From 727ba07c18194d9596be515d638e35a7d6a48f17 Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Sat, 7 Mar 2020 21:47:09 +0900 Subject: [PATCH 001/536] Use aidl::nullable for nullable type in C++ To reduce the discrepance between old code which still uses std::unique_ptr and new code using std::optional. This might help to avoid merge-conflicts between branches. Bug: 144773267 Test: m Merged-In: I33822bc76ef87637d5408849f64a0607e121792e Change-Id: I2fd5d5ead29309049a86ce764167cfb7a16196fc Exempt-From-Owner-Approval: approved from master (cherry picked from commit c85cc13b5ac09045633945357a337eb0629696f4) --- cmds/idmap2/idmap2d/Idmap2Service.cpp | 4 ++-- cmds/idmap2/idmap2d/Idmap2Service.h | 6 ++---- services/incremental/IncrementalService.cpp | 3 ++- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index 63c22ef6fb3e..02e92aeb9dc6 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -113,7 +113,7 @@ Status Idmap2Service::verifyIdmap(const std::string& overlay_apk_path, Status Idmap2Service::createIdmap(const std::string& target_apk_path, const std::string& overlay_apk_path, int32_t fulfilled_policies, bool enforce_overlayable, int32_t user_id ATTRIBUTE_UNUSED, - std::optional* _aidl_return) { + aidl::nullable* _aidl_return) { assert(_aidl_return); SYSTRACE << "Idmap2Service::createIdmap " << target_apk_path << " " << overlay_apk_path; _aidl_return->reset(); @@ -155,7 +155,7 @@ Status Idmap2Service::createIdmap(const std::string& target_apk_path, return error("failed to write to idmap path " + idmap_path); } - *_aidl_return = idmap_path; + *_aidl_return = aidl::make_nullable(idmap_path); return ok(); } diff --git a/cmds/idmap2/idmap2d/Idmap2Service.h b/cmds/idmap2/idmap2d/Idmap2Service.h index 047353f52590..b6f5136fc801 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.h +++ b/cmds/idmap2/idmap2d/Idmap2Service.h @@ -19,9 +19,7 @@ #include #include - -#include -#include +#include #include "android/os/BnIdmap2.h" @@ -46,7 +44,7 @@ class Idmap2Service : public BinderService, public BnIdmap2 { binder::Status createIdmap(const std::string& target_apk_path, const std::string& overlay_apk_path, int32_t fulfilled_policies, bool enforce_overlayable, int32_t user_id, - std::optional* _aidl_return) override; + aidl::nullable* _aidl_return) override; }; } // namespace android::os diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp index 28dd15aaf5a9..ae27c7aabdda 100644 --- a/services/incremental/IncrementalService.cpp +++ b/services/incremental/IncrementalService.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -1082,7 +1083,7 @@ bool IncrementalService::prepareDataLoader(IncrementalService::IncFsMount& ifs, return false; } FileSystemControlParcel fsControlParcel; - fsControlParcel.incremental = IncrementalFileSystemControlParcel(); + fsControlParcel.incremental = aidl::make_nullable(); fsControlParcel.incremental->cmd.reset(base::unique_fd(::dup(ifs.control.cmd))); fsControlParcel.incremental->pendingReads.reset( base::unique_fd(::dup(ifs.control.pendingReads))); -- GitLab From 153de338c182dbdbcbc3b32186cf783805fb7757 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Thu, 28 May 2020 17:49:53 -0700 Subject: [PATCH 002/536] Only autoVerify at install for new hosts Re-run app link verification at update time only when the set of hosts has expanded. Intentionally revoke verify history when an app stops using autoVerify, as a one-time measure to place it back into the non-autoverify model for tracking the user's launch preferences. If the app starts using autoVerify again later, it behaves identically to an app that has never done so before. Bug: 151475497 Bug: 146204120 Test: described on master CL Merged-In: I200d85085ce79842a3ed39377d1f75ec381c8991 Change-Id: Ibaf087946966ad82d60c7b255e3ee75990716b63 --- .../server/pm/PackageManagerService.java | 204 +++++++++++++----- .../java/com/android/server/pm/Settings.java | 10 +- 2 files changed, 156 insertions(+), 58 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index c8175befe179..5ca86517c999 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -114,6 +114,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppOpsManager; +import android.app.BroadcastOptions; import android.app.IActivityManager; import android.app.ResourcesManager; import android.app.admin.IDevicePolicyManager; @@ -1103,9 +1104,13 @@ public class PackageManagerService extends IPackageManager.Stub verificationIntent.setComponent(mIntentFilterVerifierComponent); verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + final long whitelistTimeout = getVerificationTimeout(); + final BroadcastOptions options = BroadcastOptions.makeBasic(); + options.setTemporaryAppWhitelistDuration(whitelistTimeout); + DeviceIdleController.LocalService idleController = getDeviceIdleController(); idleController.addPowerSaveTempWhitelistApp(Process.myUid(), - mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(), + mIntentFilterVerifierComponent.getPackageName(), whitelistTimeout, UserHandle.USER_SYSTEM, true, "intent filter verifier"); mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM); @@ -1146,9 +1151,6 @@ public class PackageManagerService extends IPackageManager.Stub + verificationId + " packageName:" + packageName); return; } - if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, - "Updating IntentFilterVerificationInfo for package " + packageName - +" verificationId:" + verificationId); synchronized (mPackages) { if (verified) { @@ -1166,36 +1168,70 @@ public class PackageManagerService extends IPackageManager.Stub int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; boolean needUpdate = false; - // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have - // already been set by the User thru the Disambiguation dialog - switch (userStatus) { - case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: - if (verified) { - updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; - } else { - updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; - } - needUpdate = true; - break; - - case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: - if (verified) { - updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; - needUpdate = true; - } - break; - - default: - // Nothing to do - } + // In a success case, we promote from undefined or ASK to ALWAYS. This + // supports a flow where the app fails validation but then ships an updated + // APK that passes, and therefore deserves to be in ALWAYS. + // + // If validation failed, the undefined state winds up in the basic ASK behavior, + // but apps that previously passed and became ALWAYS are *demoted* out of + // that state, since they would not deserve the ALWAYS behavior in case of a + // clean install. + switch (userStatus) { + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: + if (!verified) { + // Don't demote if sysconfig says 'always' + SystemConfig systemConfig = SystemConfig.getInstance(); + ArraySet packages = systemConfig.getLinkedApps(); + if (!packages.contains(packageName)) { + // updatedStatus is already UNDEFINED + needUpdate = true; + + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Formerly validated but now failing; demoting"); + } + } else { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Updating bundled package " + packageName + + " failed autoVerify, but sysconfig supersedes"); + } + // leave needUpdate == false here intentionally + } + } + break; + + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: + // Stay in 'undefined' on verification failure + if (verified) { + updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; + } + needUpdate = true; + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Applying update; old=" + userStatus + + " new=" + updatedStatus); + } + break; + + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: + // Keep in 'ask' on failure + if (verified) { + updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; + needUpdate = true; + } + break; + + default: + // Nothing to do + } if (needUpdate) { mSettings.updateIntentFilterVerificationStatusLPw( packageName, updatedStatus, userId); scheduleWritePackageRestrictionsLocked(userId); } + } else { + Slog.i(TAG, "autoVerify ignored when installing for all users"); } - } + } } @Override @@ -19060,70 +19096,125 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; - + boolean handlesWebUris = false; + ArraySet domains = new ArraySet<>(); + final boolean previouslyVerified; + boolean hostSetExpanded = false; + boolean needToRunVerify = false; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - if (!replacing) { - IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - if (ivi != null) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName+ " already verified: status=" - + ivi.getStatusString()); - } - return; + IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + previouslyVerified = (ivi != null); + if (!replacing && previouslyVerified) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName + " already verified: status=" + + ivi.getStatusString()); } + return; } - // If any filters need to be verified, then all need to be. - boolean needToVerify = false; + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, " Previous verified hosts: " + + (ivi == null ? "[none]" : ivi.getDomainsString())); + } + + // If any filters need to be verified, then all need to be. In addition, we need to + // know whether an updating app has any web navigation intent filters, to re- + // examine handling policy even if not re-verifying. + final boolean needsVerification = needsNetworkVerificationLPr(packageName); for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { + if (filter.handlesWebUris(true)) { + handlesWebUris = true; + } + if (needsVerification && filter.needsVerification()) { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "Intent filter needs verification, so processing all filters"); + Slog.d(TAG, "autoVerify requested, processing all filters"); } - needToVerify = true; + needToRunVerify = true; + // It's safe to break out here because filter.needsVerification() + // can only be true if filter.handlesWebUris(true) returned true, so + // we've already noted that. break; } } } - if (needToVerify) { + // Compare the new set of recognized hosts if the app is either requesting + // autoVerify or has previously used autoVerify but no longer does. + if (needToRunVerify || previouslyVerified) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { // Run verification against hosts mentioned in any web-nav intent filter, // even if the filter matches non-web schemes as well - if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) { + if (filter.handlesWebUris(false /*onlyWebSchemes*/)) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); mIntentFilterVerifier.addOneIntentFilterVerification( verifierUid, userId, verificationId, filter, packageName); + domains.addAll(filter.getHostsList()); count++; } } } } + + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, " Update published hosts: " + domains.toString()); + } + + // If we've previously verified this same host set (or a subset), we can trust that + // a current ALWAYS policy is still applicable. If this is the case, we're done. + // (If we aren't in ALWAYS, we want to reverify to allow for apps that had failing + // hosts in their intent filters, then pushed a new apk that removed them and now + // passes.) + // + // Cases: + // + still autoVerify (needToRunVerify): + // - preserve current state if all of: unexpanded, in always + // - otherwise rerun as usual (fall through) + // + no longer autoVerify (alreadyVerified && !needToRunVerify) + // - wipe verification history always + // - preserve current state if all of: unexpanded, in always + hostSetExpanded = !previouslyVerified + || (ivi != null && !ivi.getDomains().containsAll(domains)); + final int currentPolicy = + mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); + final boolean keepCurState = !hostSetExpanded + && currentPolicy == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; + + if (needToRunVerify && keepCurState) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Host set not expanding + ALWAYS -> no need to reverify"); + } + ivi.setDomains(domains); + scheduleWriteSettingsLocked(); + return; + } else if (previouslyVerified && !needToRunVerify) { + // Prior autoVerify state but not requesting it now. Clear autoVerify history, + // and preserve the always policy iff the host set is not expanding. + clearIntentFilterVerificationsLPw(packageName, userId, !keepCurState); + return; + } } - if (count > 0) { + if (needToRunVerify && count > 0) { + // app requested autoVerify and has at least one matching intent filter if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No filters or not all autoVerify for " + packageName); + Slog.d(TAG, "No web filters or no new host policy for " + packageName); } } - } - - private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { - final ComponentName cn = filter.activity.getComponentName(); - final String packageName = cn.getPackageName(); + } + private boolean needsNetworkVerificationLPr(String packageName) { IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( packageName); if (ivi == null) { @@ -19132,6 +19223,7 @@ public class PackageManagerService extends IPackageManager.Stub int status = ivi.getStatus(); switch (status) { case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return true; @@ -19841,7 +19933,7 @@ public class PackageManagerService extends IPackageManager.Stub boolean installedStateChanged = false; if (deletedPs != null) { if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { - clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); + clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL, true); clearDefaultBrowserIfNeeded(packageName); mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); removedAppId = mSettings.removePackageLPw(packageName); @@ -21147,12 +21239,13 @@ public class PackageManagerService extends IPackageManager.Stub final int packageCount = mPackages.size(); for (int i = 0; i < packageCount; i++) { PackageParser.Package pkg = mPackages.valueAt(i); - clearIntentFilterVerificationsLPw(pkg.packageName, userId); + clearIntentFilterVerificationsLPw(pkg.packageName, userId, true); } } /** This method takes a specific user id as well as UserHandle.USER_ALL. */ - void clearIntentFilterVerificationsLPw(String packageName, int userId) { + void clearIntentFilterVerificationsLPw(String packageName, int userId, + boolean alsoResetStatus) { if (userId == UserHandle.USER_ALL) { if (mSettings.removeIntentFilterVerificationLPw(packageName, sUserManager.getUserIds())) { @@ -21161,7 +21254,8 @@ public class PackageManagerService extends IPackageManager.Stub } } } else { - if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { + if (mSettings.removeIntentFilterVerificationLPw(packageName, userId, + alsoResetStatus)) { scheduleWritePackageRestrictionsLocked(userId); } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 56835f69a3c7..39ed808dd599 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1371,7 +1371,8 @@ final class Settings { return result; } - boolean removeIntentFilterVerificationLPw(String packageName, int userId) { + boolean removeIntentFilterVerificationLPw(String packageName, int userId, + boolean alsoResetStatus) { PackageSetting ps = mPackages.get(packageName); if (ps == null) { if (DEBUG_DOMAIN_VERIFICATION) { @@ -1379,14 +1380,17 @@ final class Settings { } return false; } - ps.clearDomainVerificationStatusForUser(userId); + if (alsoResetStatus) { + ps.clearDomainVerificationStatusForUser(userId); + } + ps.setIntentFilterVerificationInfo(null); return true; } boolean removeIntentFilterVerificationLPw(String packageName, int[] userIds) { boolean result = false; for (int userId : userIds) { - result |= removeIntentFilterVerificationLPw(packageName, userId); + result |= removeIntentFilterVerificationLPw(packageName, userId, true); } return result; } -- GitLab From 3e76c30b7db2cb431e84a3e933c839fefe283c6d Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Thu, 28 May 2020 17:49:53 -0700 Subject: [PATCH 003/536] Only autoVerify at install for new hosts Re-run app link verification at update time only when the set of hosts has expanded. Intentionally revoke verify history when an app stops using autoVerify, as a one-time measure to place it back into the non-autoverify model for tracking the user's launch preferences. If the app starts using autoVerify again later, it behaves identically to an app that has never done so before. Bug: 151475497 Bug: 146204120 Test: described on master CL Merged-In: I200d85085ce79842a3ed39377d1f75ec381c8991 Change-Id: Ibaf087946966ad82d60c7b255e3ee75990716b63 --- .../server/pm/PackageManagerService.java | 205 +++++++++++++----- .../java/com/android/server/pm/Settings.java | 10 +- 2 files changed, 156 insertions(+), 59 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 8d43959fb2c2..27285381369b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -121,6 +121,7 @@ import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.AppOpsManager; +import android.app.BroadcastOptions; import android.app.IActivityManager; import android.app.ResourcesManager; import android.app.admin.IDevicePolicyManager; @@ -1105,9 +1106,13 @@ public class PackageManagerService extends IPackageManager.Stub verificationIntent.setComponent(mIntentFilterVerifierComponent); verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + final long whitelistTimeout = getVerificationTimeout(); + final BroadcastOptions options = BroadcastOptions.makeBasic(); + options.setTemporaryAppWhitelistDuration(whitelistTimeout); + DeviceIdleController.LocalService idleController = getDeviceIdleController(); idleController.addPowerSaveTempWhitelistApp(Process.myUid(), - mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(), + mIntentFilterVerifierComponent.getPackageName(), whitelistTimeout, UserHandle.USER_SYSTEM, true, "intent filter verifier"); mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM); @@ -1148,9 +1153,6 @@ public class PackageManagerService extends IPackageManager.Stub + verificationId + " packageName:" + packageName); return; } - if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, - "Updating IntentFilterVerificationInfo for package " + packageName - +" verificationId:" + verificationId); synchronized (mPackages) { if (verified) { @@ -1168,36 +1170,70 @@ public class PackageManagerService extends IPackageManager.Stub int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; boolean needUpdate = false; - // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have - // already been set by the User thru the Disambiguation dialog - switch (userStatus) { - case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: - if (verified) { - updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; - } else { - updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; - } - needUpdate = true; - break; - - case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: - if (verified) { - updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; - needUpdate = true; - } - break; - - default: - // Nothing to do - } + // In a success case, we promote from undefined or ASK to ALWAYS. This + // supports a flow where the app fails validation but then ships an updated + // APK that passes, and therefore deserves to be in ALWAYS. + // + // If validation failed, the undefined state winds up in the basic ASK behavior, + // but apps that previously passed and became ALWAYS are *demoted* out of + // that state, since they would not deserve the ALWAYS behavior in case of a + // clean install. + switch (userStatus) { + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: + if (!verified) { + // Don't demote if sysconfig says 'always' + SystemConfig systemConfig = SystemConfig.getInstance(); + ArraySet packages = systemConfig.getLinkedApps(); + if (!packages.contains(packageName)) { + // updatedStatus is already UNDEFINED + needUpdate = true; + + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Formerly validated but now failing; demoting"); + } + } else { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Updating bundled package " + packageName + + " failed autoVerify, but sysconfig supersedes"); + } + // leave needUpdate == false here intentionally + } + } + break; + + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: + // Stay in 'undefined' on verification failure + if (verified) { + updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; + } + needUpdate = true; + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Applying update; old=" + userStatus + + " new=" + updatedStatus); + } + break; + + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: + // Keep in 'ask' on failure + if (verified) { + updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; + needUpdate = true; + } + break; + + default: + // Nothing to do + } if (needUpdate) { mSettings.updateIntentFilterVerificationStatusLPw( packageName, updatedStatus, userId); scheduleWritePackageRestrictionsLocked(userId); } + } else { + Slog.i(TAG, "autoVerify ignored when installing for all users"); } - } + } } @Override @@ -17724,71 +17760,125 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; - + boolean handlesWebUris = false; + ArraySet domains = new ArraySet<>(); + final boolean previouslyVerified; + boolean hostSetExpanded = false; + boolean needToRunVerify = false; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - if (!replacing) { - IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - if (ivi != null) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName+ " already verified: status=" - + ivi.getStatusString()); - } - return; + IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + previouslyVerified = (ivi != null); + if (!replacing && previouslyVerified) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName + " already verified: status=" + + ivi.getStatusString()); } + return; } - // If any filters need to be verified, then all need to be. - boolean needToVerify = false; + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, " Previous verified hosts: " + + (ivi == null ? "[none]" : ivi.getDomainsString())); + } + + // If any filters need to be verified, then all need to be. In addition, we need to + // know whether an updating app has any web navigation intent filters, to re- + // examine handling policy even if not re-verifying. + final boolean needsVerification = needsNetworkVerificationLPr(packageName); for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { + if (filter.handlesWebUris(true)) { + handlesWebUris = true; + } + if (needsVerification && filter.needsVerification()) { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, - "Intent filter needs verification, so processing all filters"); + Slog.d(TAG, "autoVerify requested, processing all filters"); } - needToVerify = true; + needToRunVerify = true; + // It's safe to break out here because filter.needsVerification() + // can only be true if filter.handlesWebUris(true) returned true, so + // we've already noted that. break; } } } - if (needToVerify) { + // Compare the new set of recognized hosts if the app is either requesting + // autoVerify or has previously used autoVerify but no longer does. + if (needToRunVerify || previouslyVerified) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { // Run verification against hosts mentioned in any web-nav intent filter, // even if the filter matches non-web schemes as well - if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) { + if (filter.handlesWebUris(false /*onlyWebSchemes*/)) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); mIntentFilterVerifier.addOneIntentFilterVerification( verifierUid, userId, verificationId, filter, packageName); + domains.addAll(filter.getHostsList()); count++; } } } } + + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, " Update published hosts: " + domains.toString()); + } + + // If we've previously verified this same host set (or a subset), we can trust that + // a current ALWAYS policy is still applicable. If this is the case, we're done. + // (If we aren't in ALWAYS, we want to reverify to allow for apps that had failing + // hosts in their intent filters, then pushed a new apk that removed them and now + // passes.) + // + // Cases: + // + still autoVerify (needToRunVerify): + // - preserve current state if all of: unexpanded, in always + // - otherwise rerun as usual (fall through) + // + no longer autoVerify (alreadyVerified && !needToRunVerify) + // - wipe verification history always + // - preserve current state if all of: unexpanded, in always + hostSetExpanded = !previouslyVerified + || (ivi != null && !ivi.getDomains().containsAll(domains)); + final int currentPolicy = + mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); + final boolean keepCurState = !hostSetExpanded + && currentPolicy == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; + + if (needToRunVerify && keepCurState) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Host set not expanding + ALWAYS -> no need to reverify"); + } + ivi.setDomains(domains); + scheduleWriteSettingsLocked(); + return; + } else if (previouslyVerified && !needToRunVerify) { + // Prior autoVerify state but not requesting it now. Clear autoVerify history, + // and preserve the always policy iff the host set is not expanding. + clearIntentFilterVerificationsLPw(packageName, userId, !keepCurState); + return; + } } - if (count > 0) { + if (needToRunVerify && count > 0) { + // app requested autoVerify and has at least one matching intent filter if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No filters or not all autoVerify for " + packageName); + Slog.d(TAG, "No web filters or no new host policy for " + packageName); } } - } - - private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { - final ComponentName cn = filter.activity.getComponentName(); - final String packageName = cn.getPackageName(); + } + private boolean needsNetworkVerificationLPr(String packageName) { IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( packageName); if (ivi == null) { @@ -17797,6 +17887,7 @@ public class PackageManagerService extends IPackageManager.Stub int status = ivi.getStatus(); switch (status) { case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return true; @@ -18510,7 +18601,7 @@ public class PackageManagerService extends IPackageManager.Stub boolean installedStateChanged = false; if (deletedPs != null) { if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { - clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); + clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL, true); clearDefaultBrowserIfNeeded(packageName); mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); removedAppId = mSettings.removePackageLPw(packageName); @@ -19898,12 +19989,13 @@ public class PackageManagerService extends IPackageManager.Stub final int packageCount = mPackages.size(); for (int i = 0; i < packageCount; i++) { PackageParser.Package pkg = mPackages.valueAt(i); - clearIntentFilterVerificationsLPw(pkg.packageName, userId); + clearIntentFilterVerificationsLPw(pkg.packageName, userId, true); } } /** This method takes a specific user id as well as UserHandle.USER_ALL. */ - void clearIntentFilterVerificationsLPw(String packageName, int userId) { + void clearIntentFilterVerificationsLPw(String packageName, int userId, + boolean alsoResetStatus) { if (userId == UserHandle.USER_ALL) { if (mSettings.removeIntentFilterVerificationLPw(packageName, sUserManager.getUserIds())) { @@ -19912,7 +20004,8 @@ public class PackageManagerService extends IPackageManager.Stub } } } else { - if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { + if (mSettings.removeIntentFilterVerificationLPw(packageName, userId, + alsoResetStatus)) { scheduleWritePackageRestrictionsLocked(userId); } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index a7e38301bb40..34a630d9449c 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1310,7 +1310,8 @@ public final class Settings { return result; } - boolean removeIntentFilterVerificationLPw(String packageName, int userId) { + boolean removeIntentFilterVerificationLPw(String packageName, int userId, + boolean alsoResetStatus) { PackageSetting ps = mPackages.get(packageName); if (ps == null) { if (DEBUG_DOMAIN_VERIFICATION) { @@ -1318,14 +1319,17 @@ public final class Settings { } return false; } - ps.clearDomainVerificationStatusForUser(userId); + if (alsoResetStatus) { + ps.clearDomainVerificationStatusForUser(userId); + } + ps.setIntentFilterVerificationInfo(null); return true; } boolean removeIntentFilterVerificationLPw(String packageName, int[] userIds) { boolean result = false; for (int userId : userIds) { - result |= removeIntentFilterVerificationLPw(packageName, userId); + result |= removeIntentFilterVerificationLPw(packageName, userId, true); } return result; } -- GitLab From b9ccfe55aa74b7900862cacd8eb2a941e8dbc79a Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Thu, 23 Apr 2020 10:22:59 -0700 Subject: [PATCH 004/536] Make system-generated FGS notification PendingIntents immutable Bug: 153878498 Test: Test app from the indicated bug Change-Id: Ied48bdfa4e168dad7d829dbe21cc441dfde868ae (cherry picked from commit 0617b71cd317935669ef6bdd58e1e2cf517c87e1) --- services/core/java/com/android/server/am/ServiceRecord.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 4670d58ca63b..274b0a83b502 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -16,6 +16,9 @@ package com.android.server.am; +import static android.app.PendingIntent.FLAG_IMMUTABLE; +import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; + import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -864,7 +867,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN runningIntent.setData(Uri.fromParts("package", appInfo.packageName, null)); PendingIntent pi = PendingIntent.getActivityAsUser(ams.mContext, 0, - runningIntent, PendingIntent.FLAG_UPDATE_CURRENT, null, + runningIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE, null, UserHandle.of(userId)); notiBuilder.setColor(ams.mContext.getColor( com.android.internal -- GitLab From 90b716a442802154208c86c31545b6f1f3ee53db Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Thu, 28 May 2020 17:49:53 -0700 Subject: [PATCH 005/536] DO NOT MERGE - Only autoVerify at install for new hosts Re-run app link verification at update time only when the set of hosts has expanded. Intentionally revoke verify history when an app stops using autoVerify, as a one-time measure to place it back into the non-autoverify model for tracking the user's launch preferences. If the app starts using autoVerify again later, it behaves identically to an app that has never done so before. Bug: 151475497 Bug: 146204120 Test: described on master CL Merged-In: I200d85085ce79842a3ed39377d1f75ec381c8991 Merged-In: Ibaf087946966ad82d60c7b255e3ee75990716b63 Change-Id: Ibaf087946966ad82d60c7b255e3ee75990716b63 --- .../server/pm/PackageManagerService.java | 206 +++++++++++++----- .../java/com/android/server/pm/Settings.java | 10 +- 2 files changed, 157 insertions(+), 59 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 3888c3130c15..ffa9309cad5b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -109,6 +109,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppOpsManager; +import android.app.BroadcastOptions; import android.app.IActivityManager; import android.app.ResourcesManager; import android.app.admin.IDevicePolicyManager; @@ -1079,10 +1080,14 @@ public class PackageManagerService extends IPackageManager.Stub verificationIntent.setComponent(mIntentFilterVerifierComponent); verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + final long whitelistTimeout = getVerificationTimeout(); + final BroadcastOptions options = BroadcastOptions.makeBasic(); + options.setTemporaryAppWhitelistDuration(whitelistTimeout); + DeviceIdleController.LocalService idleController = getDeviceIdleController(); idleController.addPowerSaveTempWhitelistApp(Process.myUid(), - mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(), - userId, false, "intent filter verifier"); + mIntentFilterVerifierComponent.getPackageName(), whitelistTimeout, + userId, true, "intent filter verifier"); UserHandle user = new UserHandle(userId); mContext.sendBroadcastAsUser(verificationIntent, user); @@ -1123,9 +1128,6 @@ public class PackageManagerService extends IPackageManager.Stub + verificationId + " packageName:" + packageName); return; } - if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, - "Updating IntentFilterVerificationInfo for package " + packageName - +" verificationId:" + verificationId); synchronized (mPackages) { if (verified) { @@ -1143,36 +1145,70 @@ public class PackageManagerService extends IPackageManager.Stub int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; boolean needUpdate = false; - // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have - // already been set by the User thru the Disambiguation dialog - switch (userStatus) { - case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: - if (verified) { - updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; - } else { - updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; - } - needUpdate = true; - break; - - case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: - if (verified) { - updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; - needUpdate = true; - } - break; - - default: - // Nothing to do - } + // In a success case, we promote from undefined or ASK to ALWAYS. This + // supports a flow where the app fails validation but then ships an updated + // APK that passes, and therefore deserves to be in ALWAYS. + // + // If validation failed, the undefined state winds up in the basic ASK behavior, + // but apps that previously passed and became ALWAYS are *demoted* out of + // that state, since they would not deserve the ALWAYS behavior in case of a + // clean install. + switch (userStatus) { + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: + if (!verified) { + // Don't demote if sysconfig says 'always' + SystemConfig systemConfig = SystemConfig.getInstance(); + ArraySet packages = systemConfig.getLinkedApps(); + if (!packages.contains(packageName)) { + // updatedStatus is already UNDEFINED + needUpdate = true; + + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Formerly validated but now failing; demoting"); + } + } else { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Updating bundled package " + packageName + + " failed autoVerify, but sysconfig supersedes"); + } + // leave needUpdate == false here intentionally + } + } + break; + + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: + // Stay in 'undefined' on verification failure + if (verified) { + updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; + } + needUpdate = true; + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Applying update; old=" + userStatus + + " new=" + updatedStatus); + } + break; + + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: + // Keep in 'ask' on failure + if (verified) { + updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; + needUpdate = true; + } + break; + + default: + // Nothing to do + } if (needUpdate) { mSettings.updateIntentFilterVerificationStatusLPw( packageName, updatedStatus, userId); scheduleWritePackageRestrictionsLocked(userId); } + } else { + Slog.i(TAG, "autoVerify ignored when installing for all users"); } - } + } } @Override @@ -18436,70 +18472,125 @@ public class PackageManagerService extends IPackageManager.Stub int count = 0; final String packageName = pkg.packageName; - + boolean handlesWebUris = false; + ArraySet domains = new ArraySet<>(); + final boolean previouslyVerified; + boolean hostSetExpanded = false; + boolean needToRunVerify = false; synchronized (mPackages) { // If this is a new install and we see that we've already run verification for this // package, we have nothing to do: it means the state was restored from backup. - if (!replacing) { - IntentFilterVerificationInfo ivi = - mSettings.getIntentFilterVerificationLPr(packageName); - if (ivi != null) { - if (DEBUG_DOMAIN_VERIFICATION) { - Slog.i(TAG, "Package " + packageName+ " already verified: status=" - + ivi.getStatusString()); - } - return; + IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + previouslyVerified = (ivi != null); + if (!replacing && previouslyVerified) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName + " already verified: status=" + + ivi.getStatusString()); } + return; } - // If any filters need to be verified, then all need to be. - boolean needToVerify = false; + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, " Previous verified hosts: " + + (ivi == null ? "[none]" : ivi.getDomainsString())); + } + + // If any filters need to be verified, then all need to be. In addition, we need to + // know whether an updating app has any web navigation intent filters, to re- + // examine handling policy even if not re-verifying. + final boolean needsVerification = needsNetworkVerificationLPr(packageName); for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { + if (filter.handlesWebUris(true)) { + handlesWebUris = true; + } + if (needsVerification && filter.needsVerification()) { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "Intent filter needs verification, so processing all filters"); + Slog.d(TAG, "autoVerify requested, processing all filters"); } - needToVerify = true; + needToRunVerify = true; + // It's safe to break out here because filter.needsVerification() + // can only be true if filter.handlesWebUris(true) returned true, so + // we've already noted that. break; } } } - if (needToVerify) { + // Compare the new set of recognized hosts if the app is either requesting + // autoVerify or has previously used autoVerify but no longer does. + if (needToRunVerify || previouslyVerified) { final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { // Run verification against hosts mentioned in any web-nav intent filter, // even if the filter matches non-web schemes as well - if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) { + if (filter.handlesWebUris(false /*onlyWebSchemes*/)) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); mIntentFilterVerifier.addOneIntentFilterVerification( verifierUid, userId, verificationId, filter, packageName); + domains.addAll(filter.getHostsList()); count++; } } } } + + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, " Update published hosts: " + domains.toString()); + } + + // If we've previously verified this same host set (or a subset), we can trust that + // a current ALWAYS policy is still applicable. If this is the case, we're done. + // (If we aren't in ALWAYS, we want to reverify to allow for apps that had failing + // hosts in their intent filters, then pushed a new apk that removed them and now + // passes.) + // + // Cases: + // + still autoVerify (needToRunVerify): + // - preserve current state if all of: unexpanded, in always + // - otherwise rerun as usual (fall through) + // + no longer autoVerify (alreadyVerified && !needToRunVerify) + // - wipe verification history always + // - preserve current state if all of: unexpanded, in always + hostSetExpanded = !previouslyVerified + || (ivi != null && !ivi.getDomains().containsAll(domains)); + final int currentPolicy = + mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); + final boolean keepCurState = !hostSetExpanded + && currentPolicy == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; + + if (needToRunVerify && keepCurState) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Host set not expanding + ALWAYS -> no need to reverify"); + } + ivi.setDomains(domains); + scheduleWriteSettingsLocked(); + return; + } else if (previouslyVerified && !needToRunVerify) { + // Prior autoVerify state but not requesting it now. Clear autoVerify history, + // and preserve the always policy iff the host set is not expanding. + clearIntentFilterVerificationsLPw(packageName, userId, !keepCurState); + return; + } } - if (count > 0) { + if (needToRunVerify && count > 0) { + // app requested autoVerify and has at least one matching intent filter if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count + " IntentFilter verification" + (count > 1 ? "s" : "") + " for userId:" + userId); mIntentFilterVerifier.startVerifications(userId); } else { if (DEBUG_DOMAIN_VERIFICATION) { - Slog.d(TAG, "No filters or not all autoVerify for " + packageName); + Slog.d(TAG, "No web filters or no new host policy for " + packageName); } } - } - - private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { - final ComponentName cn = filter.activity.getComponentName(); - final String packageName = cn.getPackageName(); + } + private boolean needsNetworkVerificationLPr(String packageName) { IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( packageName); if (ivi == null) { @@ -18508,6 +18599,7 @@ public class PackageManagerService extends IPackageManager.Stub int status = ivi.getStatus(); switch (status) { case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return true; @@ -19202,7 +19294,7 @@ public class PackageManagerService extends IPackageManager.Stub boolean installedStateChanged = false; if (deletedPs != null) { if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { - clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); + clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL, true); clearDefaultBrowserIfNeeded(packageName); mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); removedAppId = mSettings.removePackageLPw(packageName); @@ -20482,12 +20574,13 @@ public class PackageManagerService extends IPackageManager.Stub final int packageCount = mPackages.size(); for (int i = 0; i < packageCount; i++) { PackageParser.Package pkg = mPackages.valueAt(i); - clearIntentFilterVerificationsLPw(pkg.packageName, userId); + clearIntentFilterVerificationsLPw(pkg.packageName, userId, true); } } /** This method takes a specific user id as well as UserHandle.USER_ALL. */ - void clearIntentFilterVerificationsLPw(String packageName, int userId) { + void clearIntentFilterVerificationsLPw(String packageName, int userId, + boolean alsoResetStatus) { if (userId == UserHandle.USER_ALL) { if (mSettings.removeIntentFilterVerificationLPw(packageName, sUserManager.getUserIds())) { @@ -20496,7 +20589,8 @@ public class PackageManagerService extends IPackageManager.Stub } } } else { - if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { + if (mSettings.removeIntentFilterVerificationLPw(packageName, userId, + alsoResetStatus)) { scheduleWritePackageRestrictionsLocked(userId); } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 45d0c585627b..6a463a621878 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1368,7 +1368,8 @@ final class Settings { return result; } - boolean removeIntentFilterVerificationLPw(String packageName, int userId) { + boolean removeIntentFilterVerificationLPw(String packageName, int userId, + boolean alsoResetStatus) { PackageSetting ps = mPackages.get(packageName); if (ps == null) { if (DEBUG_DOMAIN_VERIFICATION) { @@ -1376,14 +1377,17 @@ final class Settings { } return false; } - ps.clearDomainVerificationStatusForUser(userId); + if (alsoResetStatus) { + ps.clearDomainVerificationStatusForUser(userId); + } + ps.setIntentFilterVerificationInfo(null); return true; } boolean removeIntentFilterVerificationLPw(String packageName, int[] userIds) { boolean result = false; for (int userId : userIds) { - result |= removeIntentFilterVerificationLPw(packageName, userId); + result |= removeIntentFilterVerificationLPw(packageName, userId, true); } return result; } -- GitLab From 86cc35a927cbc6897539e5673993f42466e40a08 Mon Sep 17 00:00:00 2001 From: Jacky Kao Date: Thu, 4 Jun 2020 15:18:49 +0800 Subject: [PATCH 006/536] Make A11yServiceConnection PendingIntent immutable. Require that the PendingIntent be immutable so that a malicious app is not able to hijack and mutate any of the details. Bug: 154913130 Test: a11y CTS & unit tests Change-Id: Ib794fa9e80b2a6c5562c66a0c17ea7c92c500e19 (cherry picked from commit a0b630075a36ce7d39b8b7ad656ca690953b445f) --- .../server/accessibility/AccessibilityServiceConnection.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java index 0f98992d1ea0..fea2e7b841e0 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java @@ -21,6 +21,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa import android.Manifest; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; +import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -83,7 +84,8 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect final long identity = Binder.clearCallingIdentity(); try { mIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, mSystemSupport.getPendingIntentActivity( - mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0)); + mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), + PendingIntent.FLAG_IMMUTABLE)); } finally { Binder.restoreCallingIdentity(identity); } -- GitLab From a9f825922e1870575aeab11a2035903c217233c9 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 15 Jun 2020 18:18:33 -0700 Subject: [PATCH 007/536] Revoke install permissions when the permission defining app is uninstalled. Bug: 155648771 Test: atest RemovePermissionTest Change-Id: I4a5ecd9bede6f11d5023b3e8345b61d5b04e566f --- .../pm/permission/PermissionManagerService.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index d3f3ba1dc6bb..78199fa24232 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -4173,6 +4173,20 @@ public class PermissionManagerService extends IPermissionManager.Stub { revokePermissionFromPackageForUser(p.getPackageName(), bp.getName(), true, userId, callback)); } + } else { + mPackageManagerInt.forEachPackage(p -> { + PackageSetting ps = mPackageManagerInt.getPackageSetting( + p.getPackageName()); + if (ps == null) { + return; + } + PermissionsState permissionsState = ps.getPermissionsState(); + if (permissionsState.getInstallPermissionState(bp.getName()) != null) { + permissionsState.revokeInstallPermission(bp); + permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, + MASK_PERMISSION_FLAGS_ALL, 0); + } + }); } it.remove(); } -- GitLab From b5e3addc5f27149d1b0bbc213ced47b2ade732bf Mon Sep 17 00:00:00 2001 From: Winson Chiu Date: Tue, 16 Jun 2020 21:41:22 +0000 Subject: [PATCH 008/536] Revert "Ignores protected broadcasts if not priv-app" Revert of I5bd2bf3bd7c38fd9cc563a02b24bc569495d79ed For now, allow all system apps to declare protected broadcasts. This will be cleaned up in a future change. Bug: 158570769 Merged-In: I54d236c0a6daaa934bd64a3bd05e2654e0e868fe Change-Id: I54d236c0a6daaa934bd64a3bd05e2654e0e868fe --- .../java/com/android/server/pm/PackageManagerService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 46f2de4404a8..2093438dfbb3 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -10837,6 +10837,8 @@ public class PackageManagerService extends IPackageManager.Stub ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; pkg.applicationInfo.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; + // clear protected broadcasts + pkg.protectedBroadcasts = null; // cap permission priorities if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) { for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) { @@ -10845,8 +10847,6 @@ public class PackageManagerService extends IPackageManager.Stub } } if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) { - // clear protected broadcasts - pkg.protectedBroadcasts = null; // ignore export request for single user receivers if (pkg.receivers != null) { for (int i = pkg.receivers.size() - 1; i >= 0; --i) { -- GitLab From 75b16ca6cf90dcf552621a4f22111903214a5145 Mon Sep 17 00:00:00 2001 From: Babak Date: Wed, 24 Jun 2020 01:40:37 -0700 Subject: [PATCH 009/536] Fix ConnectedDeviceVoiceRecognitoinNotifierTest - Adds bluetooth device to the intent since it is required by other receivers which can cause issues if test is running while other receivers are listening for the bluetooth broadcast. - Fixes a potential flakiness by making sure the looper processes all the messages. Fix: 154515909 Test: Manual Change-Id: Ib9c6f9eed20336cafcf9d984edd60eb311195e5e --- ...tedDeviceVoiceRecognitionNotifierTest.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java index eca51e34995c..232df2eced39 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java @@ -24,6 +24,8 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadsetClient; import android.content.Intent; import android.os.Handler; @@ -44,14 +46,19 @@ import org.junit.runner.RunWith; public class ConnectedDeviceVoiceRecognitionNotifierTest extends SysuiTestCase { private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; + private static final String BLUETOOTH_REMOTE_ADDRESS = "00:11:22:33:44:55"; private ConnectedDeviceVoiceRecognitionNotifier mVoiceRecognitionNotifier; + private TestableLooper mTestableLooper; private Handler mTestHandler; + private BluetoothDevice mBluetoothDevice; @Before public void setUp() throws Exception { - TestableLooper testableLooper = TestableLooper.get(this); - mTestHandler = spy(new Handler(testableLooper.getLooper())); + mTestableLooper = TestableLooper.get(this); + mTestHandler = spy(new Handler(mTestableLooper.getLooper())); + mBluetoothDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice( + BLUETOOTH_REMOTE_ADDRESS); mVoiceRecognitionNotifier = new ConnectedDeviceVoiceRecognitionNotifier( mContext, mTestHandler); mVoiceRecognitionNotifier.onBootCompleted(); @@ -61,8 +68,10 @@ public class ConnectedDeviceVoiceRecognitionNotifierTest extends SysuiTestCase { public void testReceiveIntent_started_showToast() { Intent intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); intent.putExtra(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, VOICE_RECOGNITION_STARTED); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice); + mContext.sendBroadcast(intent, BLUETOOTH_PERM); - waitForIdleSync(); + mTestableLooper.processAllMessages(); verify(mTestHandler).post(any()); } @@ -71,8 +80,10 @@ public class ConnectedDeviceVoiceRecognitionNotifierTest extends SysuiTestCase { public void testReceiveIntent_invalidExtra_noToast() { Intent intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); intent.putExtra(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, INVALID_VALUE); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice); + mContext.sendBroadcast(intent, BLUETOOTH_PERM); - waitForIdleSync(); + mTestableLooper.processAllMessages(); verify(mTestHandler, never()).post(any()); } @@ -80,8 +91,10 @@ public class ConnectedDeviceVoiceRecognitionNotifierTest extends SysuiTestCase { @Test public void testReceiveIntent_noExtra_noToast() { Intent intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice); + mContext.sendBroadcast(intent, BLUETOOTH_PERM); - waitForIdleSync(); + mTestableLooper.processAllMessages(); verify(mTestHandler, never()).post(any()); } @@ -89,8 +102,10 @@ public class ConnectedDeviceVoiceRecognitionNotifierTest extends SysuiTestCase { @Test public void testReceiveIntent_invalidIntent_noToast() { Intent intent = new Intent(BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice); + mContext.sendBroadcast(intent, BLUETOOTH_PERM); - waitForIdleSync(); + mTestableLooper.processAllMessages(); verify(mTestHandler, never()).post(any()); } -- GitLab From e9a91b39cf6e15551a18c4b697a6cfd53bd92a82 Mon Sep 17 00:00:00 2001 From: Robert Snoeberger Date: Wed, 1 Jul 2020 11:24:53 -0400 Subject: [PATCH 010/536] Migrate from old key when combining device and media data Fixes: 160256461 Test: manual - Play Spotify. Dismiss app in overview. Open app in launcher and select a cast device. Start playing again and check media player in QS. Verify that a cast icon appears in upper right corner. Change-Id: I7df9e57853db792ee6589b066dce2bb49f36dffc --- .../systemui/media/MediaDataCombineLatest.kt | 24 ++++--- .../systemui/media/MediaDeviceManager.kt | 12 ++-- .../media/MediaDataCombineLatestTest.java | 70 +++++++++++++++++-- .../systemui/media/MediaDeviceManagerTest.kt | 15 ++-- 4 files changed, 96 insertions(+), 25 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt index 0904ebccd414..6a4f0d33e127 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt @@ -33,23 +33,31 @@ class MediaDataCombineLatest @Inject constructor( init { dataSource.addListener(object : MediaDataManager.Listener { override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) { - if (oldKey != null && !oldKey.equals(key)) { - val s = entries[oldKey]?.second - entries[key] = data to entries[oldKey]?.second - entries.remove(oldKey) + if (oldKey != null && oldKey != key && entries.contains(oldKey)) { + entries[key] = data to entries.remove(oldKey)?.second + update(key, oldKey) } else { entries[key] = data to entries[key]?.second + update(key, key) } - update(key, oldKey) } override fun onMediaDataRemoved(key: String) { remove(key) } }) deviceSource.addListener(object : MediaDeviceManager.Listener { - override fun onMediaDeviceChanged(key: String, data: MediaDeviceData?) { - entries[key] = entries[key]?.first to data - update(key, key) + override fun onMediaDeviceChanged( + key: String, + oldKey: String?, + data: MediaDeviceData? + ) { + if (oldKey != null && oldKey != key && entries.contains(oldKey)) { + entries[key] = entries.remove(oldKey)?.first to data + update(key, oldKey) + } else { + entries[key] = entries[key]?.first to data + update(key, key) + } } override fun onKeyRemoved(key: String) { remove(key) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt index 7ae2dc5c0941..143f8496e7aa 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt @@ -71,7 +71,8 @@ class MediaDeviceManager @Inject constructor( val controller = data.token?.let { MediaController(context, it) } - entry = Token(key, controller, localMediaManagerFactory.create(data.packageName)) + entry = Token(key, oldKey, controller, + localMediaManagerFactory.create(data.packageName)) entries[key] = entry entry.start() } @@ -98,23 +99,24 @@ class MediaDeviceManager @Inject constructor( } } - private fun processDevice(key: String, device: MediaDevice?) { + private fun processDevice(key: String, oldKey: String?, device: MediaDevice?) { val enabled = device != null val data = MediaDeviceData(enabled, device?.iconWithoutBackground, device?.name) listeners.forEach { - it.onMediaDeviceChanged(key, data) + it.onMediaDeviceChanged(key, oldKey, data) } } interface Listener { /** Called when the route has changed for a given notification. */ - fun onMediaDeviceChanged(key: String, data: MediaDeviceData?) + fun onMediaDeviceChanged(key: String, oldKey: String?, data: MediaDeviceData?) /** Called when the notification was removed. */ fun onKeyRemoved(key: String) } private inner class Token( val key: String, + val oldKey: String?, val controller: MediaController?, val localMediaManager: LocalMediaManager ) : LocalMediaManager.DeviceCallback { @@ -125,7 +127,7 @@ class MediaDeviceManager @Inject constructor( set(value) { if (!started || value != field) { field = value - processDevice(key, value) + processDevice(key, oldKey, value) } } fun start() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java index 5d4693d3ccf8..27a63ee7d7c8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java @@ -22,6 +22,7 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import android.graphics.Color; @@ -46,6 +47,7 @@ import java.util.ArrayList; public class MediaDataCombineLatestTest extends SysuiTestCase { private static final String KEY = "TEST_KEY"; + private static final String OLD_KEY = "TEST_KEY_OLD"; private static final String APP = "APP"; private static final String PACKAGE = "PKG"; private static final int BG_COLOR = Color.RED; @@ -96,7 +98,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { @Test public void eventNotEmittedWithoutMedia() { // WHEN device source emits an event without media data - mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData); // THEN an event isn't emitted verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any()); } @@ -104,7 +106,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { @Test public void emitEventAfterDeviceFirst() { // GIVEN that a device event has already been received - mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData); // WHEN media event is received mDataListener.onMediaDataLoaded(KEY, null, mMediaData); // THEN the listener receives a combined event @@ -118,13 +120,71 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { // GIVEN that media event has already been received mDataListener.onMediaDataLoaded(KEY, null, mMediaData); // WHEN device event is received - mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData); // THEN the listener receives a combined event ArgumentCaptor captor = ArgumentCaptor.forClass(MediaData.class); verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture()); assertThat(captor.getValue().getDevice()).isNotNull(); } + @Test + public void migrateKeyMediaFirst() { + // GIVEN that media and device info has already been received + mDataListener.onMediaDataLoaded(OLD_KEY, null, mMediaData); + mDeviceListener.onMediaDeviceChanged(OLD_KEY, null, mDeviceData); + reset(mListener); + // WHEN a key migration event is received + mDataListener.onMediaDataLoaded(KEY, OLD_KEY, mMediaData); + // THEN the listener receives a combined event + ArgumentCaptor captor = ArgumentCaptor.forClass(MediaData.class); + verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture()); + assertThat(captor.getValue().getDevice()).isNotNull(); + } + + @Test + public void migrateKeyDeviceFirst() { + // GIVEN that media and device info has already been received + mDataListener.onMediaDataLoaded(OLD_KEY, null, mMediaData); + mDeviceListener.onMediaDeviceChanged(OLD_KEY, null, mDeviceData); + reset(mListener); + // WHEN a key migration event is received + mDeviceListener.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData); + // THEN the listener receives a combined event + ArgumentCaptor captor = ArgumentCaptor.forClass(MediaData.class); + verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture()); + assertThat(captor.getValue().getDevice()).isNotNull(); + } + + @Test + public void migrateKeyMediaAfter() { + // GIVEN that media and device info has already been received + mDataListener.onMediaDataLoaded(OLD_KEY, null, mMediaData); + mDeviceListener.onMediaDeviceChanged(OLD_KEY, null, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData); + reset(mListener); + // WHEN a second key migration event is received for media + mDataListener.onMediaDataLoaded(KEY, OLD_KEY, mMediaData); + // THEN the key has already been migrated + ArgumentCaptor captor = ArgumentCaptor.forClass(MediaData.class); + verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture()); + assertThat(captor.getValue().getDevice()).isNotNull(); + } + + @Test + public void migrateKeyDeviceAfter() { + // GIVEN that media and device info has already been received + mDataListener.onMediaDataLoaded(OLD_KEY, null, mMediaData); + mDeviceListener.onMediaDeviceChanged(OLD_KEY, null, mDeviceData); + mDataListener.onMediaDataLoaded(KEY, OLD_KEY, mMediaData); + reset(mListener); + // WHEN a second key migration event is received for the device + mDeviceListener.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData); + // THEN the key has already be migrated + ArgumentCaptor captor = ArgumentCaptor.forClass(MediaData.class); + verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture()); + assertThat(captor.getValue().getDevice()).isNotNull(); + } + @Test public void mediaDataRemoved() { // WHEN media data is removed without first receiving device or data @@ -142,7 +202,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { @Test public void mediaDataRemovedAfterDeviceEvent() { - mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData); mDataListener.onMediaDataRemoved(KEY); verify(mListener).onMediaDataRemoved(eq(KEY)); } @@ -151,7 +211,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { public void mediaDataKeyUpdated() { // GIVEN that device and media events have already been received mDataListener.onMediaDataLoaded(KEY, null, mMediaData); - mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDeviceListener.onMediaDeviceChanged(KEY, null, mDeviceData); // WHEN the key is changed mDataListener.onMediaDataLoaded("NEW_KEY", KEY, mMediaData); // THEN the listener gets a load event with the correct keys diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt index fc22eeb3ea68..3c6e19f0ec6f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt @@ -166,7 +166,7 @@ public class MediaDeviceManagerTest : SysuiTestCase() { // THEN the listener for the old key should removed. verify(lmm).unregisterCallback(any()) // AND a new device event emitted - val data = captureDeviceData(KEY) + val data = captureDeviceData(KEY, KEY_OLD) assertThat(data.enabled).isTrue() assertThat(data.name).isEqualTo(DEVICE_NAME) } @@ -179,13 +179,14 @@ public class MediaDeviceManagerTest : SysuiTestCase() { // WHEN the new key is the same as the old key manager.onMediaDataLoaded(KEY, KEY, mediaData) // THEN no event should be emitted - verify(listener, never()).onMediaDeviceChanged(eq(KEY), any()) + verify(listener, never()).onMediaDeviceChanged(eq(KEY), eq(null), any()) } @Test fun unknownOldKey() { - manager.onMediaDataLoaded(KEY, "unknown", mediaData) - verify(listener).onMediaDeviceChanged(eq(KEY), any()) + val oldKey = "unknown" + manager.onMediaDataLoaded(KEY, oldKey, mediaData) + verify(listener).onMediaDeviceChanged(eq(KEY), eq(oldKey), any()) } @Test @@ -223,7 +224,7 @@ public class MediaDeviceManagerTest : SysuiTestCase() { manager.removeListener(listener) // THEN it doesn't receive device events manager.onMediaDataLoaded(KEY, null, mediaData) - verify(listener, never()).onMediaDeviceChanged(eq(KEY), any()) + verify(listener, never()).onMediaDeviceChanged(eq(KEY), eq(null), any()) } @Test @@ -318,9 +319,9 @@ public class MediaDeviceManagerTest : SysuiTestCase() { return captor.getValue() } - fun captureDeviceData(key: String): MediaDeviceData { + fun captureDeviceData(key: String, oldKey: String? = null): MediaDeviceData { val captor = ArgumentCaptor.forClass(MediaDeviceData::class.java) - verify(listener).onMediaDeviceChanged(eq(key), captor.capture()) + verify(listener).onMediaDeviceChanged(eq(key), eq(oldKey), captor.capture()) return captor.getValue() } } -- GitLab From 816abfc8c1f1bf5729385941b53a097a3f7c59af Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Wed, 1 Jul 2020 12:52:42 -0400 Subject: [PATCH 011/536] Rearrange/rename GlobalScreenshot methods Moves methods to a more logical order (public/protected methods before private, make method order closer to logical flow) and renames the various takeScreenshot methods to better distinguish them from one another. Bug: 160325487 Test: manual (rearrangement/renaming only, no logical changes) Change-Id: I113608b9638383e615404dbfd89e032327f9e3ca --- .../systemui/screenshot/GlobalScreenshot.java | 445 +++++++++--------- .../screenshot/TakeScreenshotService.java | 2 +- 2 files changed, 219 insertions(+), 228 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index d6e1a16bc69e..85444303490d 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -214,9 +214,9 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset private Animator mScreenshotAnimation; private Runnable mOnCompleteRunnable; private Animator mDismissAnimation; - private boolean mInDarkMode = false; - private boolean mDirectionLTR = true; - private boolean mOrientationPortrait = true; + private boolean mInDarkMode; + private boolean mDirectionLTR; + private boolean mOrientationPortrait; private float mCornerSizeX; private float mDismissDeltaY; @@ -245,9 +245,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset } }; - /** - * @param context everything needs a context :( - */ @Inject public GlobalScreenshot( Context context, @Main Resources resources, @@ -320,6 +317,104 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset inoutInfo.touchableRegion.set(touchRegion); } + void takeScreenshotFullscreen(Consumer finisher, Runnable onComplete) { + mOnCompleteRunnable = onComplete; + + mDisplay.getRealMetrics(mDisplayMetrics); + takeScreenshotInternal( + finisher, + new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels)); + } + + void handleImageAsScreenshot(Bitmap screenshot, Rect screenshotScreenBounds, + Insets visibleInsets, int taskId, int userId, ComponentName topComponent, + Consumer finisher, Runnable onComplete) { + // TODO: use task Id, userId, topComponent for smart handler + + mOnCompleteRunnable = onComplete; + if (aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) { + saveScreenshot(screenshot, finisher, screenshotScreenBounds, visibleInsets, false); + } else { + saveScreenshot(screenshot, finisher, + new Rect(0, 0, screenshot.getWidth(), screenshot.getHeight()), Insets.NONE, + true); + } + } + + /** + * Displays a screenshot selector + */ + @SuppressLint("ClickableViewAccessibility") + void takeScreenshotPartial(final Consumer finisher, Runnable onComplete) { + dismissScreenshot("new screenshot requested", true); + mOnCompleteRunnable = onComplete; + + mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams); + mScreenshotSelectorView.setOnTouchListener((v, event) -> { + ScreenshotSelectorView view = (ScreenshotSelectorView) v; + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + view.startSelection((int) event.getX(), (int) event.getY()); + return true; + case MotionEvent.ACTION_MOVE: + view.updateSelection((int) event.getX(), (int) event.getY()); + return true; + case MotionEvent.ACTION_UP: + view.setVisibility(View.GONE); + mWindowManager.removeView(mScreenshotLayout); + final Rect rect = view.getSelectionRect(); + if (rect != null) { + if (rect.width() != 0 && rect.height() != 0) { + // Need mScreenshotLayout to handle it after the view disappears + mScreenshotLayout.post(() -> takeScreenshotInternal(finisher, rect)); + } + } + + view.stopSelection(); + return true; + } + + return false; + }); + mScreenshotLayout.post(() -> { + mScreenshotSelectorView.setVisibility(View.VISIBLE); + mScreenshotSelectorView.requestFocus(); + }); + } + + /** + * Cancels screenshot request + */ + void stopScreenshot() { + // If the selector layer still presents on screen, we remove it and resets its state. + if (mScreenshotSelectorView.getSelectionRect() != null) { + mWindowManager.removeView(mScreenshotLayout); + mScreenshotSelectorView.stopSelection(); + } + } + + /** + * Clears current screenshot + */ + void dismissScreenshot(String reason, boolean immediate) { + Log.v(TAG, "clearing screenshot: " + reason); + mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT); + mScreenshotLayout.getViewTreeObserver().removeOnComputeInternalInsetsListener(this); + if (!immediate) { + mDismissAnimation = createScreenshotDismissAnimation(); + mDismissAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + clearScreenshot(); + } + }); + mDismissAnimation.start(); + } else { + clearScreenshot(); + } + } + private void onConfigChanged(Configuration newConfig) { boolean needsUpdate = false; // dark mode @@ -408,15 +503,12 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset } return mScreenshotLayout.onApplyWindowInsets(insets); }); - mScreenshotLayout.setOnKeyListener(new View.OnKeyListener() { - @Override - public boolean onKey(View v, int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - dismissScreenshot("back pressed", true); - return true; - } - return false; + mScreenshotLayout.setOnKeyListener((v, keyCode, event) -> { + if (keyCode == KeyEvent.KEYCODE_BACK) { + dismissScreenshot("back pressed", true); + return true; } + return false; }); // Get focus so that the key events go to the layout. mScreenshotLayout.setFocusableInTouchMode(true); @@ -470,60 +562,20 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset } } - /** - * Updates the window focusability. If the window is already showing, then it updates the - * window immediately, otherwise the layout params will be applied when the window is next - * shown. - */ - private void setWindowFocusable(boolean focusable) { - if (focusable) { - mWindowLayoutParams.flags &= ~FLAG_NOT_FOCUSABLE; - } else { - mWindowLayoutParams.flags |= FLAG_NOT_FOCUSABLE; - } - if (mScreenshotLayout.isAttachedToWindow()) { - mWindowManager.updateViewLayout(mScreenshotLayout, mWindowLayoutParams); - } - } - - /** - * Creates a new worker thread and saves the screenshot to the media store. - */ - private void saveScreenshotInWorkerThread( - Consumer finisher, @Nullable ActionsReadyListener actionsReadyListener) { - SaveImageInBackgroundData data = new SaveImageInBackgroundData(); - data.image = mScreenBitmap; - data.finisher = finisher; - data.mActionsReadyListener = actionsReadyListener; - - if (mSaveInBgTask != null) { - // just log success/failure for the pre-existing screenshot - mSaveInBgTask.setActionsReadyListener(new ActionsReadyListener() { - @Override - void onActionsReady(SavedImageData imageData) { - logSuccessOnActionsReady(imageData); - } - }); - } - - mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data); - mSaveInBgTask.execute(); - } - /** * Takes a screenshot of the current display and shows an animation. */ - private void takeScreenshot(Consumer finisher, Rect crop) { + private void takeScreenshotInternal(Consumer finisher, Rect crop) { // copy the input Rect, since SurfaceControl.screenshot can mutate it Rect screenRect = new Rect(crop); int rot = mDisplay.getRotation(); int width = crop.width(); int height = crop.height(); - takeScreenshot(SurfaceControl.screenshot(crop, width, height, rot), finisher, screenRect, + saveScreenshot(SurfaceControl.screenshot(crop, width, height, rot), finisher, screenRect, Insets.NONE, true); } - private void takeScreenshot(Bitmap screenshot, Consumer finisher, Rect screenRect, + private void saveScreenshot(Bitmap screenshot, Consumer finisher, Rect screenRect, Insets screenInsets, boolean showFlash) { dismissScreenshot("new screenshot requested", true); @@ -561,85 +613,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset startAnimation(finisher, screenRect, screenInsets, showFlash); } - void takeScreenshot(Consumer finisher, Runnable onComplete) { - mOnCompleteRunnable = onComplete; - - mDisplay.getRealMetrics(mDisplayMetrics); - takeScreenshot( - finisher, - new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels)); - } - - void handleImageAsScreenshot(Bitmap screenshot, Rect screenshotScreenBounds, - Insets visibleInsets, int taskId, int userId, ComponentName topComponent, - Consumer finisher, Runnable onComplete) { - // TODO: use task Id, userId, topComponent for smart handler - - mOnCompleteRunnable = onComplete; - if (aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) { - takeScreenshot(screenshot, finisher, screenshotScreenBounds, visibleInsets, false); - } else { - takeScreenshot(screenshot, finisher, - new Rect(0, 0, screenshot.getWidth(), screenshot.getHeight()), Insets.NONE, - true); - } - } - - /** - * Displays a screenshot selector - */ - @SuppressLint("ClickableViewAccessibility") - void takeScreenshotPartial(final Consumer finisher, Runnable onComplete) { - dismissScreenshot("new screenshot requested", true); - mOnCompleteRunnable = onComplete; - - mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams); - mScreenshotSelectorView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - ScreenshotSelectorView view = (ScreenshotSelectorView) v; - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - view.startSelection((int) event.getX(), (int) event.getY()); - return true; - case MotionEvent.ACTION_MOVE: - view.updateSelection((int) event.getX(), (int) event.getY()); - return true; - case MotionEvent.ACTION_UP: - view.setVisibility(View.GONE); - mWindowManager.removeView(mScreenshotLayout); - final Rect rect = view.getSelectionRect(); - if (rect != null) { - if (rect.width() != 0 && rect.height() != 0) { - // Need mScreenshotLayout to handle it after the view disappears - mScreenshotLayout.post(() -> takeScreenshot(finisher, rect)); - } - } - - view.stopSelection(); - return true; - } - - return false; - } - }); - mScreenshotLayout.post(() -> { - mScreenshotSelectorView.setVisibility(View.VISIBLE); - mScreenshotSelectorView.requestFocus(); - }); - } - - /** - * Cancels screenshot request - */ - void stopScreenshot() { - // If the selector layer still presents on screen, we remove it and resets its state. - if (mScreenshotSelectorView.getSelectionRect() != null) { - mWindowManager.removeView(mScreenshotLayout); - mScreenshotSelectorView.stopSelection(); - } - } - /** * Save the bitmap but don't show the normal screenshot UI.. just a toast (or notification on * failure). @@ -670,55 +643,78 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset }); } - private boolean isUserSetupComplete() { - return Settings.Secure.getInt(mContext.getContentResolver(), - SETTINGS_SECURE_USER_SETUP_COMPLETE, 0) == 1; + /** + * Starts the animation after taking the screenshot + */ + private void startAnimation(final Consumer finisher, Rect screenRect, Insets screenInsets, + boolean showFlash) { + + // If power save is on, show a toast so there is some visual indication that a + // screenshot has been taken. + PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + if (powerManager.isPowerSaveMode()) { + Toast.makeText(mContext, R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show(); + } + + mScreenshotHandler.post(() -> { + if (!mScreenshotLayout.isAttachedToWindow()) { + mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams); + } + mScreenshotAnimatedView.setImageDrawable( + createScreenDrawable(mScreenBitmap, screenInsets)); + setAnimatedViewSize(screenRect.width(), screenRect.height()); + // Show when the animation starts + mScreenshotAnimatedView.setVisibility(View.GONE); + + mScreenshotPreview.setImageDrawable(createScreenDrawable(mScreenBitmap, screenInsets)); + // make static preview invisible (from gone) so we can query its location on screen + mScreenshotPreview.setVisibility(View.INVISIBLE); + + mScreenshotHandler.post(() -> { + mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this); + + mScreenshotAnimation = + createScreenshotDropInAnimation(screenRect, showFlash); + + saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() { + @Override + void onActionsReady(SavedImageData imageData) { + showUiOnActionsReady(imageData); + } + }); + + // Play the shutter sound to notify that we've taken a screenshot + mCameraSound.play(MediaActionSound.SHUTTER_CLICK); + + mScreenshotPreview.setLayerType(View.LAYER_TYPE_HARDWARE, null); + mScreenshotPreview.buildLayer(); + mScreenshotAnimation.start(); + }); + }); } /** - * Clears current screenshot + * Creates a new worker thread and saves the screenshot to the media store. */ - void dismissScreenshot(String reason, boolean immediate) { - Log.v(TAG, "clearing screenshot: " + reason); - mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT); - mScreenshotLayout.getViewTreeObserver().removeOnComputeInternalInsetsListener(this); - if (!immediate) { - mDismissAnimation = createScreenshotDismissAnimation(); - mDismissAnimation.addListener(new AnimatorListenerAdapter() { + private void saveScreenshotInWorkerThread( + Consumer finisher, @Nullable ActionsReadyListener actionsReadyListener) { + SaveImageInBackgroundData data = new SaveImageInBackgroundData(); + data.image = mScreenBitmap; + data.finisher = finisher; + data.mActionsReadyListener = actionsReadyListener; + + if (mSaveInBgTask != null) { + // just log success/failure for the pre-existing screenshot + mSaveInBgTask.setActionsReadyListener(new ActionsReadyListener() { @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - clearScreenshot(); + void onActionsReady(SavedImageData imageData) { + logSuccessOnActionsReady(imageData); } }); - mDismissAnimation.start(); - } else { - clearScreenshot(); } - } - private void clearScreenshot() { - if (mScreenshotLayout.isAttachedToWindow()) { - mWindowManager.removeView(mScreenshotLayout); - } - - // Clear any references to the bitmap - mScreenshotPreview.setImageDrawable(null); - mScreenshotAnimatedView.setImageDrawable(null); - mScreenshotAnimatedView.setVisibility(View.GONE); - mActionsContainerBackground.setVisibility(View.GONE); - mActionsContainer.setVisibility(View.GONE); - mBackgroundProtection.setAlpha(0f); - mDismissButton.setVisibility(View.GONE); - mScreenshotPreview.setVisibility(View.GONE); - mScreenshotPreview.setLayerType(View.LAYER_TYPE_NONE, null); - mScreenshotPreview.setContentDescription( - mContext.getResources().getString(R.string.screenshot_preview_description)); - mScreenshotLayout.setAlpha(1); - mDismissButton.setTranslationY(0); - mActionsContainer.setTranslationY(0); - mActionsContainerBackground.setTranslationY(0); - mScreenshotPreview.setTranslationY(0); + mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data); + mSaveInBgTask.execute(); } /** @@ -768,56 +764,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset } } - /** - * Starts the animation after taking the screenshot - */ - private void startAnimation(final Consumer finisher, Rect screenRect, Insets screenInsets, - boolean showFlash) { - - // If power save is on, show a toast so there is some visual indication that a - // screenshot has been taken. - PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); - if (powerManager.isPowerSaveMode()) { - Toast.makeText(mContext, R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show(); - } - - mScreenshotHandler.post(() -> { - if (!mScreenshotLayout.isAttachedToWindow()) { - mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams); - } - mScreenshotAnimatedView.setImageDrawable( - createScreenDrawable(mScreenBitmap, screenInsets)); - setAnimatedViewSize(screenRect.width(), screenRect.height()); - // Show when the animation starts - mScreenshotAnimatedView.setVisibility(View.GONE); - - mScreenshotPreview.setImageDrawable(createScreenDrawable(mScreenBitmap, screenInsets)); - // make static preview invisible (from gone) so we can query its location on screen - mScreenshotPreview.setVisibility(View.INVISIBLE); - - mScreenshotHandler.post(() -> { - mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this); - - mScreenshotAnimation = - createScreenshotDropInAnimation(screenRect, showFlash); - - saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() { - @Override - void onActionsReady(SavedImageData imageData) { - showUiOnActionsReady(imageData); - } - }); - - // Play the shutter sound to notify that we've taken a screenshot - mCameraSound.play(MediaActionSound.SHUTTER_CLICK); - - mScreenshotPreview.setLayerType(View.LAYER_TYPE_HARDWARE, null); - mScreenshotPreview.buildLayer(); - mScreenshotAnimation.start(); - }); - }); - } - private AnimatorSet createScreenshotDropInAnimation(Rect bounds, boolean showFlash) { Rect previewBounds = new Rect(); mScreenshotPreview.getBoundsOnScreen(previewBounds); @@ -1070,6 +1016,30 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset return animSet; } + private void clearScreenshot() { + if (mScreenshotLayout.isAttachedToWindow()) { + mWindowManager.removeView(mScreenshotLayout); + } + + // Clear any references to the bitmap + mScreenshotPreview.setImageDrawable(null); + mScreenshotAnimatedView.setImageDrawable(null); + mScreenshotAnimatedView.setVisibility(View.GONE); + mActionsContainerBackground.setVisibility(View.GONE); + mActionsContainer.setVisibility(View.GONE); + mBackgroundProtection.setAlpha(0f); + mDismissButton.setVisibility(View.GONE); + mScreenshotPreview.setVisibility(View.GONE); + mScreenshotPreview.setLayerType(View.LAYER_TYPE_NONE, null); + mScreenshotPreview.setContentDescription( + mContext.getResources().getString(R.string.screenshot_preview_description)); + mScreenshotLayout.setAlpha(1); + mDismissButton.setTranslationY(0); + mActionsContainer.setTranslationY(0); + mActionsContainerBackground.setTranslationY(0); + mScreenshotPreview.setTranslationY(0); + } + private void setAnimatedViewSize(int width, int height) { ViewGroup.LayoutParams layoutParams = mScreenshotAnimatedView.getLayoutParams(); layoutParams.width = width; @@ -1077,6 +1047,27 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset mScreenshotAnimatedView.setLayoutParams(layoutParams); } + /** + * Updates the window focusability. If the window is already showing, then it updates the + * window immediately, otherwise the layout params will be applied when the window is next + * shown. + */ + private void setWindowFocusable(boolean focusable) { + if (focusable) { + mWindowLayoutParams.flags &= ~FLAG_NOT_FOCUSABLE; + } else { + mWindowLayoutParams.flags |= FLAG_NOT_FOCUSABLE; + } + if (mScreenshotLayout.isAttachedToWindow()) { + mWindowManager.updateViewLayout(mScreenshotLayout, mWindowLayoutParams); + } + } + + private boolean isUserSetupComplete() { + return Settings.Secure.getInt(mContext.getContentResolver(), + SETTINGS_SECURE_USER_SETUP_COMPLETE, 0) == 1; + } + /** Does the aspect ratio of the bitmap with insets removed match the bounds. */ private boolean aspectRatiosMatch(Bitmap bitmap, Insets bitmapInsets, Rect screenBounds) { int insettedWidth = bitmap.getWidth() - bitmapInsets.left - bitmapInsets.right; @@ -1128,7 +1119,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset if (insets.left < 0 || insets.top < 0 || insets.right < 0 || insets.bottom < 0) { // Are any of the insets negative, meaning the bitmap is smaller than the bounds so need // to fill in the background of the drawable. - return new LayerDrawable(new Drawable[] { + return new LayerDrawable(new Drawable[]{ new ColorDrawable(Color.BLACK), insetDrawable}); } else { return insetDrawable; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java index 9f8a9bb4a432..6f143da5405a 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java @@ -102,7 +102,7 @@ public class TakeScreenshotService extends Service { switch (msg.what) { case WindowManager.TAKE_SCREENSHOT_FULLSCREEN: - mScreenshot.takeScreenshot(uriConsumer, onComplete); + mScreenshot.takeScreenshotFullscreen(uriConsumer, onComplete); break; case WindowManager.TAKE_SCREENSHOT_SELECTED_REGION: mScreenshot.takeScreenshotPartial(uriConsumer, onComplete); -- GitLab From d1736bd7bfd83b8a1ba66cd70c9f04101f7d9764 Mon Sep 17 00:00:00 2001 From: Lyn Han Date: Wed, 1 Jul 2020 11:52:18 -0700 Subject: [PATCH 012/536] Fix bubble button alignment Set gravity of linear layout parent to "end" Fixes: 159471266 Test: bubble button aligned right in LTR, left in RTL (w/ & w/o actions) Change-Id: If15a70edca8aada3e2891758e15dc4a771099a04 --- core/res/res/layout/notification_material_action_list.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/core/res/res/layout/notification_material_action_list.xml b/core/res/res/layout/notification_material_action_list.xml index 3615b9e2f9cb..df271f0f2942 100644 --- a/core/res/res/layout/notification_material_action_list.xml +++ b/core/res/res/layout/notification_material_action_list.xml @@ -25,6 +25,7 @@ android:id="@+id/actions_container_layout" android:layout_width="match_parent" android:layout_height="wrap_content" + android:gravity="end" android:orientation="horizontal" android:paddingEnd="@dimen/bubble_gone_padding_end" > -- GitLab From 857bc685c9cded2512f424dee8d2e6884cdbd610 Mon Sep 17 00:00:00 2001 From: Robert Snoeberger Date: Wed, 1 Jul 2020 14:18:17 -0400 Subject: [PATCH 013/536] Disable MediaNotificationProcessor Disabling MediaNotificationProcessor when the new media experience is enabled. The notification views that are inflated won't be shown anyway so it is just a waste of time and memory. Fixes: 157732475 Test: manual - heap_profile systemui while SoundCloud is playing. Verify that flame graph doesn't show a hotspot for MediaNotificationProcessor.processNotification Change-Id: I252697255ce2b30c99d244acd4e30cd56eb0416d --- .../row/NotificationContentInflater.java | 16 +++++++++++++--- .../row/NotificationContentInflaterTest.java | 2 ++ .../NotificationEntryManagerInflationTest.java | 2 ++ .../notification/row/NotificationTestHelper.java | 2 ++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java index 582e3e5b6c34..a7d83b3b2774 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java @@ -37,6 +37,8 @@ import android.widget.RemoteViews; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.ImageMessageConsumer; import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.media.MediaDataManagerKt; +import com.android.systemui.media.MediaFeatureFlag; import com.android.systemui.statusbar.InflationTask; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.SmartReplyController; @@ -71,6 +73,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder public static final String TAG = "NotifContentInflater"; private boolean mInflateSynchronously = false; + private final boolean mIsMediaInQS; private final NotificationRemoteInputManager mRemoteInputManager; private final NotifRemoteViewCache mRemoteViewCache; private final Lazy mSmartReplyConstants; @@ -85,12 +88,14 @@ public class NotificationContentInflater implements NotificationRowContentBinder Lazy smartReplyConstants, Lazy smartReplyController, ConversationNotificationProcessor conversationProcessor, + MediaFeatureFlag mediaFeatureFlag, @Background Executor bgExecutor) { mRemoteViewCache = remoteViewCache; mRemoteInputManager = remoteInputManager; mSmartReplyConstants = smartReplyConstants; mSmartReplyController = smartReplyController; mConversationProcessor = conversationProcessor; + mIsMediaInQS = mediaFeatureFlag.getEnabled(); mBgExecutor = bgExecutor; } @@ -135,7 +140,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder bindParams.usesIncreasedHeight, bindParams.usesIncreasedHeadsUpHeight, callback, - mRemoteInputManager.getRemoteViewsOnClickHandler()); + mRemoteInputManager.getRemoteViewsOnClickHandler(), + mIsMediaInQS); if (mInflateSynchronously) { task.onPostExecute(task.doInBackground()); } else { @@ -711,6 +717,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder private RemoteViews.OnClickHandler mRemoteViewClickHandler; private CancellationSignal mCancellationSignal; private final ConversationNotificationProcessor mConversationProcessor; + private final boolean mIsMediaInQS; private AsyncInflationTask( Executor bgExecutor, @@ -726,7 +733,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder boolean usesIncreasedHeight, boolean usesIncreasedHeadsUpHeight, InflationCallback callback, - RemoteViews.OnClickHandler remoteViewClickHandler) { + RemoteViews.OnClickHandler remoteViewClickHandler, + boolean isMediaFlagEnabled) { mEntry = entry; mRow = row; mSmartReplyConstants = smartReplyConstants; @@ -742,6 +750,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder mRemoteViewClickHandler = remoteViewClickHandler; mCallback = callback; mConversationProcessor = conversationProcessor; + mIsMediaInQS = isMediaFlagEnabled; entry.setInflationTask(this); } @@ -765,7 +774,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder packageContext = new RtlEnabledContext(packageContext); } Notification notification = sbn.getNotification(); - if (notification.isMediaNotification()) { + if (notification.isMediaNotification() && !(mIsMediaInQS + && MediaDataManagerKt.isMediaNotification(sbn))) { MediaNotificationProcessor processor = new MediaNotificationProcessor(mContext, packageContext); processor.processNotification(notification, recoveredBuilder); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java index 25da74137a90..3718cd720659 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java @@ -51,6 +51,7 @@ import androidx.test.filters.SmallTest; import androidx.test.filters.Suppress; import com.android.systemui.SysuiTestCase; +import com.android.systemui.media.MediaFeatureFlag; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.SmartReplyController; import com.android.systemui.statusbar.notification.ConversationNotificationProcessor; @@ -110,6 +111,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase { () -> smartReplyConstants, () -> smartReplyController, mConversationNotificationProcessor, + mock(MediaFeatureFlag.class), mock(Executor.class)); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java index 7dfead7575a9..3ea0e5639c71 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java @@ -43,6 +43,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.util.NotificationMessagingUtil; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.media.MediaFeatureFlag; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shared.plugins.PluginManager; @@ -197,6 +198,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { () -> mock(SmartReplyConstants.class), () -> mock(SmartReplyController.class), mock(ConversationNotificationProcessor.class), + mock(MediaFeatureFlag.class), mBgExecutor); mRowContentBindStage = new RowContentBindStage( binder, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index b9eb4d1e29c2..0c6409b38d21 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -46,6 +46,7 @@ import android.widget.RemoteViews; import com.android.systemui.TestableDependency; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.bubbles.BubblesTestActivity; +import com.android.systemui.media.MediaFeatureFlag; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationMediaManager; @@ -133,6 +134,7 @@ public class NotificationTestHelper { () -> mock(SmartReplyConstants.class), () -> mock(SmartReplyController.class), mock(ConversationNotificationProcessor.class), + mock(MediaFeatureFlag.class), mock(Executor.class)); contentBinder.setInflateSynchronously(true); mBindStage = new RowContentBindStage(contentBinder, -- GitLab From 61d251fb66e6f4cc3de735ad8ee9e1c0e697f4f9 Mon Sep 17 00:00:00 2001 From: arangelov Date: Mon, 29 Jun 2020 17:43:24 +0100 Subject: [PATCH 014/536] Force enable vertical scrolling on profile tab change This fixes an edge case where after performing a variety of gestures vertical scrolling ends up disabled. That's because at some point the old tab's vertical scrolling is disabled and the new tab's is enabled. Fixes: 160086572 Test: manually played with scrolling and swiping Test: atest ChoserActivityTest Test: atest ResolverActivityTest Change-Id: Id241bef19af88a48bf43217627d636403a514568 --- core/java/com/android/internal/app/ChooserActivity.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 14cf258f18ab..87d35092a245 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -3127,6 +3127,10 @@ public class ChooserActivity extends ResolverActivity implements ChooserGridAdapter currentRootAdapter = mChooserMultiProfilePagerAdapter.getCurrentRootAdapter(); currentRootAdapter.updateDirectShareExpansion(); + // This fixes an edge case where after performing a variety of gestures, vertical scrolling + // ends up disabled. That's because at some point the old tab's vertical scrolling is + // disabled and the new tab's is enabled. For context, see b/159997845 + setVerticalScrollEnabled(true); } @Override -- GitLab From b85215ff62262b29c8686adc7924765676283ca1 Mon Sep 17 00:00:00 2001 From: arangelov Date: Tue, 30 Jun 2020 18:52:34 +0100 Subject: [PATCH 015/536] Don't update height if recycler view was scrolled Fixes: 159999176 Fixes: 159997845 Test: manual Test: atest ChooserActivityTest Change-Id: Ie867ee419b3595023195022b0f9f12e5da214938 --- core/java/com/android/internal/app/ChooserActivity.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 14cf258f18ab..50579cce23eb 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -2640,7 +2640,10 @@ public class ChooserActivity extends ResolverActivity implements } RecyclerView recyclerView = mChooserMultiProfilePagerAdapter.getActiveAdapterView(); ChooserGridAdapter gridAdapter = mChooserMultiProfilePagerAdapter.getCurrentRootAdapter(); - if (gridAdapter == null || recyclerView == null) { + // Skip height calculation if recycler view was scrolled to prevent it inaccurately + // calculating the height, as the logic below does not account for the scrolled offset. + if (gridAdapter == null || recyclerView == null + || recyclerView.computeVerticalScrollOffset() != 0) { return; } -- GitLab From 3ea519db54ce870b9514355ac6f2d542e294b2f7 Mon Sep 17 00:00:00 2001 From: Danny Epstein Date: Wed, 1 Jul 2020 13:55:01 -0700 Subject: [PATCH 016/536] Clean up FocusParkingViews Put FocusParkingView first rather than last and update comment to indicate that the FocusParkingView must be first. Use start rather than left to position FocusParkingView first. Bug: 131421840 Bug: 154540419 Test: manual Change-Id: I89b9977e1be4722c1e922e360332aa9d631b9540 --- .../CarSystemUI/res/layout/headsup_container_bottom.xml | 7 +++---- .../car/navigationbar/NavigationBarViewFactory.java | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/CarSystemUI/res/layout/headsup_container_bottom.xml b/packages/CarSystemUI/res/layout/headsup_container_bottom.xml index 1782d2536035..5aab0a172b99 100644 --- a/packages/CarSystemUI/res/layout/headsup_container_bottom.xml +++ b/packages/CarSystemUI/res/layout/headsup_container_bottom.xml @@ -29,13 +29,12 @@ android:orientation="horizontal" app:layout_constraintGuide_begin="@dimen/headsup_scrim_height"/> - + Date: Mon, 6 Jul 2020 18:04:47 -0700 Subject: [PATCH 017/536] Don't delay frame scheduling Doing so will lead to state inconsistencies. setExpansionAffectsAlpha won't enque opacity requrests because mUpdatePending won't be true yet, causing sudden opacity changes. The much longer mAnimationDelay will already take care of waiting for a while before starting the scrim animation. Test: manual, with fp sensor Fixes: 158955776 Change-Id: I9f7342f01de36576ba0108edfecbfc97448c8756 --- .../com/android/systemui/statusbar/phone/ScrimController.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 60fc17d9474a..686b87127239 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -348,10 +348,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo } if (mKeyguardUpdateMonitor.needsSlowUnlockTransition() && mState == ScrimState.UNLOCKED) { - // In case the user isn't unlocked, make sure to delay a bit because the system is hosed - // with too many things at this case, in order to not skip the initial frames. - mScrimInFront.postOnAnimationDelayed(this::scheduleUpdate, 16); mAnimationDelay = StatusBar.FADE_KEYGUARD_START_DELAY; + scheduleUpdate(); } else if ((!mDozeParameters.getAlwaysOn() && oldState == ScrimState.AOD) || (mState == ScrimState.AOD && !mDozeParameters.getDisplayNeedsBlanking())) { // Scheduling a frame isn't enough when: -- GitLab From 43a6de043e742827431f8c17640646c9b4dacfa4 Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Mon, 6 Jul 2020 21:28:55 -0400 Subject: [PATCH 018/536] Do not hide the bell icon. Bug: 156887617 Test: Update a notification between 10-30 seconds after the last update, watch bell icon stay visible. Change-Id: Ib737fd78ac5afa26ee0e456ffbee6c6dc0a5c835 --- core/java/android/app/Notification.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 79d2a8102358..76226888bf1a 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -4801,7 +4801,6 @@ public class Notification implements Parcelable contentView.setViewVisibility(R.id.time, View.GONE); contentView.setImageViewIcon(R.id.profile_badge, null); contentView.setViewVisibility(R.id.profile_badge, View.GONE); - contentView.setViewVisibility(R.id.alerted_icon, View.GONE); mN.mUsesStandardHeader = false; } -- GitLab From 723f5f365f98a7d4d0b9d60c776536ae5e07420f Mon Sep 17 00:00:00 2001 From: Tobias Thierer Date: Fri, 5 Jun 2020 14:48:10 +0100 Subject: [PATCH 019/536] Fix state deletion for transient backup issues. Since Android 10, backupPm() includes sendDataToTransport(), which was not previously the case. This means that error handling logic that deletes the backup state file (causing initialize_device() on the next attempt, which deletes any existing backup) will now also be triggered upon errors during sendDataToTransport(), which wasn't previously (Android <= 9) the case. This has the potential of making an existing temporary outage much worse: 1. A few devices might run into temporary issues, e.g. a B&R server returning HTTP 503 Service Unavailable (treated as a TransientHttpStatusException instanceof NetworkException, which is mapped to TRANSPORT_ERROR during handleTransportStatus(), which results in a TaskException with stateCompromised==false but which backupPm() wraps in another TaskException that forces stateCompromised=true). 2. On their next backup attempt, those devices throw away any existing backup and start from scratch (initialize_device()), increasing the load on the server. 3. This leads to a positive-feedback loop where more devices than before run into HTTP 503 Service Unavailable. 4. As a result, masses of devices delete their backups and then hammer the B&R server with attempts to upload new backups. 5. Backups are unavailable to any users who would otherwise rely on them during this outage. To improve on this dangerous situation, this CL changes the code to force stateCompromised=true only for TaskExceptions thrown specifically during extractPmAgentData(), and (as before) for all AgentExceptions. Note that the code is still quite brittle. It still seems like we are probably forcing stateCompromised=true in too many situations, but it's hard to say so this CL is being conservative about the changes. Changing back to the old behavior could be done through a local change around KeyValueBackupTask.java:676; a future CL may do this to have a safety hatch in case we want to cherry-pick this CL into an upcoming Android release late in the release cycle. [1] https://android.googlesource.com/platform/frameworks/base/+/refs/heads/pie-dev/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java#1035 [2] https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java#1040 [3] https://source.corp.google.com/piper///depot/google3/java/com/google/android/gmscore/integ/modules/backup/transport/src/com/google/android/gms/backup/transport/GmsBackupTransport.java;l=770;rcl=281845876 Bug: 144030477 Test: Checked that the following passes after this CL, but testRunTask_whenTransportReturnsErrorForPm_updatesFilesAndCleansUp() fails if I revert the state of KeyValueBackupTask.java to before this CL: ROBOTEST_FILTER=KeyValueBackupTaskTest make \ RunBackupFrameworksServicesRoboTests Change-Id: I6c622c55fbd804ec0a12e0bea7ade1308f7a3877 (cherry picked from commit 819ed81faaa295d9e1096f13f599cb43d48cda88) --- .../backup/keyvalue/KeyValueBackupTask.java | 25 ++++++-- .../keyvalue/KeyValueBackupTaskTest.java | 59 ++++++++++++++++--- 2 files changed, 72 insertions(+), 12 deletions(-) diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java index 5e10916c4491..a4e58a1faeac 100644 --- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java +++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java @@ -649,16 +649,33 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { mReporter.onStartPackageBackup(PM_PACKAGE); mCurrentPackage = new PackageInfo(); mCurrentPackage.packageName = PM_PACKAGE; - try { - extractPmAgentData(mCurrentPackage); + // If we can't even extractPmAgentData(), then we treat the local state as + // compromised, just in case. This means that we will clear data and will + // start from a clean slate in the next attempt. It's not clear whether that's + // the right thing to do, but matches what we have historically done. + try { + extractPmAgentData(mCurrentPackage); + } catch (TaskException e) { + throw TaskException.stateCompromised(e); // force stateCompromised + } + // During sendDataToTransport, we generally trust any thrown TaskException + // about whether stateCompromised because those are likely transient; + // clearing state for those would have the potential to lead to cascading + // failures, as discussed in http://b/144030477. + // For specific status codes (e.g. TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED), + // cleanUpAgentForTransportStatus() or theoretically handleTransportStatus() + // still have the opportunity to perform additional clean-up tasks. int status = sendDataToTransport(mCurrentPackage); cleanUpAgentForTransportStatus(status); } catch (AgentException | TaskException e) { mReporter.onExtractPmAgentDataError(e); cleanUpAgentForError(e); - // PM agent failure is task failure. - throw TaskException.stateCompromised(e); + if (e instanceof TaskException) { + throw (TaskException) e; + } else { + throw TaskException.stateCompromised(e); // PM agent failure is task failure. + } } } diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java index ec56e1ebc8e0..b5c9375fcc0d 100644 --- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java +++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java @@ -122,6 +122,7 @@ import com.android.server.testing.shadows.ShadowBackupDataOutput; import com.android.server.testing.shadows.ShadowEventLog; import com.android.server.testing.shadows.ShadowSystemServiceRegistry; +import com.google.common.base.Charsets; import com.google.common.truth.IterableSubject; import org.junit.After; @@ -1910,7 +1911,8 @@ public class KeyValueBackupTaskTest { } @Test - public void testRunTask_whenTransportReturnsError_updatesFilesAndCleansUp() throws Exception { + public void testRunTask_whenTransportReturnsErrorForGenericPackage_updatesFilesAndCleansUp() + throws Exception { TransportMock transportMock = setUpInitializedTransport(mTransport); when(transportMock.transport.performBackup( argThat(packageInfo(PACKAGE_1)), any(), anyInt())) @@ -1926,6 +1928,39 @@ public class KeyValueBackupTaskTest { assertCleansUpFilesAndAgent(mTransport, PACKAGE_1); } + /** + * Checks that TRANSPORT_ERROR during @pm@ backup keeps the state file untouched. + * http://b/144030477 + */ + @Test + public void testRunTask_whenTransportReturnsErrorForPm_updatesFilesAndCleansUp() + throws Exception { + // TODO(tobiast): Refactor this method to share code with + // testRunTask_whenTransportReturnsErrorForGenericPackage_updatesFilesAndCleansUp + // See patchset 7 of http://ag/11762961 + final PackageData packageData = PM_PACKAGE; + TransportMock transportMock = setUpInitializedTransport(mTransport); + when(transportMock.transport.performBackup( + argThat(packageInfo(packageData)), any(), anyInt())) + .thenReturn(BackupTransport.TRANSPORT_ERROR); + + byte[] pmStateBytes = "fake @pm@ state for testing".getBytes(Charsets.UTF_8); + + Path pmStatePath = createPmStateFile(pmStateBytes.clone()); + PackageManagerBackupAgent pmAgent = spy(createPmAgent()); + KeyValueBackupTask task = createKeyValueBackupTask(transportMock, packageData); + runTask(task); + verify(pmAgent, never()).onBackup(any(), any(), any()); + + assertThat(Files.readAllBytes(pmStatePath)).isEqualTo(pmStateBytes.clone()); + + boolean existed = deletePmStateFile(); + assertThat(existed).isTrue(); + // unbindAgent() is skipped for @pm@. Comment in KeyValueBackupTask.java: + // "For PM metadata (for which applicationInfo is null) there is no agent-bound state." + assertCleansUpFiles(mTransport, packageData); + } + @Test public void testRunTask_whenTransportGetBackupQuotaThrowsForPm() throws Exception { TransportMock transportMock = setUpInitializedTransport(mTransport); @@ -2707,21 +2742,29 @@ public class KeyValueBackupTaskTest { * * */ - private void createPmStateFile() throws IOException { - createPmStateFile(mTransport); + private Path createPmStateFile() throws IOException { + return createPmStateFile("pmState".getBytes()); + } + + private Path createPmStateFile(byte[] bytes) throws IOException { + return createPmStateFile(bytes, mTransport); + } + + private Path createPmStateFile(TransportData transport) throws IOException { + return createPmStateFile("pmState".getBytes(), mTransport); } - /** @see #createPmStateFile() */ - private void createPmStateFile(TransportData transport) throws IOException { - Files.write(getStateFile(transport, PM_PACKAGE), "pmState".getBytes()); + /** @see #createPmStateFile(byte[]) */ + private Path createPmStateFile(byte[] bytes, TransportData transport) throws IOException { + return Files.write(getStateFile(transport, PM_PACKAGE), bytes); } /** * Forces transport initialization and call to {@link * UserBackupManagerService#resetBackupState(File)} */ - private void deletePmStateFile() throws IOException { - Files.deleteIfExists(getStateFile(mTransport, PM_PACKAGE)); + private boolean deletePmStateFile() throws IOException { + return Files.deleteIfExists(getStateFile(mTransport, PM_PACKAGE)); } /** -- GitLab From 206e7d747e67fb7317b2e1b7d59728fa3fc52be8 Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Tue, 7 Jul 2020 15:53:50 -0400 Subject: [PATCH 020/536] Prevent bell icon from disappearing on immediate followup notification. The Ranking object of a notification update has lastAudiblylertedMs of -1 if the notification did not buzz because a buzz happened within the last 5s. This causes the bell icon to disappear on a conversation where a person posted twice within 5s. This is resolved by copying the lastAudiblyAlertedMs from the NotificationEntry's existing Ranking when setting a new one, if the new Ranking's value is -1. Bug: 156887617 Test: Update an alerting notification within 5s of update which caused an alert; bell should stay even though buzz is skipped. Change-Id: Ibb72ab27c88cfa57add781e2746fff0eee5de6be --- .../notification/NotificationListenerService.java | 11 +++++++++++ .../notification/collection/NotificationEntry.java | 2 +- .../systemui/statusbar/policy/HeadsUpManager.java | 6 +++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index c52b02bb6a3c..dfd305330b14 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -1900,6 +1900,17 @@ public abstract class NotificationListenerService extends Service { mIsBubble = isBubble; } + /** + * @hide + */ + public @NonNull Ranking withAudiblyAlertedInfo(@Nullable Ranking previous) { + if (previous != null && previous.mLastAudiblyAlertedMs > 0 + && this.mLastAudiblyAlertedMs <= 0) { + this.mLastAudiblyAlertedMs = previous.mLastAudiblyAlertedMs; + } + return this; + } + /** * @hide */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index 423f85f2ddd0..bd65ef06f3a9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -282,7 +282,7 @@ public final class NotificationEntry extends ListEntry { + " doesn't match existing key " + mKey); } - mRanking = ranking; + mRanking = ranking.withAudiblyAlertedInfo(mRanking); } /* diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java index 07de388598b7..c43ad36d4462 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java @@ -106,9 +106,9 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { public void updateNotification(@NonNull String key, boolean alert) { super.updateNotification(key, alert); - AlertEntry alertEntry = getHeadsUpEntry(key); - if (alert && alertEntry != null) { - setEntryPinned((HeadsUpEntry) alertEntry, shouldHeadsUpBecomePinned(alertEntry.mEntry)); + HeadsUpEntry headsUpEntry = getHeadsUpEntry(key); + if (alert && headsUpEntry != null) { + setEntryPinned(headsUpEntry, shouldHeadsUpBecomePinned(headsUpEntry.mEntry)); } } -- GitLab From 96078b10521676bd60ffff60f14619c1dcdaead6 Mon Sep 17 00:00:00 2001 From: arangelov Date: Wed, 8 Jul 2020 15:53:26 +0100 Subject: [PATCH 021/536] Add bottom offset to the intial padding rather than accumulating it. This prevents the padding from growing on screen rotations. Fixes: 160005616 Test: manual Test: atest ChooserActivityTest Change-Id: I87fcfede3cf9cfad63adeb07b67ed68df403453f --- .../android/internal/app/ChooserMultiProfilePagerAdapter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java index ffa6041721c6..3a65a324f9d6 100644 --- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java @@ -252,8 +252,10 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd @Override protected void setupContainerPadding(View container) { + int initialBottomPadding = getContext().getResources().getDimensionPixelSize( + R.dimen.resolver_empty_state_container_padding_bottom); container.setPadding(container.getPaddingLeft(), container.getPaddingTop(), - container.getPaddingRight(), container.getPaddingBottom() + mBottomOffset); + container.getPaddingRight(), initialBottomPadding + mBottomOffset); } class ChooserProfileDescriptor extends ProfileDescriptor { -- GitLab From 564ace9a92a7b2ddc7b81940b050f7aba52fcdc7 Mon Sep 17 00:00:00 2001 From: Robert Snoeberger Date: Wed, 8 Jul 2020 12:32:34 -0400 Subject: [PATCH 022/536] Unregister broadcast receiver when detached from window Fixes: 160682161 Test: manual - Perform repro steps. Take heap dump. Check that there aren't Clock instances rooted via UserBroadcastDispatcher. Change-Id: Ic5a9f139009845c9e2f608e77067f1502232d522 --- .../com/android/systemui/statusbar/policy/Clock.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index 812ce1c62677..6dd96f92b344 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -82,6 +82,7 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C private boolean mClockVisibleByUser = true; private boolean mAttached; + private boolean mScreenReceiverRegistered; private Calendar mCalendar; private String mClockFormatString; private SimpleDateFormat mClockFormat; @@ -213,6 +214,14 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); + if (mScreenReceiverRegistered) { + mScreenReceiverRegistered = false; + mBroadcastDispatcher.unregisterReceiver(mScreenReceiver); + if (mSecondsHandler != null) { + mSecondsHandler.removeCallbacks(mSecondTick); + mSecondsHandler = null; + } + } if (mAttached) { mBroadcastDispatcher.unregisterReceiver(mIntentReceiver); mAttached = false; @@ -363,12 +372,14 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C mSecondsHandler.postAtTime(mSecondTick, SystemClock.uptimeMillis() / 1000 * 1000 + 1000); } + mScreenReceiverRegistered = true; IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); mBroadcastDispatcher.registerReceiver(mScreenReceiver, filter); } } else { if (mSecondsHandler != null) { + mScreenReceiverRegistered = false; mBroadcastDispatcher.unregisterReceiver(mScreenReceiver); mSecondsHandler.removeCallbacks(mSecondTick); mSecondsHandler = null; -- GitLab From 2c403a6526eea2b153716bac96bf96f6cab252bd Mon Sep 17 00:00:00 2001 From: JianYang Liu Date: Fri, 26 Jun 2020 14:18:11 -0700 Subject: [PATCH 023/536] Added systemui controller to control system bars. When config_remoteInsetsControllerControlsSystemBars is true, DisplaySystemBarsController provides its own policy of how system bars are displayed for specific packages. Currently limited to only auto versions of Android. Bug: 149585273 Test: Manual, atest BarControlPolicyTest, atest InsetsPolicyTest, atest DisplaySystemBarsControllerTest Change-Id: Ie6b1cc3e2760cbc9e48d62dfbd8bc3e23ffca20c Merged-In: Ie6b1cc3e2760cbc9e48d62dfbd8bc3e23ffca20c --- api/test-current.txt | 1 + .../view/IDisplayWindowInsetsController.aidl | 7 + core/java/android/view/IWindowManager.aidl | 10 - core/res/res/values/config.xml | 15 +- core/res/res/values/public.xml | 2 + core/res/res/values/symbols.xml | 2 +- .../android/systemui/CarSystemUIModule.java | 6 + .../android/systemui/wm/BarControlPolicy.java | 250 ++++++++++++++++++ .../wm/DisplaySystemBarsController.java | 168 ++++++++++++ ...DisplaySystemBarsInsetsControllerHost.java | 173 ++++++++++++ .../systemui/wm/BarControlPolicyTest.java | 195 ++++++++++++++ .../wm/DisplaySystemBarsControllerTest.java | 111 ++++++++ .../systemui/wm/DisplayImeController.java | 5 + .../com/android/server/wm/DisplayContent.java | 13 + .../com/android/server/wm/DisplayPolicy.java | 24 +- .../com/android/server/wm/InsetsPolicy.java | 58 +++- .../server/wm/WindowManagerService.java | 21 -- .../server/wm/DisplayContentTests.java | 25 -- .../server/wm/DisplayPolicyLayoutTests.java | 22 -- .../android/server/wm/InsetsPolicyTest.java | 5 +- .../server/wm/WindowManagerServiceTests.java | 18 -- .../android/server/wm/WindowTestsBase.java | 32 ++- 22 files changed, 1034 insertions(+), 129 deletions(-) create mode 100644 packages/CarSystemUI/src/com/android/systemui/wm/BarControlPolicy.java create mode 100644 packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java create mode 100644 packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsInsetsControllerHost.java create mode 100644 packages/CarSystemUI/tests/src/com/android/systemui/wm/BarControlPolicyTest.java create mode 100644 packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java diff --git a/api/test-current.txt b/api/test-current.txt index 3838bad57aa7..cf97b848e80b 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -34,6 +34,7 @@ package android { public static final class R.bool { field public static final int config_assistantOnTopOfDream = 17891333; // 0x1110005 field public static final int config_perDisplayFocusEnabled = 17891332; // 0x1110004 + field public static final int config_remoteInsetsControllerControlsSystemBars = 17891334; // 0x1110006 } public static final class R.string { diff --git a/core/java/android/view/IDisplayWindowInsetsController.aidl b/core/java/android/view/IDisplayWindowInsetsController.aidl index 429c3aeba9b3..a0d4a6587bcf 100644 --- a/core/java/android/view/IDisplayWindowInsetsController.aidl +++ b/core/java/android/view/IDisplayWindowInsetsController.aidl @@ -26,6 +26,13 @@ import android.view.InsetsState; */ oneway interface IDisplayWindowInsetsController { + /** + * Called when top focused window changes to determine whether or not to take over insets + * control. Won't be called if config_remoteInsetsControllerControlsSystemBars is false. + * @param packageName: Passes the top package name + */ + void topFocusedWindowChanged(String packageName); + /** * @see IWindow#insetsChanged */ diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 58597cf3fb6d..00fc67214f75 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -387,16 +387,6 @@ interface IWindowManager */ oneway void hideTransientBars(int displayId); - /** - * When set to {@code true} the system bars will always be shown. This is true even if an app - * requests to be fullscreen by setting the system ui visibility flags. The - * functionality was added for the automotive case as a way to guarantee required content stays - * on screen at all times. - * - * @hide - */ - oneway void setForceShowSystemBars(boolean show); - /** * Called by System UI to notify of changes to the visibility of Recents. */ diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 3d9147448200..3d145c01de11 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -712,10 +712,17 @@ case, this can be disabled (set to false). --> true - - false + + false diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index e2fbbf46608f..e00aff1af37b 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3024,6 +3024,8 @@ + + + {@link android.text.InputType#TYPE_TEXT_FLAG_MULTI_LINE}. + + Note: If this flag is not set and the text field doesn't have max length limit, the + framework automatically set maximum length of the characters to 5000 for the + performance reasons. + --> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 27daf8615a31..837543c9bdae 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -591,6 +591,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback .registerDisplayListener(this, new Handler(Looper.getMainLooper())); mOrientationHandle = new QuickswitchOrientedNavHandle(getContext()); + mOrientationHandle.setId(R.id.secondary_home_handle); getBarTransitions().addDarkIntensityListener(mOrientationHandleIntensityListener); mOrientationParams = new WindowManager.LayoutParams(0, 0, -- GitLab From e7ca377655e71ef923ee02d020abebafe2833b81 Mon Sep 17 00:00:00 2001 From: Lyn Han Date: Fri, 10 Jul 2020 17:37:44 -0500 Subject: [PATCH 033/536] Ensure that bubble badge is always circle Fixes: 159846969 Test: select all the system icon shapes => badge always circle Change-Id: Iec3d09cf851794f1792fa2134e962c3c3ebca083 --- .../systemui/bubbles/BubbleIconFactory.java | 70 +++++++++++++++---- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java index 57e2362bd511..d017bc0e31c2 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java @@ -24,6 +24,8 @@ import android.content.pm.ShortcutInfo; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; @@ -40,15 +42,15 @@ import com.android.systemui.R; */ public class BubbleIconFactory extends BaseIconFactory { + private int mBadgeSize; + protected BubbleIconFactory(Context context) { super(context, context.getResources().getConfiguration().densityDpi, context.getResources().getDimensionPixelSize(R.dimen.individual_bubble_size)); - } - - int getBadgeSize() { - return mContext.getResources().getDimensionPixelSize( + mBadgeSize = mContext.getResources().getDimensionPixelSize( com.android.launcher3.icons.R.dimen.profile_badge_size); } + /** * Returns the drawable that the developer has provided to display in the bubble. */ @@ -78,18 +80,20 @@ public class BubbleIconFactory extends BaseIconFactory { * will include the workprofile indicator on the badge if appropriate. */ BitmapInfo getBadgeBitmap(Drawable userBadgedAppIcon, boolean isImportantConversation) { - Bitmap userBadgedBitmap = createIconBitmap( - userBadgedAppIcon, 1f, getBadgeSize()); - ShadowGenerator shadowGenerator = new ShadowGenerator(getBadgeSize()); - if (!isImportantConversation) { - Canvas c = new Canvas(); - c.setBitmap(userBadgedBitmap); - shadowGenerator.recreateIcon(Bitmap.createBitmap(userBadgedBitmap), c); - return createIconBitmap(userBadgedBitmap); - } else { - float ringStrokeWidth = mContext.getResources().getDimensionPixelSize( + ShadowGenerator shadowGenerator = new ShadowGenerator(mBadgeSize); + Bitmap userBadgedBitmap = createIconBitmap(userBadgedAppIcon, 1f, mBadgeSize); + + if (userBadgedAppIcon instanceof AdaptiveIconDrawable) { + userBadgedBitmap = Bitmap.createScaledBitmap( + getCircleBitmap((AdaptiveIconDrawable) userBadgedAppIcon, /* size */ + userBadgedAppIcon.getIntrinsicWidth()), + mBadgeSize, mBadgeSize, /* filter */ true); + } + + if (isImportantConversation) { + final float ringStrokeWidth = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.importance_ring_stroke_width); - int importantConversationColor = mContext.getResources().getColor( + final int importantConversationColor = mContext.getResources().getColor( com.android.settingslib.R.color.important_conversation, null); Bitmap badgeAndRing = Bitmap.createBitmap(userBadgedBitmap.getWidth(), userBadgedBitmap.getHeight(), userBadgedBitmap.getConfig()); @@ -114,9 +118,45 @@ public class BubbleIconFactory extends BaseIconFactory { shadowGenerator.recreateIcon(Bitmap.createBitmap(badgeAndRing), c); return createIconBitmap(badgeAndRing); + } else { + Canvas c = new Canvas(); + c.setBitmap(userBadgedBitmap); + shadowGenerator.recreateIcon(Bitmap.createBitmap(userBadgedBitmap), c); + return createIconBitmap(userBadgedBitmap); } } + public Bitmap getCircleBitmap(AdaptiveIconDrawable icon, int size) { + Drawable foreground = icon.getForeground(); + Drawable background = icon.getBackground(); + Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(); + canvas.setBitmap(bitmap); + + // Clip canvas to circle. + Path circlePath = new Path(); + circlePath.addCircle(/* x */ size / 2f, + /* y */ size / 2f, + /* radius */ size / 2f, + Path.Direction.CW); + canvas.clipPath(circlePath); + + // Draw background. + background.setBounds(0, 0, size, size); + background.draw(canvas); + + // Draw foreground. The foreground and background drawables are derived from adaptive icons + // Some icon shapes fill more space than others, so adaptive icons are normalized to about + // the same size. This size is smaller than the original bounds, so we estimate + // the difference in this offset. + int offset = size / 5; + foreground.setBounds(-offset, -offset, size + offset, size + offset); + foreground.draw(canvas); + + canvas.setBitmap(null); + return bitmap; + } + /** * Returns a {@link BitmapInfo} for the entire bubble icon including the badge. */ -- GitLab From 7d4f7799ca22020eac3abbade8b39aafd6b2aa64 Mon Sep 17 00:00:00 2001 From: Josh Hou Date: Thu, 28 May 2020 23:32:37 +0800 Subject: [PATCH 034/536] Allow call forwarding number with prefixes to be dialed while on IMS roaming If the carrier supports call forwarding number prefixes to be allowed while on IMS roaming, then the number should be dialed and forwarded successfully Bug: 153413483 Test: Verify the call using *72 is dialed and forwarded successully Change-Id: Ia93dec2ebb11aa3ab8f48975a9b6f02089d1482b --- .../java/android/telephony/CarrierConfigManager.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 318b15293d8d..52f1e37e69f4 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -2344,6 +2344,16 @@ public class CarrierConfigManager { public static final String KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY = "call_forwarding_blocks_while_roaming_string_array"; + /** + * Call forwarding number prefixes defined by {@link + * #KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY} which will be allowed while the + * device is reporting that it is roaming and IMS is registered over LTE or Wi-Fi. + * By default this value is {@code true}. + * @hide + */ + public static final String KEY_SUPPORT_IMS_CALL_FORWARDING_WHILE_ROAMING_BOOL = + "support_ims_call_forwarding_while_roaming_bool"; + /** * The day of the month (1-31) on which the data cycle rolls over. *

@@ -4174,6 +4184,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SHOW_VIDEO_CALL_CHARGES_ALERT_DIALOG_BOOL, false); sDefaults.putStringArray(KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY, null); + sDefaults.putBoolean(KEY_SUPPORT_IMS_CALL_FORWARDING_WHILE_ROAMING_BOOL, true); sDefaults.putInt(KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0); sDefaults.putStringArray(KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY, null); sDefaults.putBoolean(KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL, false); -- GitLab From a3986a5def1070ab7b216e92c4b4ce6eef54dc54 Mon Sep 17 00:00:00 2001 From: Hall Liu Date: Mon, 27 Jan 2020 15:23:25 -0800 Subject: [PATCH 035/536] Allow empty tokens in strict grammar Allow empty tokens in SQLiteQueryBuilder's strict grammar enforcement Bug: 143230980 Test: atest SQLiteQueryBuilderTest, manual Change-Id: Ie82dded77a3eaa75095333b0e77f10e21c9f7caf Merged-In: Ie82dded77a3eaa75095333b0e77f10e21c9f7caf --- core/java/android/provider/CallLog.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index a0e92b398c4e..276f16216b4d 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -98,6 +98,13 @@ public class CallLog { */ public static final String LIMIT_PARAM_KEY = "limit"; + /** + * Form of {@link #CONTENT_URI} which limits the query results to a single result. + */ + private static final Uri CONTENT_URI_LIMIT_1 = CONTENT_URI.buildUpon() + .appendQueryParameter(LIMIT_PARAM_KEY, "1") + .build(); + /** * Query parameter used to specify the starting record to return. *

@@ -932,11 +939,11 @@ public class CallLog { Cursor c = null; try { c = resolver.query( - CONTENT_URI, + CONTENT_URI_LIMIT_1, new String[] {NUMBER}, TYPE + " = " + OUTGOING_TYPE, null, - DEFAULT_SORT_ORDER + " LIMIT 1"); + DEFAULT_SORT_ORDER); if (c == null || !c.moveToFirst()) { return ""; } -- GitLab From 078be01072ff695d517e7131166e37d23ba22ef4 Mon Sep 17 00:00:00 2001 From: kwaky Date: Wed, 8 Jul 2020 07:20:51 -0700 Subject: [PATCH 036/536] DO NOT MERGE Annotate CarSystemUiTests to be run for AAOS pre-submit. Bug: 144452110 Test: atest :carsysui-presubmit under packages/CarSystemUI directory. Change-Id: Icec563e6dc2ee4ad27a8a961caa1ffd97ce68d54 --- packages/CarSystemUI/TEST_MAPPING | 11 +++++++ .../android/systemui/car/CarSystemUiTest.java | 32 +++++++++++++++++++ ...VerifySysuiRequiredTestPropertiesTest.java | 2 ++ .../systemui/car/hvac/HvacControllerTest.java | 2 ++ .../CarKeyguardViewControllerTest.java | 2 ++ .../ButtonRoleHolderControllerTest.java | 2 ++ .../ButtonSelectionStateControllerTest.java | 2 ++ .../CarNavigationBarControllerTest.java | 2 ++ .../navigationbar/CarNavigationBarTest.java | 2 ++ .../CarNavigationBarViewTest.java | 2 ++ .../CarNavigationButtonTest.java | 2 ++ ...eadsUpNotificationSystemContainerTest.java | 2 ++ .../NotificationVisibilityLoggerTest.java | 2 ++ .../sideloaded/SideLoadedAppDetectorTest.java | 2 ++ .../sideloaded/SideLoadedAppListenerTest.java | 2 ++ ...serSwitchTransitionViewControllerTest.java | 2 ++ .../UserSwitchTransitionViewMediatorTest.java | 2 ++ ...tedDeviceVoiceRecognitionNotifierTest.java | 2 ++ .../OverlayPanelViewControllerTest.java | 2 ++ .../car/window/OverlayViewControllerTest.java | 2 ++ .../OverlayViewGlobalStateControllerTest.java | 2 ++ 21 files changed, 81 insertions(+) create mode 100644 packages/CarSystemUI/src/com/android/systemui/car/CarSystemUiTest.java diff --git a/packages/CarSystemUI/TEST_MAPPING b/packages/CarSystemUI/TEST_MAPPING index 6056ddfc0bc7..c18a12aeb2aa 100644 --- a/packages/CarSystemUI/TEST_MAPPING +++ b/packages/CarSystemUI/TEST_MAPPING @@ -8,5 +8,16 @@ } ] } + ], + + "carsysui-presubmit": [ + { + "name": "CarSystemUITests", + "options" : [ + { + "include-annotation": "com.android.systemui.car.CarSystemUiTest" + } + ] + } ] } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarSystemUiTest.java b/packages/CarSystemUI/src/com/android/systemui/car/CarSystemUiTest.java new file mode 100644 index 000000000000..5f593b06c511 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/car/CarSystemUiTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 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.car; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotates that a test class should be run as part of CarSystemUI presubmit + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +public @interface CarSystemUiTest { +} diff --git a/packages/CarSystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java b/packages/CarSystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java index fe59cbf20a13..d769cacadf1d 100644 --- a/packages/CarSystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java +++ b/packages/CarSystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java @@ -33,6 +33,7 @@ import androidx.test.internal.runner.ClassPathScanner.ExternalClassNameFilter; import com.android.systemui.SysuiBaseFragmentTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarSystemUiTest; import org.junit.Test; import org.junit.runner.RunWith; @@ -55,6 +56,7 @@ import java.util.Collections; * test suite causes errors, such as the incorrect settings provider being cached. * For an example, see {@link com.android.systemui.DependencyTest}. */ +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @SmallTest public class AAAPlusPlusVerifySysuiRequiredTestPropertiesTest extends SysuiTestCase { diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java index 7996170ba7d6..e179ef1ce2a4 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java @@ -32,6 +32,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.car.CarSystemUiTest; import org.junit.Before; import org.junit.Test; @@ -39,6 +40,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java index 189e240169c3..62dc23624520 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java @@ -41,6 +41,7 @@ import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.car.navigationbar.CarNavigationBarController; import com.android.systemui.car.window.OverlayViewGlobalStateController; import com.android.systemui.keyguard.DismissCallbackRegistry; @@ -59,6 +60,7 @@ import org.mockito.MockitoAnnotations; import dagger.Lazy; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonRoleHolderControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonRoleHolderControllerTest.java index a57736bb3502..4b8268052324 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonRoleHolderControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonRoleHolderControllerTest.java @@ -39,6 +39,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.car.CarDeviceProvisionedController; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.tests.R; import org.junit.Before; @@ -49,6 +50,7 @@ import org.mockito.MockitoAnnotations; import java.util.List; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java index 893057e222a9..f623c26d12b6 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java @@ -28,6 +28,7 @@ import android.widget.LinearLayout; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.tests.R; import org.junit.Before; @@ -38,6 +39,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java index e84e42c77245..dec8b8ecdfb4 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java @@ -31,6 +31,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.car.hvac.HvacController; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.phone.StatusBarIconController; @@ -41,6 +42,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java index 0caa86f0eab2..d9edfa960858 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java @@ -45,6 +45,7 @@ import com.android.internal.view.AppearanceRegion; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.car.CarDeviceProvisionedController; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.LightBarController; @@ -63,6 +64,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java index 19e394f69af4..47fd8201d197 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java @@ -30,6 +30,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarSystemUiTest; import org.junit.After; import org.junit.Before; @@ -38,6 +39,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java index bcaa5e9a03ee..173f5487c728 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java @@ -37,6 +37,7 @@ import android.widget.LinearLayout; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.statusbar.AlphaOptimizedImageView; import com.android.systemui.tests.R; @@ -45,6 +46,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainerTest.java index ccaeb458fe54..384888ab42c3 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainerTest.java @@ -30,6 +30,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.car.CarDeviceProvisionedController; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.car.window.OverlayViewGlobalStateController; import org.junit.Before; @@ -38,6 +39,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/NotificationVisibilityLoggerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/NotificationVisibilityLoggerTest.java index 89dac58cd2a7..d51aeb18135d 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/NotificationVisibilityLoggerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/notification/NotificationVisibilityLoggerTest.java @@ -37,6 +37,7 @@ import com.android.car.notification.NotificationDataManager; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; @@ -49,6 +50,7 @@ import org.mockito.MockitoAnnotations; import java.util.Collections; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java index 77620f3fb345..421e2109356d 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java @@ -37,6 +37,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.car.CarDeviceProvisionedController; +import com.android.systemui.car.CarSystemUiTest; import org.junit.Before; import org.junit.Test; @@ -44,6 +45,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java index 73f9f6a55afc..20576e9ec11f 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java @@ -35,6 +35,7 @@ import android.view.DisplayInfo; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarSystemUiTest; import org.junit.Before; import org.junit.Test; @@ -46,6 +47,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java index 797dbf515b7e..2e9d43b595a1 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java @@ -36,6 +36,7 @@ import android.view.ViewGroup; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.car.window.OverlayViewGlobalStateController; import org.junit.Before; @@ -44,6 +45,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java index a808e2d40e26..de6feb64391f 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java @@ -25,6 +25,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.car.CarSystemUiTest; import org.junit.Before; import org.junit.Test; @@ -32,6 +33,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java index 232df2eced39..31f1170c9603 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/voicerecognition/ConnectedDeviceVoiceRecognitionNotifierTest.java @@ -35,11 +35,13 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarSystemUiTest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java index 45a05ac69bd7..7311cdb68a3c 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java @@ -39,6 +39,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.car.CarDeviceProvisionedController; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.tests.R; @@ -52,6 +53,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java index c24a3b52e348..e784761f6d5d 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java @@ -29,6 +29,7 @@ import android.view.ViewGroup; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.tests.R; import org.junit.Before; @@ -39,6 +40,7 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java index cba42e5a9be4..20f9bc8ec1cb 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java @@ -32,6 +32,7 @@ import android.view.ViewStub; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarSystemUiTest; import com.android.systemui.car.navigationbar.CarNavigationBarController; import com.android.systemui.tests.R; @@ -44,6 +45,7 @@ import org.mockito.MockitoAnnotations; import java.util.Arrays; +@CarSystemUiTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest -- GitLab From 925a102e10622b74d0abac6526469dc6d1bfc23c Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Tue, 14 Jul 2020 15:26:32 -0700 Subject: [PATCH 037/536] Animate when removing PiP Fade out the PiP window when PipTaskOrganizer#removePip is called, which covers the following scenarios: - Tap on the close button - Drag the PiP window to close area - Disable PiP via settings Note that when dragging to remove, we spring also the window off screen and therefore, the fade out animation does not really appealing in that case. Video is taken with 10x normal duration. Video: http://rcll/aaaaaabFQoRHlzixHdtY/gZfSf7SaGKepwiqvXA15dx Bug: 159805747 Test: see video Change-Id: Icc26c81711bae69bd00a2812661c00fd93055a92 --- .../systemui/pip/PipAnimationController.java | 11 +++-- .../systemui/pip/PipTaskOrganizer.java | 41 ++++++++++++------- .../pip/PipAnimationControllerTest.java | 3 +- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java index ead17867844a..72019315139b 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java @@ -21,7 +21,6 @@ import android.animation.Animator; import android.animation.RectEvaluator; import android.animation.ValueAnimator; import android.annotation.IntDef; -import android.content.Context; import android.graphics.Rect; import android.view.SurfaceControl; @@ -56,13 +55,15 @@ public class PipAnimationController { public static final int TRANSITION_DIRECTION_TO_PIP = 2; public static final int TRANSITION_DIRECTION_TO_FULLSCREEN = 3; public static final int TRANSITION_DIRECTION_TO_SPLIT_SCREEN = 4; + public static final int TRANSITION_DIRECTION_REMOVE_STACK = 5; @IntDef(prefix = { "TRANSITION_DIRECTION_" }, value = { TRANSITION_DIRECTION_NONE, TRANSITION_DIRECTION_SAME, TRANSITION_DIRECTION_TO_PIP, TRANSITION_DIRECTION_TO_FULLSCREEN, - TRANSITION_DIRECTION_TO_SPLIT_SCREEN + TRANSITION_DIRECTION_TO_SPLIT_SCREEN, + TRANSITION_DIRECTION_REMOVE_STACK }) @Retention(RetentionPolicy.SOURCE) public @interface TransitionDirection {} @@ -88,7 +89,7 @@ public class PipAnimationController { }); @Inject - PipAnimationController(Context context, PipSurfaceTransactionHelper helper) { + PipAnimationController(PipSurfaceTransactionHelper helper) { mSurfaceTransactionHelper = helper; } @@ -338,6 +339,10 @@ public class PipAnimationController { @Override void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) { + if (getTransitionDirection() == TRANSITION_DIRECTION_REMOVE_STACK) { + // while removing the pip stack, no extra work needs to be done here. + return; + } getSurfaceTransactionHelper() .resetScale(tx, leash, getDestinationBounds()) .crop(tx, leash, getDestinationBounds()) diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 0141dee04086..c4152fa9a4e7 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -24,6 +24,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_ALPHA; import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_BOUNDS; import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_NONE; +import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_REMOVE_STACK; import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_SAME; import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN; import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP; @@ -337,23 +338,32 @@ public class PipTaskOrganizer extends TaskOrganizer implements + " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken); return; } - getUpdateHandler().post(() -> { - try { - // Reset the task bounds first to ensure the activity configuration is reset as well - final WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.setBounds(mToken, null); - WindowOrganizer.applyTransaction(wct); - - ActivityTaskManager.getService().removeStacksInWindowingModes( - new int[]{ WINDOWING_MODE_PINNED }); - } catch (RemoteException e) { - Log.e(TAG, "Failed to remove PiP", e); - } - }); + + // removePipImmediately is expected when the following animation finishes. + mUpdateHandler.post(() -> mPipAnimationController + .getAnimator(mLeash, mLastReportedBounds, 1f, 0f) + .setTransitionDirection(TRANSITION_DIRECTION_REMOVE_STACK) + .setPipAnimationCallback(mPipAnimationCallback) + .setDuration(mEnterExitAnimationDuration) + .start()); mInitialState.remove(mToken.asBinder()); mExitingPip = true; } + private void removePipImmediately() { + try { + // Reset the task bounds first to ensure the activity configuration is reset as well + final WindowContainerTransaction wct = new WindowContainerTransaction(); + wct.setBounds(mToken, null); + WindowOrganizer.applyTransaction(wct); + + ActivityTaskManager.getService().removeStacksInWindowingModes( + new int[]{ WINDOWING_MODE_PINNED }); + } catch (RemoteException e) { + Log.e(TAG, "Failed to remove PiP", e); + } + } + @Override public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) { Objects.requireNonNull(info, "Requires RunningTaskInfo"); @@ -803,7 +813,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements + "directly"); } mLastReportedBounds.set(destinationBounds); - if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA) { + if (direction == TRANSITION_DIRECTION_REMOVE_STACK) { + removePipImmediately(); + return; + } else if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA) { return; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java index 536cae4380c4..c9c111198f4c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/pip/PipAnimationControllerTest.java @@ -61,8 +61,7 @@ public class PipAnimationControllerTest extends SysuiTestCase { @Before public void setUp() throws Exception { mPipAnimationController = new PipAnimationController( - mContext, new PipSurfaceTransactionHelper(mContext, - mock(ConfigurationController.class))); + new PipSurfaceTransactionHelper(mContext, mock(ConfigurationController.class))); mLeash = new SurfaceControl.Builder() .setContainerLayer() .setName("FakeLeash") -- GitLab From 98bf74b77624dc92938a8ee257d793a10d494fa2 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Wed, 15 Jul 2020 10:04:49 +0800 Subject: [PATCH 038/536] Skip resuming activities on sleeping display Bubble activity was resumed while the ActivityView was hidden after device unlocked. Also reduce always resuming activities from RWC since already looping through all displays when applying sleep tokens. Bug: 160338354 Test: atest RootActivityContainerTests Change-Id: I7f08e09fb9273a3ae7855728ed6f4eb1b7fdb206 Merged-in: I7f08e09fb9273a3ae7855728ed6f4eb1b7fdb206 --- .../android/server/wm/RootWindowContainer.java | 8 ++++++-- .../server/wm/RootActivityContainerTests.java | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 4700864c03bc..84a389349204 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2300,8 +2300,12 @@ class RootWindowContainer extends WindowContainer } for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { - boolean resumedOnDisplay = false; final DisplayContent display = getChildAt(displayNdx); + if (display.shouldSleep()) { + continue; + } + + boolean resumedOnDisplay = false; for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { @@ -2390,7 +2394,7 @@ class RootWindowContainer extends WindowContainer // process the keyguard going away, which can happen before the sleep // token is released. As a result, it is important we resume the // activity here. - resumeFocusedStacksTopActivities(); + stack.resumeTopActivityUncheckedLocked(null, null); } // The visibility update must not be called before resuming the top, so the // display orientation can be updated first if needed. Otherwise there may diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java index 51db099676b0..c848736a64c2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java @@ -896,6 +896,24 @@ public class RootActivityContainerTests extends ActivityTestsBase { assertEquals(taskDisplayArea.getTopStack(), taskDisplayArea.getRootHomeTask()); } + @Test + public void testResumeFocusedStackOnSleepingDisplay() { + // Create an activity on secondary display. + final TestDisplayContent secondDisplay = addNewDisplayContentAt( + DisplayContent.POSITION_TOP); + final ActivityStack stack = secondDisplay.getDefaultTaskDisplayArea() + .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); + final ActivityRecord activity = new ActivityBuilder(mService).setStack(stack).build(); + spyOn(activity); + spyOn(stack); + + // Cannot resumed activities on secondary display if the display should sleep. + doReturn(true).when(secondDisplay).shouldSleep(); + mRootWindowContainer.resumeFocusedStacksTopActivities(); + verify(stack, never()).resumeTopActivityUncheckedLocked(any(), any()); + verify(activity, never()).makeActiveIfNeeded(any()); + } + /** * Mock {@link RootWindowContainer#resolveHomeActivity} for returning consistent activity * info for test cases. -- GitLab From dce238b63f0e6616ea2e03cc80dea8874dbb3e48 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Wed, 15 Jul 2020 11:55:48 -0400 Subject: [PATCH 039/536] Make the build text in QS marquee The text marquees only when visible. Test: manual Test: manual check that it's not announced prematurely Fixes: 158410766 Change-Id: Iede2b8d20de4f87f6bbc95f228376bb5bf488a9e --- .../SystemUI/res/layout/qs_footer_impl.xml | 2 +- .../com/android/systemui/qs/QSFooterImpl.java | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml index 5c00af5705e9..436188a83d4f 100644 --- a/packages/SystemUI/res/layout/qs_footer_impl.xml +++ b/packages/SystemUI/res/layout/qs_footer_impl.xml @@ -62,7 +62,7 @@ android:gravity="center_vertical" android:focusable="true" android:singleLine="true" - android:ellipsize="end" + android:ellipsize="marquee" android:textAppearance="@style/TextAppearance.QS.Status" android:layout_marginEnd="4dp" android:visibility="gone"/> diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java index c4bb4e86e41e..6e4ab9a3323a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java @@ -78,6 +78,8 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, private SettingsButton mSettingsButton; protected View mSettingsContainer; private PageIndicator mPageIndicator; + private TextView mBuildText; + private boolean mShouldShowBuildText; private boolean mQsDisabled; private QSPanel mQsPanel; @@ -147,6 +149,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, mActionsContainer = findViewById(R.id.qs_footer_actions_container); mEditContainer = findViewById(R.id.qs_footer_actions_edit_container); + mBuildText = findViewById(R.id.build); // RenderThread is doing more harm than good when touching the header (to expand quick // settings), so disable it for this view @@ -162,16 +165,19 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, } private void setBuildText() { - TextView v = findViewById(R.id.build); - if (v == null) return; + if (mBuildText == null) return; if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) { - v.setText(mContext.getString( + mBuildText.setText(mContext.getString( com.android.internal.R.string.bugreport_status, Build.VERSION.RELEASE_OR_CODENAME, Build.ID)); - v.setVisibility(View.VISIBLE); + // Set as selected for marquee before its made visible, then it won't be announced when + // it's made visible. + mBuildText.setSelected(true); + mShouldShowBuildText = true; } else { - v.setVisibility(View.GONE); + mShouldShowBuildText = false; + mBuildText.setSelected(false); } } @@ -321,6 +327,8 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, mMultiUserSwitch.setVisibility(showUserSwitcher() ? View.VISIBLE : View.INVISIBLE); mEditContainer.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE); mSettingsButton.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE); + + mBuildText.setVisibility(mExpanded && mShouldShowBuildText ? View.VISIBLE : View.GONE); } private boolean showUserSwitcher() { -- GitLab From 7652ae9080b8cdb3c619982465228778fbc45736 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 14 Jul 2020 12:23:21 -0700 Subject: [PATCH 040/536] Don't clone the locale redundantly in Configuration.setTo() When updating an existing Configuration instance, don't create a new clone of the pattern's embedded Locale unless it is materially different from the existing instance's own. Bug: 161264248 Test: boot & run Test: atest AppConfigurationTests Test: atest ConfigChangeTests Test: atest LocaleListTest Change-Id: I5dc0598b89305c488ba50c1774ecdabf939a6ccc Merged-In: I5dc0598b89305c488ba50c1774ecdabf939a6ccc --- core/java/android/content/res/Configuration.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index 6a9e0aa047d1..9480d369065d 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -45,7 +45,6 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.app.UiModeManager; import android.app.WindowConfiguration; import android.compat.annotation.UnsupportedAppUsage; import android.content.LocaleProto; @@ -928,7 +927,13 @@ public final class Configuration implements Parcelable, Comparable Date: Fri, 10 Jul 2020 14:33:26 -0400 Subject: [PATCH 041/536] Update PowerNotificationWarnings Test: manual Fixes: 160969580 Change-Id: I451338d8fcad71d1e3d95cbc08808d76f8b7d991 --- packages/SystemUI/res/values/strings.xml | 21 ++++++--- .../power/PowerNotificationWarnings.java | 43 ++++++++++++++++++- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index db45a60ab7c0..f51cffcdfb5c 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2404,17 +2404,26 @@ Phone turned off due to heat - - Your phone is now running normally - + + Your phone is now running normally.\nTap for more info + Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n\t• Use resource-intensive apps (such as gaming, video, or navigation apps)\n\t• Download or upload large files\n\t• Use your phone in high temperatures + + See care steps + + Phone is getting warm - - Some features limited while phone cools down - + + Some features limited while phone cools down.\nTap for more info + Your phone will automatically try to cool down. You can still use your phone, but it may run slower.\n\nOnce your phone has cooled down, it will run normally. + + See care steps + + + Unplug charger diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java index 10b04c0129e4..6abbbbeaa397 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java @@ -24,6 +24,7 @@ import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.media.AudioAttributes; @@ -376,13 +377,15 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { return; } mHighTempWarning = true; + final String message = mContext.getString(R.string.high_temp_notif_message); final Notification.Builder nb = new Notification.Builder(mContext, NotificationChannels.ALERTS) .setSmallIcon(R.drawable.ic_device_thermostat_24) .setWhen(0) .setShowWhen(false) .setContentTitle(mContext.getString(R.string.high_temp_title)) - .setContentText(mContext.getString(R.string.high_temp_notif_message)) + .setContentText(message) + .setStyle(new Notification.BigTextStyle().bigText(message)) .setVisibility(Notification.VISIBILITY_PUBLIC) .setContentIntent(pendingBroadcast(ACTION_CLICKED_TEMP_WARNING)) .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_TEMP_WARNING)) @@ -402,6 +405,23 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { d.setPositiveButton(com.android.internal.R.string.ok, null); d.setShowForAllUsers(true); d.setOnDismissListener(dialog -> mHighTempDialog = null); + final String url = mContext.getString(R.string.high_temp_dialog_help_url); + if (!url.isEmpty()) { + d.setNeutralButton(R.string.high_temp_dialog_help_text, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final Intent helpIntent = + new Intent(Intent.ACTION_VIEW) + .setData(Uri.parse(url)) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Dependency.get(ActivityStarter.class).startActivity(helpIntent, + true /* dismissShade */, resultCode -> { + mHighTempDialog = null; + }); + } + }); + } d.show(); mHighTempDialog = d; } @@ -420,19 +440,38 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { d.setPositiveButton(com.android.internal.R.string.ok, null); d.setShowForAllUsers(true); d.setOnDismissListener(dialog -> mThermalShutdownDialog = null); + final String url = mContext.getString(R.string.thermal_shutdown_dialog_help_url); + if (!url.isEmpty()) { + d.setNeutralButton(R.string.thermal_shutdown_dialog_help_text, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final Intent helpIntent = + new Intent(Intent.ACTION_VIEW) + .setData(Uri.parse(url)) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Dependency.get(ActivityStarter.class).startActivity(helpIntent, + true /* dismissShade */, resultCode -> { + mThermalShutdownDialog = null; + }); + } + }); + } d.show(); mThermalShutdownDialog = d; } @Override public void showThermalShutdownWarning() { + final String message = mContext.getString(R.string.thermal_shutdown_message); final Notification.Builder nb = new Notification.Builder(mContext, NotificationChannels.ALERTS) .setSmallIcon(R.drawable.ic_device_thermostat_24) .setWhen(0) .setShowWhen(false) .setContentTitle(mContext.getString(R.string.thermal_shutdown_title)) - .setContentText(mContext.getString(R.string.thermal_shutdown_message)) + .setContentText(message) + .setStyle(new Notification.BigTextStyle().bigText(message)) .setVisibility(Notification.VISIBILITY_PUBLIC) .setContentIntent(pendingBroadcast(ACTION_CLICKED_THERMAL_SHUTDOWN_WARNING)) .setDeleteIntent( -- GitLab From 10789f19d79cb35dadb495ab8b58071cc5af59a5 Mon Sep 17 00:00:00 2001 From: Sarah Chin Date: Mon, 13 Jul 2020 16:54:23 -0700 Subject: [PATCH 042/536] Add icon logic for 5G SA mode Test: manual test with fake NR SA ServiceState Bug: 153395625 Change-Id: Ic15d2a0ce0fd287f44e244d08ba399f83f6100b7 Merged-In: Ic15d2a0ce0fd287f44e244d08ba399f83f6100b7 (cherry picked from commit e375b1e50c25bee8f03ff2bf0f58072a64c81ddc) --- .../systemui/statusbar/policy/MobileSignalController.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 18a7adda3f7d..cf83603997c0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -284,6 +284,9 @@ public class MobileSignalController extends SignalController< mNetworkToIconLookup.put(toDisplayIconKey( TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE), TelephonyIcons.NR_5G_PLUS); + mNetworkToIconLookup.put(toIconKey( + TelephonyManager.NETWORK_TYPE_NR), + TelephonyIcons.NR_5G); } private String getIconKey() { @@ -306,9 +309,9 @@ public class MobileSignalController extends SignalController< case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO: return toIconKey(TelephonyManager.NETWORK_TYPE_LTE) + "_CA_Plus"; case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA: - return "5G"; + return toIconKey(TelephonyManager.NETWORK_TYPE_NR); case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE: - return "5G_Plus"; + return toIconKey(TelephonyManager.NETWORK_TYPE_NR) + "_Plus"; default: return "unsupported"; } -- GitLab From 7b1c1db80aebc39f704360ad2ec636d912d470d2 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Wed, 15 Jul 2020 14:31:13 -0700 Subject: [PATCH 043/536] Check foreground and appOps for BiometricPrompt#authenticate Bug: 158481661 Test: Callers with incorrect opPackageName are no longer able to request auth Test: Callers not in foreground are no longer able to request auth Test: atest AuthServiceTest Change-Id: Ic26e47c11395a5fded1d2ab3e75466fdbd6c2f1b Merged-In: Ic26e47c11395a5fded1d2ab3e75466fdbd6c2f1b --- .../server/biometrics/AuthService.java | 25 +++++++++++- .../biometrics/BiometricServiceBase.java | 25 +----------- .../com/android/server/biometrics/Utils.java | 29 ++++++++++++++ .../server/biometrics/AuthServiceTest.java | 40 ++++++++++++++++++- 4 files changed, 92 insertions(+), 27 deletions(-) diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java index 061972c5723a..131267924179 100644 --- a/services/core/java/com/android/server/biometrics/AuthService.java +++ b/services/core/java/com/android/server/biometrics/AuthService.java @@ -28,6 +28,7 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRIN import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS; import static android.hardware.biometrics.BiometricManager.Authenticators; +import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.biometrics.BiometricPrompt; @@ -128,6 +129,11 @@ public class AuthService extends SystemService { return IIrisService.Stub.asInterface( ServiceManager.getService(Context.IRIS_SERVICE)); } + + @VisibleForTesting + public AppOpsManager getAppOps(Context context) { + return context.getSystemService(AppOpsManager.class); + } } private final class AuthServiceImpl extends IAuthService.Stub { @@ -138,6 +144,8 @@ public class AuthService extends SystemService { // Only allow internal clients to authenticate with a different userId. final int callingUserId = UserHandle.getCallingUserId(); + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); if (userId == callingUserId) { checkPermission(); } else { @@ -146,6 +154,16 @@ public class AuthService extends SystemService { checkInternalPermission(); } + if (!checkAppOps(callingUid, opPackageName, "authenticate()")) { + Slog.e(TAG, "Denied by app ops: " + opPackageName); + return; + } + + if (!Utils.isForeground(callingUid, callingPid)) { + Slog.e(TAG, "Caller is not foreground: " + opPackageName); + return; + } + if (token == null || receiver == null || opPackageName == null || bundle == null) { Slog.e(TAG, "Unable to authenticate, one or more null arguments"); return; @@ -163,8 +181,6 @@ public class AuthService extends SystemService { checkInternalPermission(); } - final int callingUid = Binder.getCallingUid(); - final int callingPid = Binder.getCallingPid(); final long identity = Binder.clearCallingIdentity(); try { mBiometricService.authenticate( @@ -392,4 +408,9 @@ public class AuthService extends SystemService { "Must have USE_BIOMETRIC permission"); } } + + private boolean checkAppOps(int uid, String opPackageName, String reason) { + return mInjector.getAppOps(getContext()).noteOp(AppOpsManager.OP_USE_BIOMETRIC, uid, + opPackageName, null /* attributionTag */, reason) == AppOpsManager.MODE_ALLOWED; + } } diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java index 75452ea5fb61..88469a2caee8 100644 --- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java +++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java @@ -1019,7 +1019,7 @@ public abstract class BiometricServiceBase extends SystemService return false; } - if (requireForeground && !(isForegroundActivity(uid, pid) || isCurrentClient( + if (requireForeground && !(Utils.isForeground(uid, pid) || isCurrentClient( opPackageName))) { Slog.w(getTag(), "Rejecting " + opPackageName + "; not in foreground"); return false; @@ -1042,29 +1042,6 @@ public abstract class BiometricServiceBase extends SystemService return mKeyguardPackage.equals(clientPackage); } - private boolean isForegroundActivity(int uid, int pid) { - try { - final List procs = - ActivityManager.getService().getRunningAppProcesses(); - if (procs == null) { - Slog.e(getTag(), "Processes null, defaulting to true"); - return true; - } - - int N = procs.size(); - for (int i = 0; i < N; i++) { - ActivityManager.RunningAppProcessInfo proc = procs.get(i); - if (proc.pid == pid && proc.uid == uid - && proc.importance <= IMPORTANCE_FOREGROUND_SERVICE) { - return true; - } - } - } catch (RemoteException e) { - Slog.w(getTag(), "am.getRunningAppProcesses() failed"); - } - return false; - } - /** * Calls the HAL to switch states to the new task. If there's already a current task, * it calls cancel() and sets mPendingClient to begin when the current task finishes diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java index 14378da0a90b..543ce575b1fc 100644 --- a/services/core/java/com/android/server/biometrics/Utils.java +++ b/services/core/java/com/android/server/biometrics/Utils.java @@ -16,8 +16,10 @@ package com.android.server.biometrics; +import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; import static android.hardware.biometrics.BiometricManager.Authenticators; +import android.app.ActivityManager; import android.content.Context; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricManager; @@ -25,11 +27,16 @@ import android.hardware.biometrics.BiometricPrompt; import android.hardware.biometrics.BiometricPrompt.AuthenticationResultType; import android.os.Build; import android.os.Bundle; +import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.util.Slog; +import java.util.List; + public class Utils { + private static final String TAG = "BiometricUtils"; + public static boolean isDebugEnabled(Context context, int targetUserId) { if (targetUserId == UserHandle.USER_NULL) { return false; @@ -256,4 +263,26 @@ public class Utils { throw new IllegalArgumentException("Unsupported dismissal reason: " + reason); } } + + public static boolean isForeground(int callingUid, int callingPid) { + try { + final List procs = + ActivityManager.getService().getRunningAppProcesses(); + if (procs == null) { + Slog.e(TAG, "No running app processes found, defaulting to true"); + return true; + } + + for (int i = 0; i < procs.size(); i++) { + ActivityManager.RunningAppProcessInfo proc = procs.get(i); + if (proc.pid == callingPid && proc.uid == callingUid + && proc.importance <= IMPORTANCE_FOREGROUND_SERVICE) { + return true; + } + } + } catch (RemoteException e) { + Slog.w(TAG, "am.getRunningAppProcesses() failed"); + } + return false; + } } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java index 30bb38a075be..ad0b092b5543 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java @@ -28,6 +28,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback; @@ -72,6 +73,8 @@ public class AuthServiceTest { IIrisService mIrisService; @Mock IFaceService mFaceService; + @Mock + AppOpsManager mAppOpsManager; @Before public void setUp() { @@ -90,6 +93,7 @@ public class AuthServiceTest { when(mInjector.getFingerprintService()).thenReturn(mFingerprintService); when(mInjector.getFaceService()).thenReturn(mFaceService); when(mInjector.getIrisService()).thenReturn(mIrisService); + when(mInjector.getAppOps(any())).thenReturn(mAppOpsManager); } @Test @@ -137,7 +141,9 @@ public class AuthServiceTest { // TODO(b/141025588): Check that an exception is thrown when the userId != callingUserId @Test - public void testAuthenticate_callsBiometricServiceAuthenticate() throws Exception { + public void testAuthenticate_appOpsOk_callsBiometricServiceAuthenticate() throws Exception { + when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_USE_BIOMETRIC), anyInt(), any(), any(), + any())).thenReturn(AppOpsManager.MODE_ALLOWED); mAuthService = new AuthService(mContext, mInjector); mAuthService.onStart(); @@ -166,6 +172,38 @@ public class AuthServiceTest { eq(UserHandle.getCallingUserId())); } + @Test + public void testAuthenticate_appOpsDenied_doesNotCallBiometricService() throws Exception { + when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_USE_BIOMETRIC), anyInt(), any(), any(), + any())).thenReturn(AppOpsManager.MODE_ERRORED); + mAuthService = new AuthService(mContext, mInjector); + mAuthService.onStart(); + + final Binder token = new Binder(); + final Bundle bundle = new Bundle(); + final long sessionId = 0; + final int userId = 0; + + mAuthService.mImpl.authenticate( + token, + sessionId, + userId, + mReceiver, + TEST_OP_PACKAGE_NAME, + bundle); + waitForIdle(); + verify(mBiometricService, never()).authenticate( + eq(token), + eq(sessionId), + eq(userId), + eq(mReceiver), + eq(TEST_OP_PACKAGE_NAME), + eq(bundle), + eq(Binder.getCallingUid()), + eq(Binder.getCallingPid()), + eq(UserHandle.getCallingUserId())); + } + @Test public void testCanAuthenticate_callsBiometricServiceCanAuthenticate() throws Exception { mAuthService = new AuthService(mContext, mInjector); -- GitLab From d24084e95a9ff52a8c4a384dcce9bbf0d301bf6a Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Wed, 15 Jul 2020 19:17:38 -0700 Subject: [PATCH 044/536] Update authentication when encrypted or lockout Fingerprint authentication should not expose accept/reject/lockout when the user is encrypted or locked out. This is possible with IBiometricsFingerprint@2.1 since lockout is controlled by the framework. IBiometricsFace@1.0 does not support this since lockout is controlled in the HAL (or lower). Bug: 79776455 Test: On fingerprint device, during encrypted or lockdown, any finger works, lockout never occurs Test: BiometricPromptDemo, normal path is run (e.g. incorrect fingers are rejected) Test: Test no effect on face device Test: atest KeyguardUpdateMonitorTest Change-Id: I9ded8efd80d4f8b92ce054262e721853703c6437 Merged-In: I6c9717d1f8ed3e844b3d92727396e2ce2e7fd94f --- .../fingerprint/FingerprintManager.java | 81 ++++++++++++++++ .../fingerprint/IFingerprintService.aidl | 8 ++ .../IFingerprintServiceReceiver.aidl | 1 + .../keyguard/KeyguardUpdateMonitor.java | 26 +++++- .../keyguard/KeyguardUpdateMonitorTest.java | 39 ++++++++ .../biometrics/BiometricServiceBase.java | 5 +- .../com/android/server/biometrics/Utils.java | 35 +++++++ .../server/biometrics/face/FaceService.java | 5 +- .../fingerprint/FingerprintService.java | 92 +++++++++++++++++-- 9 files changed, 275 insertions(+), 17 deletions(-) diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index d57a7e4b97f0..6900105c4d4c 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -19,6 +19,7 @@ package android.hardware.fingerprint; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.MANAGE_FINGERPRINT; import static android.Manifest.permission.USE_BIOMETRIC; +import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; import static android.Manifest.permission.USE_FINGERPRINT; import android.annotation.NonNull; @@ -75,11 +76,13 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing private static final int MSG_ERROR = 104; private static final int MSG_REMOVED = 105; private static final int MSG_ENUMERATED = 106; + private static final int MSG_FINGERPRINT_DETECTED = 107; private IFingerprintService mService; private Context mContext; private IBinder mToken = new Binder(); private AuthenticationCallback mAuthenticationCallback; + private FingerprintDetectionCallback mFingerprintDetectionCallback; private EnrollmentCallback mEnrollmentCallback; private RemovalCallback mRemovalCallback; private EnumerateCallback mEnumerateCallback; @@ -107,6 +110,13 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing } } + private class OnFingerprintDetectionCancelListener implements OnCancelListener { + @Override + public void onCancel() { + cancelFingerprintDetect(); + } + } + /** * A wrapper class for the crypto objects supported by FingerprintManager. Currently the * framework supports {@link Signature}, {@link Cipher} and {@link Mac} objects. @@ -271,6 +281,18 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing public void onAuthenticationAcquired(int acquireInfo) {} }; + /** + * Callback structure provided for {@link #detectFingerprint(CancellationSignal, + * FingerprintDetectionCallback, int)}. + * @hide + */ + public interface FingerprintDetectionCallback { + /** + * Invoked when a fingerprint has been detected. + */ + void onFingerprintDetected(int userId, boolean isStrongBiometric); + } + /** * Callback structure provided to {@link FingerprintManager#enroll(byte[], CancellationSignal, * int, int, EnrollmentCallback)} must provide an implementation of this for listening to @@ -453,6 +475,35 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing } } + /** + * Uses the fingerprint hardware to detect for the presence of a finger, without giving details + * about accept/reject/lockout. + * @hide + */ + @RequiresPermission(USE_BIOMETRIC_INTERNAL) + public void detectFingerprint(@NonNull CancellationSignal cancel, + @NonNull FingerprintDetectionCallback callback, int userId) { + if (mService == null) { + return; + } + + if (cancel.isCanceled()) { + Slog.w(TAG, "Detection already cancelled"); + return; + } else { + cancel.setOnCancelListener(new OnFingerprintDetectionCancelListener()); + } + + mFingerprintDetectionCallback = callback; + + try { + mService.detectFingerprint(mToken, userId, mServiceReceiver, + mContext.getOpPackageName()); + } catch (RemoteException e) { + Slog.w(TAG, "Remote exception when requesting finger detect", e); + } + } + /** * Request fingerprint enrollment. This call warms up the fingerprint hardware * and starts scanning for fingerprints. Progress will be indicated by callbacks to the @@ -797,6 +848,10 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing sendEnumeratedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */, msg.arg2 /* groupId */); break; + case MSG_FINGERPRINT_DETECTED: + sendFingerprintDetected(msg.arg1 /* userId */, + (boolean) msg.obj /* isStrongBiometric */); + break; } } }; @@ -891,6 +946,14 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing } } + private void sendFingerprintDetected(int userId, boolean isStrongBiometric) { + if (mFingerprintDetectionCallback == null) { + Slog.e(TAG, "sendFingerprintDetected, callback null"); + return; + } + mFingerprintDetectionCallback.onFingerprintDetected(userId, isStrongBiometric); + } + /** * @hide */ @@ -927,6 +990,18 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing } } + private void cancelFingerprintDetect() { + if (mService == null) { + return; + } + + try { + mService.cancelFingerprintDetect(mToken, mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * @hide */ @@ -1032,6 +1107,12 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing fp).sendToTarget(); } + @Override + public void onFingerprintDetected(long deviceId, int userId, boolean isStrongBiometric) { + mHandler.obtainMessage(MSG_FINGERPRINT_DETECTED, userId, 0, isStrongBiometric) + .sendToTarget(); + } + @Override // binder call public void onAuthenticationFailed(long deviceId) { mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget(); diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl index c5c375543adc..8aa36d7d5d76 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl @@ -33,6 +33,11 @@ interface IFingerprintService { void authenticate(IBinder token, long sessionId, int userId, IFingerprintServiceReceiver receiver, int flags, String opPackageName); + // Uses the fingerprint hardware to detect for the presence of a finger, without giving details + // about accept/reject/lockout. + void detectFingerprint(IBinder token, int userId, IFingerprintServiceReceiver receiver, + String opPackageName); + // This method prepares the service to start authenticating, but doesn't start authentication. // This is protected by the MANAGE_BIOMETRIC signatuer permission. This method should only be // called from BiometricService. The additional uid, pid, userId arguments should be determined @@ -48,6 +53,9 @@ interface IFingerprintService { // Cancel authentication for the given sessionId void cancelAuthentication(IBinder token, String opPackageName); + // Cancel finger detection + void cancelFingerprintDetect(IBinder token, String opPackageName); + // Same as above, except this is protected by the MANAGE_BIOMETRIC signature permission. Takes // an additional uid, pid, userid. void cancelAuthenticationFromService(IBinder token, String opPackageName, diff --git a/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl b/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl index 4412cee31bb0..a84b81e1eb81 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl @@ -26,6 +26,7 @@ oneway interface IFingerprintServiceReceiver { void onAcquired(long deviceId, int acquiredInfo, int vendorCode); void onAuthenticationSucceeded(long deviceId, in Fingerprint fp, int userId, boolean isStrongBiometric); + void onFingerprintDetected(long deviceId, int userId, boolean isStrongBiometric); void onAuthenticationFailed(long deviceId); void onError(long deviceId, int error, int vendorCode); void onRemoved(long deviceId, int fingerId, int groupId, int remaining); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 3acbfb87c3f4..c07c982b7451 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -1072,6 +1072,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); } + private boolean isEncryptedOrLockdown(int userId) { + final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(userId); + final boolean isLockDown = + containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) + || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); + final boolean isEncrypted = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT); + return isEncrypted || isLockDown; + } + public boolean userNeedsStrongAuth() { return mStrongAuthTracker.getStrongAuthForUser(getCurrentUser()) != LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED; @@ -1248,6 +1257,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } }; + // Trigger the fingerprint success path so the bouncer can be shown + private final FingerprintManager.FingerprintDetectionCallback mFingerprintDetectionCallback + = this::handleFingerprintAuthenticated; + private FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback = new AuthenticationCallback() { @@ -2050,8 +2063,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mFingerprintCancelSignal.cancel(); } mFingerprintCancelSignal = new CancellationSignal(); - mFpm.authenticate(null, mFingerprintCancelSignal, 0, mFingerprintAuthenticationCallback, - null, userId); + + if (isEncryptedOrLockdown(userId)) { + mFpm.detectFingerprint(mFingerprintCancelSignal, mFingerprintDetectionCallback, + userId); + } else { + mFpm.authenticate(null, mFingerprintCancelSignal, 0, + mFingerprintAuthenticationCallback, null, userId); + } + setFingerprintRunningState(BIOMETRIC_STATE_RUNNING); } } @@ -2087,7 +2107,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private boolean isUnlockWithFingerprintPossible(int userId) { return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId) - && mFpm.getEnrolledFingerprints(userId).size() > 0; + && mFpm.hasEnrolledTemplates(userId); } private boolean isUnlockWithFacePossible(int userId) { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 9e056cf16ec7..6362812d4fed 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -174,6 +174,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { when(mFaceManager.isHardwareDetected()).thenReturn(true); when(mFaceManager.hasEnrolledTemplates()).thenReturn(true); when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true); + when(mFingerprintManager.isHardwareDetected()).thenReturn(true); + when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true); when(mUserManager.isUserUnlocked(anyInt())).thenReturn(true); when(mUserManager.isPrimaryUser()).thenReturn(true); when(mStrongAuthTracker.getStub()).thenReturn(mock(IStrongAuthTracker.Stub.class)); @@ -418,6 +420,43 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { assertThat(mKeyguardUpdateMonitor.mTelephonyCapable).isTrue(); } + @Test + public void testTriesToAuthenticateFingerprint_whenKeyguard() { + mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */); + mTestableLooper.processAllMessages(); + + verify(mFingerprintManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt()); + verify(mFingerprintManager, never()).detectFingerprint(any(), any(), anyInt()); + } + + @Test + public void testFingerprintDoesNotAuth_whenEncrypted() { + testFingerprintWhenStrongAuth( + KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT); + } + + @Test + public void testFingerprintDoesNotAuth_whenDpmLocked() { + testFingerprintWhenStrongAuth( + KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW); + } + + @Test + public void testFingerprintDoesNotAuth_whenUserLockdown() { + testFingerprintWhenStrongAuth( + KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); + } + + private void testFingerprintWhenStrongAuth(int strongAuth) { + when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(strongAuth); + mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */); + mTestableLooper.processAllMessages(); + + verify(mFingerprintManager, never()) + .authenticate(any(), any(), anyInt(), any(), any(), anyInt()); + verify(mFingerprintManager).detectFingerprint(any(), any(), anyInt()); + } + @Test public void testTriesToAuthenticate_whenBouncer() { mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true); diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java index 88469a2caee8..20c004db4c9f 100644 --- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java +++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java @@ -722,10 +722,9 @@ public abstract class BiometricServiceBase extends SystemService } } - protected void handleAuthenticated(BiometricAuthenticator.Identifier identifier, - ArrayList token) { + protected void handleAuthenticated(boolean authenticated, + BiometricAuthenticator.Identifier identifier, ArrayList token) { ClientMonitor client = mCurrentClient; - final boolean authenticated = identifier.getBiometricId() != 0; if (client != null && client.onAuthenticated(identifier, authenticated, token)) { removeClient(client); diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java index 543ce575b1fc..c661f452820d 100644 --- a/services/core/java/com/android/server/biometrics/Utils.java +++ b/services/core/java/com/android/server/biometrics/Utils.java @@ -16,11 +16,19 @@ package com.android.server.biometrics; +import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; import static android.hardware.biometrics.BiometricManager.Authenticators; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; + +import android.annotation.NonNull; import android.app.ActivityManager; +import android.content.ComponentName; import android.content.Context; +import android.content.pm.PackageManager; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricPrompt; @@ -32,6 +40,9 @@ import android.os.UserHandle; import android.provider.Settings; import android.util.Slog; +import com.android.internal.R; +import com.android.internal.widget.LockPatternUtils; + import java.util.List; public class Utils { @@ -285,4 +296,28 @@ public class Utils { } return false; } + + public static boolean isKeyguard(Context context, String clientPackage) { + final boolean hasPermission = context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL) + == PackageManager.PERMISSION_GRANTED; + + final ComponentName keyguardComponent = ComponentName.unflattenFromString( + context.getResources().getString(R.string.config_keyguardComponent)); + final String keyguardPackage = keyguardComponent != null + ? keyguardComponent.getPackageName() : null; + return hasPermission && keyguardPackage != null && keyguardPackage.equals(clientPackage); + } + + private static boolean containsFlag(int haystack, int needle) { + return (haystack & needle) != 0; + } + + public static boolean isUserEncryptedOrLockdown(@NonNull LockPatternUtils lpu, int user) { + final int strongAuth = lpu.getStrongAuthForUser(user); + final boolean isEncrypted = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT); + final boolean isLockDown = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) + || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); + Slog.d(TAG, "isEncrypted: " + isEncrypted + " isLockdown: " + isLockDown); + return isEncrypted || isLockDown; + } } diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java index 72e1bbbcba60..e5a1898459a2 100644 --- a/services/core/java/com/android/server/biometrics/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/face/FaceService.java @@ -896,8 +896,9 @@ public class FaceService extends BiometricServiceBase { public void onAuthenticated(final long deviceId, final int faceId, final int userId, ArrayList token) { mHandler.post(() -> { - Face face = new Face("", faceId, deviceId); - FaceService.super.handleAuthenticated(face, token); + final Face face = new Face("", faceId, deviceId); + final boolean authenticated = faceId != 0; + FaceService.super.handleAuthenticated(authenticated, face, token); }); } diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java index 6b7ba6a56d82..a53fe47e4d3f 100644 --- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java @@ -56,6 +56,7 @@ import android.os.SELinux; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; +import android.util.EventLog; import android.util.Slog; import android.util.SparseBooleanArray; import android.util.SparseIntArray; @@ -64,6 +65,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.logging.MetricsLogger; import com.android.internal.util.DumpUtils; +import com.android.internal.widget.LockPatternUtils; import com.android.server.SystemServerInitThreadPool; import com.android.server.biometrics.AuthenticationClient; import com.android.server.biometrics.BiometricServiceBase; @@ -72,6 +74,7 @@ import com.android.server.biometrics.ClientMonitor; import com.android.server.biometrics.Constants; import com.android.server.biometrics.EnumerateClient; import com.android.server.biometrics.RemovalClient; +import com.android.server.biometrics.Utils; import org.json.JSONArray; import org.json.JSONException; @@ -124,6 +127,8 @@ public class FingerprintService extends BiometricServiceBase { } private final class FingerprintAuthClient extends AuthenticationClientImpl { + private final boolean mDetectOnly; + @Override protected boolean isFingerprint() { return true; @@ -133,9 +138,10 @@ public class FingerprintService extends BiometricServiceBase { DaemonWrapper daemon, long halDeviceId, IBinder token, ServiceListener listener, int targetUserId, int groupId, long opId, boolean restricted, String owner, int cookie, - boolean requireConfirmation) { + boolean requireConfirmation, boolean detectOnly) { super(context, daemon, halDeviceId, token, listener, targetUserId, groupId, opId, restricted, owner, cookie, requireConfirmation); + mDetectOnly = detectOnly; } @Override @@ -177,6 +183,10 @@ public class FingerprintService extends BiometricServiceBase { return super.handleFailedAttempt(); } + + boolean isDetectOnly() { + return mDetectOnly; + } } /** @@ -234,18 +244,55 @@ public class FingerprintService extends BiometricServiceBase { } @Override // Binder call - public void authenticate(final IBinder token, final long opId, final int groupId, + public void authenticate(final IBinder token, final long opId, final int userId, final IFingerprintServiceReceiver receiver, final int flags, final String opPackageName) { - updateActiveGroup(groupId, opPackageName); + if (Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId) + && Utils.isKeyguard(getContext(), opPackageName)) { + // If this happens, something in KeyguardUpdateMonitor is wrong. + // SafetyNet for b/79776455 + EventLog.writeEvent(0x534e4554, "79776455"); + Slog.e(TAG, "Authenticate invoked when user is encrypted or lockdown"); + return; + } + + updateActiveGroup(userId, opPackageName); final boolean restricted = isRestricted(); final AuthenticationClientImpl client = new FingerprintAuthClient(getContext(), mDaemonWrapper, mHalDeviceId, token, new ServiceListenerImpl(receiver), - mCurrentUserId, groupId, opId, restricted, opPackageName, - 0 /* cookie */, false /* requireConfirmation */); + mCurrentUserId, userId, opId, restricted, opPackageName, + 0 /* cookie */, false /* requireConfirmation */, false /* detectOnly */); authenticateInternal(client, opId, opPackageName); } + @Override + public void detectFingerprint(final IBinder token, final int userId, + final IFingerprintServiceReceiver receiver, final String opPackageName) { + checkPermission(USE_BIOMETRIC_INTERNAL); + if (!Utils.isKeyguard(getContext(), opPackageName)) { + Slog.w(TAG, "detectFingerprint called from non-sysui package: " + opPackageName); + return; + } + + if (!Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) { + // If this happens, something in KeyguardUpdateMonitor is wrong. This should only + // ever be invoked when the user is encrypted or lockdown. + Slog.e(TAG, "detectFingerprint invoked when user is not encrypted or lockdown"); + return; + } + + Slog.d(TAG, "detectFingerprint, owner: " + opPackageName + ", user: " + userId); + + updateActiveGroup(userId, opPackageName); + final boolean restricted = isRestricted(); + final int operationId = 0; + final AuthenticationClientImpl client = new FingerprintAuthClient(getContext(), + mDaemonWrapper, mHalDeviceId, token, new ServiceListenerImpl(receiver), + mCurrentUserId, userId, operationId, restricted, opPackageName, + 0 /* cookie */, false /* requireConfirmation */, true /* detectOnly */); + authenticateInternal(client, operationId, opPackageName); + } + @Override // Binder call public void prepareForAuthentication(IBinder token, long opId, int groupId, IBiometricServiceReceiverInternal wrapperReceiver, String opPackageName, @@ -257,7 +304,7 @@ public class FingerprintService extends BiometricServiceBase { mDaemonWrapper, mHalDeviceId, token, new BiometricPromptServiceListenerImpl(wrapperReceiver), mCurrentUserId, groupId, opId, restricted, opPackageName, cookie, - false /* requireConfirmation */); + false /* requireConfirmation */, false /* detectOnly */); authenticateInternal(client, opId, opPackageName, callingUid, callingPid, callingUserId); } @@ -274,6 +321,17 @@ public class FingerprintService extends BiometricServiceBase { cancelAuthenticationInternal(token, opPackageName); } + @Override // Binder call + public void cancelFingerprintDetect(final IBinder token, final String opPackageName) { + checkPermission(USE_BIOMETRIC_INTERNAL); + if (!Utils.isKeyguard(getContext(), opPackageName)) { + Slog.w(TAG, "cancelFingerprintDetect called from non-sysui package: " + + opPackageName); + return; + } + cancelAuthenticationInternal(token, opPackageName); + } + @Override // Binder call public void cancelAuthenticationFromService(final IBinder token, final String opPackageName, int callingUid, int callingPid, int callingUserId, boolean fromClient) { @@ -518,7 +576,12 @@ public class FingerprintService extends BiometricServiceBase { BiometricAuthenticator.Identifier biometric, int userId) throws RemoteException { if (mFingerprintServiceReceiver != null) { - if (biometric == null || biometric instanceof Fingerprint) { + final ClientMonitor client = getCurrentClient(); + if (client instanceof FingerprintAuthClient + && ((FingerprintAuthClient) client).isDetectOnly()) { + mFingerprintServiceReceiver + .onFingerprintDetected(deviceId, userId, isStrongBiometric()); + } else if (biometric == null || biometric instanceof Fingerprint) { mFingerprintServiceReceiver.onAuthenticationSucceeded(deviceId, (Fingerprint) biometric, userId, isStrongBiometric()); } else { @@ -575,6 +638,7 @@ public class FingerprintService extends BiometricServiceBase { private final LockoutReceiver mLockoutReceiver = new LockoutReceiver(); protected final ResetFailedAttemptsForUserRunnable mResetFailedAttemptsForCurrentUserRunnable = new ResetFailedAttemptsForUserRunnable(); + private final LockPatternUtils mLockPatternUtils; /** * Receives callbacks from the HAL. @@ -608,8 +672,17 @@ public class FingerprintService extends BiometricServiceBase { public void onAuthenticated(final long deviceId, final int fingerId, final int groupId, ArrayList token) { mHandler.post(() -> { - Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId); - FingerprintService.super.handleAuthenticated(fp, token); + boolean authenticated = fingerId != 0; + final ClientMonitor client = getCurrentClient(); + if (client instanceof FingerprintAuthClient) { + if (((FingerprintAuthClient) client).isDetectOnly()) { + Slog.w(TAG, "Detect-only. Device is encrypted or locked down"); + authenticated = true; + } + } + + final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId); + FingerprintService.super.handleAuthenticated(authenticated, fp, token); }); } @@ -722,6 +795,7 @@ public class FingerprintService extends BiometricServiceBase { mAlarmManager = context.getSystemService(AlarmManager.class); context.registerReceiver(mLockoutReceiver, new IntentFilter(getLockoutResetIntent()), getLockoutBroadcastPermission(), null /* handler */); + mLockPatternUtils = new LockPatternUtils(context); } @Override -- GitLab From f784aed8e2c5938220519a82868fde3175f125b4 Mon Sep 17 00:00:00 2001 From: Steve Elliott Date: Wed, 15 Jul 2020 14:57:24 -0400 Subject: [PATCH 045/536] Clicking convo header launches notif settings Fixes: 161251986 Test: manual Change-Id: I45cdda2322b725fdf6186d1e6ea26aae69b3fab6 --- .../notification/stack/NotificationSectionsManager.kt | 5 ++++- .../systemui/statusbar/notification/stack/PeopleHubView.kt | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt index c87b9986ca55..91cc8963b947 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt @@ -41,8 +41,8 @@ import com.android.systemui.statusbar.notification.row.StackScrollerDecorView import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.children -import com.android.systemui.util.takeUntil import com.android.systemui.util.foldToSparseArray +import com.android.systemui.util.takeUntil import javax.inject.Inject /** @@ -166,6 +166,9 @@ class NotificationSectionsManager @Inject internal constructor( peopleHubSubscription?.unsubscribe() peopleHubSubscription = null peopleHeaderView = reinflateView(peopleHeaderView, layoutInflater, R.layout.people_strip) + .apply { + setOnHeaderClickListener(View.OnClickListener { onGentleHeaderClick() }) + } if (ENABLE_SNOOZED_CONVERSATION_HUB) { peopleHubSubscription = peopleHubViewAdapter.bindView(peopleHubViewBoundary) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/PeopleHubView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/PeopleHubView.kt index 8f77a1d776e4..b13e7fb839ff 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/PeopleHubView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/PeopleHubView.kt @@ -93,6 +93,8 @@ class PeopleHubView(context: Context, attrs: AttributeSet) : } } + fun setOnHeaderClickListener(listener: OnClickListener) = label.setOnClickListener(listener) + private inner class PersonDataListenerImpl(val avatarView: ImageView) : DataListener { -- GitLab From c109dd0ac74d328c2fa8b255f40a8a5b992c2e85 Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Thu, 16 Jul 2020 13:56:15 -0400 Subject: [PATCH 046/536] Remove toast in power save mode Redundant since animations are now shown even in battery saver. Bug: 161458152 Fix: 161458152 Test: verified that both animations and the toast show up at head; removed toast code; verified that animation still appears in both regular and extreme battery saver mode. Change-Id: I55ba9a72dfe2f3f9741aca9dd719283dce114bce --- .../android/systemui/screenshot/GlobalScreenshot.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 85444303490d..4a4aa79aadfa 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -57,7 +57,6 @@ import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.PowerManager; import android.os.RemoteException; import android.provider.Settings; import android.util.DisplayMetrics; @@ -648,14 +647,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset */ private void startAnimation(final Consumer finisher, Rect screenRect, Insets screenInsets, boolean showFlash) { - - // If power save is on, show a toast so there is some visual indication that a - // screenshot has been taken. - PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); - if (powerManager.isPowerSaveMode()) { - Toast.makeText(mContext, R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show(); - } - mScreenshotHandler.post(() -> { if (!mScreenshotLayout.isAttachedToWindow()) { mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams); -- GitLab From 068ddf7b06a81244bb1e52db72e387c70bf724ef Mon Sep 17 00:00:00 2001 From: Zhen Zhang Date: Wed, 15 Jul 2020 11:16:54 -0700 Subject: [PATCH 047/536] Scroll the hiding page to top on tab changed in sharesheet After the tab changed, ResolverDrawerLayout will lose reference of the hidden page which can cause the page not able to scoll back to top. Automatically scroll on tab changed to avoid that situation. Bug: 160886554 Test: manually test; atest ChooserActivityTest; atest ResolverActivityTest Change-Id: I1a8ba72f6b1dcb9bca19262b97983788001d715b --- .../android/internal/app/ChooserActivity.java | 1 + .../internal/widget/ResolverDrawerLayout.java | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index fbf050ad08f6..3a89dcd96487 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -3134,6 +3134,7 @@ public class ChooserActivity extends ResolverActivity implements // ends up disabled. That's because at some point the old tab's vertical scrolling is // disabled and the new tab's is enabled. For context, see b/159997845 setVerticalScrollEnabled(true); + mResolverDrawerLayout.scrollNestedScrollableChildBackToTop(); } @Override diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index 3f708f84750c..90eeabb47e9a 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -464,11 +464,7 @@ public class ResolverDrawerLayout extends ViewGroup { smoothScrollTo(mCollapsibleHeight + mUncollapsibleHeight, yvel); mDismissOnScrollerFinished = true; } else { - if (isNestedListChildScrolled()) { - mNestedListChild.smoothScrollToPosition(0); - } else if (isNestedRecyclerChildScrolled()) { - mNestedRecyclerChild.smoothScrollToPosition(0); - } + scrollNestedScrollableChildBackToTop(); smoothScrollTo(yvel < 0 ? 0 : mCollapsibleHeight, yvel); } } @@ -493,6 +489,17 @@ public class ResolverDrawerLayout extends ViewGroup { return handled; } + /** + * Scroll nested scrollable child back to top if it has been scrolled. + */ + public void scrollNestedScrollableChildBackToTop() { + if (isNestedListChildScrolled()) { + mNestedListChild.smoothScrollToPosition(0); + } else if (isNestedRecyclerChildScrolled()) { + mNestedRecyclerChild.smoothScrollToPosition(0); + } + } + private void onSecondaryPointerUp(MotionEvent ev) { final int pointerIndex = ev.getActionIndex(); final int pointerId = ev.getPointerId(pointerIndex); -- GitLab From c2e8162410cd05d9a70e2e62b8a2517cbc3c2fc4 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Tue, 12 May 2020 01:06:39 -0700 Subject: [PATCH 048/536] Keep alternate reference to mStatusBar and mNavigationBar for flexible insets Needed in order to ensure the immersive confirmation dialog and behavior work correctly and for the swipe directions to updated based on system bar position Bug: 156304383 Test: manual (change immersive behavior), atest WindowInsetsControllerTests Change-Id: Id4258d06e9d02a55b46afd53eefb7ec19a50a2ed --- .../view/WindowManagerPolicyConstants.java | 7 + .../server/policy/WindowManagerPolicy.java | 4 + .../com/android/server/wm/DisplayPolicy.java | 190 +++++++++++++++--- .../server/wm/WindowManagerService.java | 4 + .../server/wm/DisplayPolicyLayoutTests.java | 49 +++++ .../server/wm/ScreenDecorWindowTests.java | 8 +- 6 files changed, 234 insertions(+), 28 deletions(-) diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java index 492ab6f8a3d5..8c355202b63f 100644 --- a/core/java/android/view/WindowManagerPolicyConstants.java +++ b/core/java/android/view/WindowManagerPolicyConstants.java @@ -49,6 +49,13 @@ public interface WindowManagerPolicyConstants { int PRESENCE_INTERNAL = 1 << 0; int PRESENCE_EXTERNAL = 1 << 1; + // Alternate bars position values + int ALT_BAR_UNKNOWN = -1; + int ALT_BAR_LEFT = 1 << 0; + int ALT_BAR_RIGHT = 1 << 1; + int ALT_BAR_BOTTOM = 1 << 2; + int ALT_BAR_TOP = 1 << 3; + // Navigation bar position values int NAV_BAR_INVALID = -1; int NAV_BAR_LEFT = 1 << 0; diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index 8868a6c2e6d8..a1d42d3d5682 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -141,6 +141,10 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { @IntDef({NAV_BAR_LEFT, NAV_BAR_RIGHT, NAV_BAR_BOTTOM}) @interface NavigationBarPosition {} + @Retention(SOURCE) + @IntDef({ALT_BAR_UNKNOWN, ALT_BAR_LEFT, ALT_BAR_RIGHT, ALT_BAR_BOTTOM, ALT_BAR_TOP}) + @interface AltBarPosition {} + /** * Pass this event to the user / app. To be returned from * {@link #interceptKeyBeforeQueueing}. diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 5ae6f80b262d..3b5c2422f742 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -102,6 +102,11 @@ import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManagerGlobal.ADD_OKAY; import static android.view.WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_BOTTOM; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_LEFT; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_RIGHT; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_TOP; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_UNKNOWN; import static android.view.WindowManagerPolicyConstants.EXTRA_HDMI_PLUGGED_STATE; import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM; import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT; @@ -314,6 +319,17 @@ public class DisplayPolicy { private int[] mNavigationBarHeightForRotationInCarMode = new int[4]; private int[] mNavigationBarWidthForRotationInCarMode = new int[4]; + // Alternative status bar for when flexible insets mapping is used to place the status bar on + // another side of the screen. + private WindowState mStatusBarAlt = null; + @WindowManagerPolicy.AltBarPosition + private int mStatusBarAltPosition = ALT_BAR_UNKNOWN; + // Alternative navigation bar for when flexible insets mapping is used to place the navigation + // bar elsewhere on the screen. + private WindowState mNavigationBarAlt = null; + @WindowManagerPolicy.AltBarPosition + private int mNavigationBarAltPosition = ALT_BAR_UNKNOWN; + /** See {@link #getNavigationBarFrameHeight} */ private int[] mNavigationBarFrameHeightForRotationDefault = new int[4]; @@ -431,7 +447,7 @@ public class DisplayPolicy { case MSG_REQUEST_TRANSIENT_BARS: synchronized (mLock) { WindowState targetBar = (msg.arg1 == MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS) - ? mStatusBar : mNavigationBar; + ? getStatusBar() : getNavigationBar(); if (targetBar != null) { requestTransientBars(targetBar); } @@ -494,6 +510,7 @@ public class DisplayPolicy { if (mStatusBar != null) { requestTransientBars(mStatusBar); } + checkAltBarSwipeForTransientBars(ALT_BAR_TOP); } } @@ -504,6 +521,7 @@ public class DisplayPolicy { && mNavigationBarPosition == NAV_BAR_BOTTOM) { requestTransientBars(mNavigationBar); } + checkAltBarSwipeForTransientBars(ALT_BAR_BOTTOM); } } @@ -520,6 +538,7 @@ public class DisplayPolicy { excludedRegion)) { requestTransientBars(mNavigationBar); } + checkAltBarSwipeForTransientBars(ALT_BAR_RIGHT); } excludedRegion.recycle(); } @@ -537,6 +556,7 @@ public class DisplayPolicy { excludedRegion)) { requestTransientBars(mNavigationBar); } + checkAltBarSwipeForTransientBars(ALT_BAR_LEFT); } excludedRegion.recycle(); } @@ -638,6 +658,15 @@ public class DisplayPolicy { mHandler.post(mGestureNavigationSettingsObserver::register); } + private void checkAltBarSwipeForTransientBars(@WindowManagerPolicy.AltBarPosition int pos) { + if (mStatusBarAlt != null && mStatusBarAltPosition == pos) { + requestTransientBars(mStatusBarAlt); + } + if (mNavigationBarAlt != null && mNavigationBarAltPosition == pos) { + requestTransientBars(mNavigationBarAlt); + } + } + void systemReady() { mSystemGestures.systemReady(); if (mService.mPointerLocationEnabled) { @@ -899,6 +928,14 @@ public class DisplayPolicy { } break; } + + // Check if alternate bars positions were updated. + if (mStatusBarAlt == win) { + mStatusBarAltPosition = getAltBarPosition(attrs); + } + if (mNavigationBarAlt == win) { + mNavigationBarAltPosition = getAltBarPosition(attrs); + } } /** @@ -938,10 +975,9 @@ public class DisplayPolicy { mContext.enforcePermission( android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid, "DisplayPolicy"); - if (mStatusBar != null) { - if (mStatusBar.isAlive()) { - return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; - } + if ((mStatusBar != null && mStatusBar.isAlive()) + || (mStatusBarAlt != null && mStatusBarAlt.isAlive())) { + return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; } break; case TYPE_NOTIFICATION_SHADE: @@ -958,10 +994,9 @@ public class DisplayPolicy { mContext.enforcePermission( android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid, "DisplayPolicy"); - if (mNavigationBar != null) { - if (mNavigationBar.isAlive()) { - return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; - } + if ((mNavigationBar != null && mNavigationBar.isAlive()) + || (mNavigationBarAlt != null && mNavigationBarAlt.isAlive())) { + return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; } break; case TYPE_NAVIGATION_BAR_PANEL: @@ -993,6 +1028,23 @@ public class DisplayPolicy { android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid, "DisplayPolicy"); enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providesInsetsTypes); + + for (@InternalInsetsType int insetType : attrs.providesInsetsTypes) { + switch (insetType) { + case ITYPE_STATUS_BAR: + if ((mStatusBar != null && mStatusBar.isAlive()) + || (mStatusBarAlt != null && mStatusBarAlt.isAlive())) { + return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; + } + break; + case ITYPE_NAVIGATION_BAR: + if ((mNavigationBar != null && mNavigationBar.isAlive()) + || (mNavigationBarAlt != null && mNavigationBarAlt.isAlive())) { + return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; + } + break; + } + } } return ADD_OKAY; } @@ -1084,7 +1136,19 @@ public class DisplayPolicy { break; default: if (attrs.providesInsetsTypes != null) { - for (int insetsType : attrs.providesInsetsTypes) { + for (@InternalInsetsType int insetsType : attrs.providesInsetsTypes) { + switch (insetsType) { + case ITYPE_STATUS_BAR: + mStatusBarAlt = win; + mStatusBarController.setWindow(mStatusBarAlt); + mStatusBarAltPosition = getAltBarPosition(attrs); + break; + case ITYPE_NAVIGATION_BAR: + mNavigationBarAlt = win; + mNavigationBarController.setWindow(mNavigationBarAlt); + mNavigationBarAltPosition = getAltBarPosition(attrs); + break; + } mDisplayContent.setInsetProvider(insetsType, win, null); } } @@ -1092,6 +1156,22 @@ public class DisplayPolicy { } } + @WindowManagerPolicy.AltBarPosition + private int getAltBarPosition(WindowManager.LayoutParams params) { + switch (params.gravity) { + case Gravity.LEFT: + return ALT_BAR_LEFT; + case Gravity.RIGHT: + return ALT_BAR_RIGHT; + case Gravity.BOTTOM: + return ALT_BAR_BOTTOM; + case Gravity.TOP: + return ALT_BAR_TOP; + default: + return ALT_BAR_UNKNOWN; + } + } + TriConsumer getImeSourceFrameProvider() { return (displayFrames, windowState, inOutFrame) -> { if (mNavigationBar != null && navigationBarPosition(displayFrames.mDisplayWidth, @@ -1132,12 +1212,14 @@ public class DisplayPolicy { * @param win The window being removed. */ void removeWindowLw(WindowState win) { - if (mStatusBar == win) { + if (mStatusBar == win || mStatusBarAlt == win) { mStatusBar = null; + mStatusBarAlt = null; mStatusBarController.setWindow(null); mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, null, null); - } else if (mNavigationBar == win) { + } else if (mNavigationBar == win || mNavigationBarAlt == win) { mNavigationBar = null; + mNavigationBarAlt = null; mNavigationBarController.setWindow(null); mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, null, null); } else if (mNotificationShade == win) { @@ -1163,7 +1245,7 @@ public class DisplayPolicy { } WindowState getStatusBar() { - return mStatusBar; + return mStatusBar != null ? mStatusBar : mStatusBarAlt; } WindowState getNotificationShade() { @@ -1171,7 +1253,7 @@ public class DisplayPolicy { } WindowState getNavigationBar() { - return mNavigationBar; + return mNavigationBar != null ? mNavigationBar : mNavigationBarAlt; } /** @@ -1233,6 +1315,46 @@ public class DisplayPolicy { return R.anim.dock_left_enter; } } + } else if (win == mStatusBarAlt || win == mNavigationBarAlt) { + if (win.getAttrs().windowAnimations != 0) { + return ANIMATION_STYLEABLE; + } + + int pos = (win == mStatusBarAlt) ? mStatusBarAltPosition : mNavigationBarAltPosition; + + boolean isExitOrHide = transit == TRANSIT_EXIT || transit == TRANSIT_HIDE; + boolean isEnterOrShow = transit == TRANSIT_ENTER || transit == TRANSIT_SHOW; + + switch (pos) { + case ALT_BAR_LEFT: + if (isExitOrHide) { + return R.anim.dock_left_exit; + } else if (isEnterOrShow) { + return R.anim.dock_left_enter; + } + break; + case ALT_BAR_RIGHT: + if (isExitOrHide) { + return R.anim.dock_right_exit; + } else if (isEnterOrShow) { + return R.anim.dock_right_enter; + } + break; + case ALT_BAR_BOTTOM: + if (isExitOrHide) { + return R.anim.dock_bottom_exit; + } else if (isEnterOrShow) { + return R.anim.dock_bottom_enter; + } + break; + case ALT_BAR_TOP: + if (isExitOrHide) { + return R.anim.dock_top_exit; + } else if (isEnterOrShow) { + return R.anim.dock_top_enter; + } + break; + } } if (transit == TRANSIT_PREVIEW_DONE) { @@ -1591,7 +1713,7 @@ public class DisplayPolicy { mInputConsumer = null; Slog.v(TAG, INPUT_CONSUMER_NAVIGATION + " dismissed."); } - } else if (mInputConsumer == null && mStatusBar != null && canHideNavigationBar()) { + } else if (mInputConsumer == null && getStatusBar() != null && canHideNavigationBar()) { mInputConsumer = mDisplayContent.getInputMonitor().createInputConsumer( mHandler.getLooper(), INPUT_CONSUMER_NAVIGATION, @@ -2677,10 +2799,10 @@ public class DisplayPolicy { mDreamingLockscreen = mService.mPolicy.isKeyguardShowingAndNotOccluded(); } - if (mStatusBar != null) { + if (getStatusBar() != null) { if (DEBUG_LAYOUT) Slog.i(TAG, "force=" + mForceStatusBar + " top=" + mTopFullscreenOpaqueWindowState); - final boolean forceShowStatusBar = (mStatusBar.getAttrs().privateFlags + final boolean forceShowStatusBar = (getStatusBar().getAttrs().privateFlags & PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR) != 0; final boolean notificationShadeForcesShowingNavigation = mNotificationShade != null @@ -3166,6 +3288,16 @@ public class DisplayPolicy { return mNavigationBarPosition; } + @WindowManagerPolicy.AltBarPosition + int getAlternateStatusBarPosition() { + return mStatusBarAltPosition; + } + + @WindowManagerPolicy.AltBarPosition + int getAlternateNavBarPosition() { + return mNavigationBarAltPosition; + } + /** * A new window has been focused. */ @@ -3327,8 +3459,8 @@ public class DisplayPolicy { final boolean isFullscreen = (visibility & (View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)) != 0 || (PolicyControl.getWindowFlags(win, win.mAttrs) & FLAG_FULLSCREEN) != 0 - || (mStatusBar != null && insetsPolicy.isHidden(ITYPE_STATUS_BAR)) - || (mNavigationBar != null && insetsPolicy.isHidden( + || (getStatusBar() != null && insetsPolicy.isHidden(ITYPE_STATUS_BAR)) + || (getNavigationBar() != null && insetsPolicy.isHidden( ITYPE_NAVIGATION_BAR)); final int behavior = win.mAttrs.insetsFlags.behavior; final boolean isImmersive = (visibility & (View.SYSTEM_UI_FLAG_IMMERSIVE @@ -3583,7 +3715,7 @@ public class DisplayPolicy { final boolean hideNavBarSysui = (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0; - final boolean transientStatusBarAllowed = mStatusBar != null + final boolean transientStatusBarAllowed = getStatusBar() != null && (notificationShadeHasFocus || (!mForceShowSystemBars && (hideStatusBarWM || (hideStatusBarSysui && immersiveSticky)))); @@ -3741,7 +3873,7 @@ public class DisplayPolicy { // TODO(b/118118435): Remove this after migration private boolean isImmersiveMode(int vis) { final int flags = View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; - return mNavigationBar != null + return getNavigationBar() != null && (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0 && (vis & flags) != 0 && canHideNavigationBar(); @@ -3749,7 +3881,7 @@ public class DisplayPolicy { private boolean isImmersiveMode(WindowState win) { final int behavior = win.mAttrs.insetsFlags.behavior; - return mNavigationBar != null + return getNavigationBar() != null && canHideNavigationBar() && (behavior == BEHAVIOR_SHOW_BARS_BY_SWIPE || behavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) @@ -3830,8 +3962,8 @@ public class DisplayPolicy { public void takeScreenshot(int screenshotType, int source) { if (mScreenshotHelper != null) { mScreenshotHelper.takeScreenshot(screenshotType, - mStatusBar != null && mStatusBar.isVisibleLw(), - mNavigationBar != null && mNavigationBar.isVisibleLw(), + getStatusBar() != null && getStatusBar().isVisibleLw(), + getNavigationBar() != null && getNavigationBar().isVisibleLw(), source, mHandler, null /* completionConsumer */); } } @@ -3869,6 +4001,11 @@ public class DisplayPolicy { if (mStatusBar != null) { pw.print(prefix); pw.print("mStatusBar="); pw.print(mStatusBar); } + if (mStatusBarAlt != null) { + pw.print(prefix); pw.print("mStatusBarAlt="); pw.print(mStatusBarAlt); + pw.print(prefix); pw.print("mStatusBarAltPosition="); + pw.println(mStatusBarAltPosition); + } if (mNotificationShade != null) { pw.print(prefix); pw.print("mExpandedPanel="); pw.print(mNotificationShade); } @@ -3880,6 +4017,11 @@ public class DisplayPolicy { pw.print(prefix); pw.print("mNavigationBarPosition="); pw.println(mNavigationBarPosition); } + if (mNavigationBarAlt != null) { + pw.print(prefix); pw.print("mNavigationBarAlt="); pw.println(mNavigationBarAlt); + pw.print(prefix); pw.print("mNavigationBarAltPosition="); + pw.println(mNavigationBarAltPosition); + } if (mFocusedWindow != null) { pw.print(prefix); pw.print("mFocusedWindow="); pw.println(mFocusedWindow); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 3cfb5f7d5441..b71fefc92f8d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2163,6 +2163,10 @@ public class WindowManagerService extends IWindowManager.Stub throw new IllegalArgumentException( "Window type can not be changed after the window is added."); } + if (!Arrays.equals(win.mAttrs.providesInsetsTypes, attrs.providesInsetsTypes)) { + throw new IllegalArgumentException( + "Insets types can not be changed after the window is added."); + } // Odd choice but less odd than embedding in copyFrom() if ((attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY) diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java index 278de56dfea0..2f3afbcb6d72 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -40,8 +40,13 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DEC import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; +import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_BOTTOM; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_LEFT; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_RIGHT; +import static android.view.WindowManagerPolicyConstants.ALT_BAR_TOP; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; @@ -60,6 +65,7 @@ import android.util.Pair; import android.util.SparseArray; import android.view.DisplayCutout; import android.view.DisplayInfo; +import android.view.Gravity; import android.view.InsetsState; import android.view.WindowInsets.Side; import android.view.WindowInsets.Type; @@ -147,6 +153,8 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { @Test public void addingWindow_withInsetsTypes() { + mDisplayPolicy.removeWindowLw(mStatusBarWindow); // Removes the existing one. + WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel"); win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES}; win.getFrameLw().set(0, 0, 500, 100); @@ -195,6 +203,47 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { expectThrows(IllegalArgumentException.class, () -> addWindow(win)); } + @Test + public void addingWindow_variousGravities_alternateBarPosUpdated() { + mDisplayPolicy.removeWindowLw(mNavBarWindow); // Removes the existing one. + + WindowState win1 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel1"); + win1.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR}; + win1.mAttrs.gravity = Gravity.TOP; + win1.getFrameLw().set(0, 0, 200, 500); + addWindow(win1); + + assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_TOP); + mDisplayPolicy.removeWindowLw(win1); + + WindowState win2 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel2"); + win2.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR}; + win2.mAttrs.gravity = Gravity.BOTTOM; + win2.getFrameLw().set(0, 0, 200, 500); + addWindow(win2); + + assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_BOTTOM); + mDisplayPolicy.removeWindowLw(win2); + + WindowState win3 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel3"); + win3.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR}; + win3.mAttrs.gravity = Gravity.LEFT; + win3.getFrameLw().set(0, 0, 200, 500); + addWindow(win3); + + assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_LEFT); + mDisplayPolicy.removeWindowLw(win3); + + WindowState win4 = createWindow(null, TYPE_NAVIGATION_BAR_PANEL, "NavBarPanel4"); + win4.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR}; + win4.mAttrs.gravity = Gravity.RIGHT; + win4.getFrameLw().set(0, 0, 200, 500); + addWindow(win4); + + assertEquals(mDisplayPolicy.getAlternateNavBarPosition(), ALT_BAR_RIGHT); + mDisplayPolicy.removeWindowLw(win4); + } + @Test public void layoutWindowLw_fitStatusBars() { mWindow.mAttrs.setFitInsetsTypes(Type.statusBars()); diff --git a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java index 31a102ae3bad..ef74861e9422 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java @@ -25,8 +25,8 @@ import static android.view.Gravity.BOTTOM; import static android.view.Gravity.LEFT; import static android.view.Gravity.RIGHT; import static android.view.Gravity.TOP; -import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; -import static android.view.InsetsState.ITYPE_STATUS_BAR; +import static android.view.InsetsState.ITYPE_CLIMATE_BAR; +import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; @@ -190,7 +190,7 @@ public class ScreenDecorWindowTests { @Test public void testProvidesInsetsTypes() { - int[] providesInsetsTypes = new int[]{ITYPE_STATUS_BAR}; + int[] providesInsetsTypes = new int[]{ITYPE_CLIMATE_BAR}; final View win = createWindow("StatusBarSubPanel", TOP, MATCH_PARENT, mDecorThickness, RED, FLAG_LAYOUT_IN_SCREEN, 0, providesInsetsTypes); @@ -199,7 +199,7 @@ public class ScreenDecorWindowTests { private View createDecorWindow(int gravity, int width, int height) { int[] providesInsetsTypes = - new int[]{gravity == TOP ? ITYPE_STATUS_BAR : ITYPE_NAVIGATION_BAR}; + new int[]{gravity == TOP ? ITYPE_CLIMATE_BAR : ITYPE_EXTRA_NAVIGATION_BAR}; return createWindow("decorWindow", gravity, width, height, RED, FLAG_LAYOUT_IN_SCREEN, PRIVATE_FLAG_IS_SCREEN_DECOR, providesInsetsTypes); } -- GitLab From 98349de32ad8b3f3e516c8e3cc0e6e6d8904cc42 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Thu, 25 Jun 2020 11:06:24 -0700 Subject: [PATCH 049/536] Reintroduce flexible inset mapping This was cut from R due to timing. Reintroducing for R QPR1. Allows for the usage of flexible inset mapping Bug: 156304383 Test: atest WindowInsetsControllerTest Change-Id: I51992277409da40f28bdf36b62203d4a07af933b --- .../car/navigationbar/CarNavigationBar.java | 9 ++++++-- .../navigationbar/CarNavigationBarView.java | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java index 37dfce4e16ce..35b2080dddf9 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java @@ -16,10 +16,12 @@ package com.android.systemui.car.navigationbar; +import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES; import static android.view.InsetsState.ITYPE_CLIMATE_BAR; import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; +import static android.view.InsetsState.ITYPE_TOP_GESTURES; import static android.view.InsetsState.containsType; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; @@ -368,13 +370,15 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, height, - WindowManager.LayoutParams.TYPE_STATUS_BAR, + WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, PixelFormat.TRANSLUCENT); lp.setTitle("TopCarNavigationBar"); + lp.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES}; + lp.setFitInsetsTypes(0); lp.windowAnimations = 0; lp.gravity = Gravity.TOP; mWindowManager.addView(mTopNavigationBarWindow, lp); @@ -388,13 +392,14 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, height, - WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, PixelFormat.TRANSLUCENT); lp.setTitle("BottomCarNavigationBar"); + lp.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR, ITYPE_BOTTOM_GESTURES}; lp.windowAnimations = 0; lp.gravity = Gravity.BOTTOM; mWindowManager.addView(mBottomNavigationBarWindow, lp); diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java index 029d4c7fa2fb..0ced4021ce38 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java @@ -16,7 +16,10 @@ package com.android.systemui.car.navigationbar; +import static android.view.WindowInsets.Type.systemBars; + import android.content.Context; +import android.graphics.Insets; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -79,9 +82,28 @@ public class CarNavigationBarView extends LinearLayout { @Override public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) { + applyMargins(windowInsets.getInsets(systemBars())); return windowInsets; } + private void applyMargins(Insets insets) { + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + View child = getChildAt(i); + if (child.getLayoutParams() instanceof LayoutParams) { + LayoutParams lp = (LayoutParams) child.getLayoutParams(); + if (lp.rightMargin != insets.right || lp.leftMargin != insets.left + || lp.topMargin != insets.top || lp.bottomMargin != insets.bottom) { + lp.rightMargin = insets.right; + lp.leftMargin = insets.left; + lp.topMargin = insets.top; + lp.bottomMargin = insets.bottom; + child.requestLayout(); + } + } + } + } + // Used to forward touch events even if the touch was initiated from a child component @Override public boolean onInterceptTouchEvent(MotionEvent ev) { -- GitLab From 39ba8c9cc3137a31793a229dd7f21a63f1b3a946 Mon Sep 17 00:00:00 2001 From: Agatha Man Date: Mon, 13 Jul 2020 15:17:53 -0700 Subject: [PATCH 050/536] Add CAR_DRIVING_STATE and CAR_CONTROL_AUDIO_VOLUME permissions to run ATS tests AtsCarHostTestCases and AtsCarDeviceApp requires CAR_DRIVING_STATE. AtsDeviceInfo and AtsAudioDeviceTestCases requires CAR_CONTROL_AUDIO_VOLUME. Bug: 161193447 Test: m -j && run ats tests Change-Id: Ib16c6c5e54b489479c872cfa826b055262b797bb --- data/etc/privapp-permissions-platform.xml | 4 ++++ packages/Shell/AndroidManifest.xml | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index e6f4e27100de..5cdcaba6ce48 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -427,6 +427,10 @@ applications that come with the platform + + + + diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 570c2ab3efd1..3100e2fce085 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -317,6 +317,11 @@ + + + + + Date: Wed, 15 Jul 2020 18:26:11 -0700 Subject: [PATCH 051/536] Add permission QUERY_ALL_PACKAGES into WAPPushManager Test: Sanity Bug: 161319976 Change-Id: I931c5a7c5e9c5ee3fd72fa2c0a29df48073fd90c Merged-In: I931c5a7c5e9c5ee3fd72fa2c0a29df48073fd90c (cherry picked from commit 11bbbee915c5d02d4ef85c03695db8de8e486b9a) --- packages/WAPPushManager/AndroidManifest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/WAPPushManager/AndroidManifest.xml b/packages/WAPPushManager/AndroidManifest.xml index 14e6e91e3a25..a75fb2d47bbd 100644 --- a/packages/WAPPushManager/AndroidManifest.xml +++ b/packages/WAPPushManager/AndroidManifest.xml @@ -23,6 +23,8 @@ + + -- GitLab From d541f6d85e9030c5e0e7372332854684d8a32916 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Mon, 8 Jun 2020 14:59:23 -0700 Subject: [PATCH 052/536] Remove unused intent in NiNotification Bug: 154319182 Test: manual Change-Id: I5958a8fb442cf4506e1824243493f91aea34a7cc Merged-In: I5958a8fb442cf4506e1824243493f91aea34a7cc --- .../android/internal/location/GpsNetInitiatedHandler.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index 4e2f28b24305..81e68d3307e7 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -21,7 +21,6 @@ import java.util.concurrent.TimeUnit; import android.app.Notification; import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -399,13 +398,9 @@ public class GpsNetInitiatedHandler { mNiNotificationBuilder.setDefaults(0); } - // if not to popup dialog immediately, pending intent will open the dialog - Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent(); - PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0); mNiNotificationBuilder.setTicker(getNotifTicker(notif, mContext)) .setContentTitle(title) - .setContentText(message) - .setContentIntent(pi); + .setContentText(message); notificationManager.notifyAsUser(null, notif.notificationId, mNiNotificationBuilder.build(), UserHandle.ALL); -- GitLab From ef5279d9f589d6d626863551cfd0a35cc2633ae7 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Mon, 8 Jun 2020 14:59:23 -0700 Subject: [PATCH 053/536] Remove unused intent in NiNotification Bug: 154319182 Test: manual Change-Id: I5958a8fb442cf4506e1824243493f91aea34a7cc Merged-In: I5958a8fb442cf4506e1824243493f91aea34a7cc --- .../android/internal/location/GpsNetInitiatedHandler.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index 2c8d9ee5d32c..108139e33689 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -21,7 +21,6 @@ import java.util.concurrent.TimeUnit; import android.app.Notification; import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -402,13 +401,9 @@ public class GpsNetInitiatedHandler { mNiNotificationBuilder.setDefaults(0); } - // if not to popup dialog immediately, pending intent will open the dialog - Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent(); - PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0); mNiNotificationBuilder.setTicker(getNotifTicker(notif, mContext)) .setContentTitle(title) - .setContentText(message) - .setContentIntent(pi); + .setContentText(message); notificationManager.notifyAsUser(null, notif.notificationId, mNiNotificationBuilder.build(), UserHandle.ALL); -- GitLab From 8b7811ce591b323549ce12e431a9f3c67a5372d9 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Mon, 8 Jun 2020 14:59:23 -0700 Subject: [PATCH 054/536] Remove unused intent in NiNotification Bug: 154319182 Test: manual Change-Id: I5958a8fb442cf4506e1824243493f91aea34a7cc Merged-In: I5958a8fb442cf4506e1824243493f91aea34a7cc --- .../android/internal/location/GpsNetInitiatedHandler.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index 2c8d9ee5d32c..108139e33689 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -21,7 +21,6 @@ import java.util.concurrent.TimeUnit; import android.app.Notification; import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -402,13 +401,9 @@ public class GpsNetInitiatedHandler { mNiNotificationBuilder.setDefaults(0); } - // if not to popup dialog immediately, pending intent will open the dialog - Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent(); - PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0); mNiNotificationBuilder.setTicker(getNotifTicker(notif, mContext)) .setContentTitle(title) - .setContentText(message) - .setContentIntent(pi); + .setContentText(message); notificationManager.notifyAsUser(null, notif.notificationId, mNiNotificationBuilder.build(), UserHandle.ALL); -- GitLab From 3a5cd5bbe3418f79970f5c37f45583a0323b0d41 Mon Sep 17 00:00:00 2001 From: John Reck Date: Mon, 6 Jul 2020 16:10:49 -0700 Subject: [PATCH 055/536] Add missing isShellUser check Bug: 160390416 Test: verified command still works from shell Change-Id: I23bb06e00f1623e4f27c02d7eb2c0d273b40771b (cherry picked from commit 03542611973e4ce3ddca522ee12bcc85e59ce901) Merged-In: I23bb06e00f1623e4f27c02d7eb2c0d273b40771b --- .../com/android/server/am/ActivityManagerService.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c917530ea42c..49827ae6199a 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -4260,9 +4260,18 @@ public class ActivityManagerService extends IActivityManager.Stub return procState; } + private boolean isCallerShell() { + final int callingUid = Binder.getCallingUid(); + return callingUid == SHELL_UID || callingUid == ROOT_UID; + } + @Override public boolean setProcessMemoryTrimLevel(String process, int userId, int level) throws RemoteException { + if (!isCallerShell()) { + EventLog.writeEvent(0x534e4554, 160390416, Binder.getCallingUid(), ""); + throw new SecurityException("Only shell can call it"); + } synchronized (this) { final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel"); if (app == null) { -- GitLab From 9c33b3fe919d9aa295e83f2ed78bad2b229314c1 Mon Sep 17 00:00:00 2001 From: John Reck Date: Mon, 6 Jul 2020 16:10:49 -0700 Subject: [PATCH 056/536] Add missing isShellUser check Bug: 160390416 Test: verified command still works from shell Change-Id: I23bb06e00f1623e4f27c02d7eb2c0d273b40771b Merged-In: I23bb06e00f1623e4f27c02d7eb2c0d273b40771b --- .../java/com/android/server/am/ActivityManagerService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index ebf5068ca942..b3d52f46b332 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -4830,6 +4830,10 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public boolean setProcessMemoryTrimLevel(String process, int userId, int level) throws RemoteException { + if (!isCallerShell()) { + EventLog.writeEvent(0x534e4554, 160390416, Binder.getCallingUid(), ""); + throw new SecurityException("Only shell can call it"); + } synchronized (this) { final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel"); if (app == null) { -- GitLab From 5e2931c6569aa8084be9d0690a1ca30534f49c46 Mon Sep 17 00:00:00 2001 From: John Reck Date: Mon, 6 Jul 2020 16:10:49 -0700 Subject: [PATCH 057/536] Add missing isShellUser check Bug: 160390416 Test: verified command still works from shell Change-Id: I23bb06e00f1623e4f27c02d7eb2c0d273b40771b (cherry picked from commit 03542611973e4ce3ddca522ee12bcc85e59ce901) Merged-In: I23bb06e00f1623e4f27c02d7eb2c0d273b40771b --- .../com/android/server/am/ActivityManagerService.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index e0ac45adb3f4..d77c55059e50 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -4251,9 +4251,18 @@ public class ActivityManagerService extends IActivityManager.Stub return procState; } + private boolean isCallerShell() { + final int callingUid = Binder.getCallingUid(); + return callingUid == SHELL_UID || callingUid == ROOT_UID; + } + @Override public boolean setProcessMemoryTrimLevel(String process, int userId, int level) throws RemoteException { + if (!isCallerShell()) { + EventLog.writeEvent(0x534e4554, 160390416, Binder.getCallingUid(), ""); + throw new SecurityException("Only shell can call it"); + } synchronized (this) { final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel"); if (app == null) { -- GitLab From bdf78962f40dfb6152c632c04ce69995c9f560b2 Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Mon, 20 Jul 2020 10:56:03 -0400 Subject: [PATCH 058/536] Reset the screenshot preview intent on clear Currently, we only reset the intent sent upon tapping the screenshot preview when we get a new intent. This means that if you tap on the preview after the animation is complete, but before the screenshot has saved, you'll be sent to the edit app with the old (previous) screenshot. This change sets the intent to null when the screenshot is cleared, so that tapping on it will do nothing until we can send the user to the right place. Bug: 161434853 Fix: 161434853 Bug: 161532249 Fix: 161532249 Test: manual Change-Id: Id8542985cba73bab6d0c9cb35760d43403cee1d9 --- .../src/com/android/systemui/screenshot/GlobalScreenshot.java | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 85444303490d..ef6b041afd9e 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -1033,6 +1033,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset mScreenshotPreview.setLayerType(View.LAYER_TYPE_NONE, null); mScreenshotPreview.setContentDescription( mContext.getResources().getString(R.string.screenshot_preview_description)); + mScreenshotPreview.setOnClickListener(null); mScreenshotLayout.setAlpha(1); mDismissButton.setTranslationY(0); mActionsContainer.setTranslationY(0); -- GitLab From c4bbfd14a128cb3572e5db3872659c04b8202639 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Mon, 20 Jul 2020 11:25:46 -0700 Subject: [PATCH 059/536] Clear identity when checking strongauth flags Fixes: 161557889 Fixes: 161566755 Test: atest FingerprintManagerTest Test: AccessibilityFingerprintGestureTest#testGestureDetectionListener_whenAuthenticationStartsAndStops_calledBack Merged-In: Icb273fc0cf2ce1891550130539c0b2e6e788b533 Change-Id: I9ebed8adc401fc745f581c8e0fe38c3790dd5fb6 --- .../fingerprint/FingerprintService.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java index a53fe47e4d3f..a90fee6788a8 100644 --- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java @@ -247,13 +247,22 @@ public class FingerprintService extends BiometricServiceBase { public void authenticate(final IBinder token, final long opId, final int userId, final IFingerprintServiceReceiver receiver, final int flags, final String opPackageName) { - if (Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId) - && Utils.isKeyguard(getContext(), opPackageName)) { - // If this happens, something in KeyguardUpdateMonitor is wrong. - // SafetyNet for b/79776455 - EventLog.writeEvent(0x534e4554, "79776455"); - Slog.e(TAG, "Authenticate invoked when user is encrypted or lockdown"); - return; + // Keyguard check must be done on the caller's binder identity, since it also checks + // permission. + final boolean isKeyguard = Utils.isKeyguard(getContext(), opPackageName); + + // Clear calling identity when checking LockPatternUtils for StrongAuth flags. + final long identity = Binder.clearCallingIdentity(); + try { + if (isKeyguard && Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) { + // If this happens, something in KeyguardUpdateMonitor is wrong. + // SafetyNet for b/79776455 + EventLog.writeEvent(0x534e4554, "79776455"); + Slog.e(TAG, "Authenticate invoked when user is encrypted or lockdown"); + return; + } + } finally { + Binder.restoreCallingIdentity(identity); } updateActiveGroup(userId, opPackageName); -- GitLab From d074a544353287572ee6877cb336b25f6463ee4e Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Mon, 6 Jul 2020 10:26:03 -0400 Subject: [PATCH 060/536] Add back privacy chip This adds back the privacy chip classes (Controller and view). Change to using Executors and DeviceConfigProxy, also fix tests that were flaky before. Test: SystemUITests Bug: 160966908 Change-Id: Id3e5981a87c33a8cabe7ce348f9512d81ad2b1d8 Merged-In: Id3e5981a87c33a8cabe7ce348f9512d81ad2b1d8 --- .../sysui/SystemUiDeviceConfigFlags.java | 7 + packages/CarSystemUI/res/values/dimens.xml | 15 + .../SystemUI/res/drawable/privacy_chip_bg.xml | 23 ++ .../res/layout/ongoing_privacy_chip.xml | 40 +++ .../quick_status_bar_header_system_icons.xml | 29 +- packages/SystemUI/res/values/config.xml | 2 + packages/SystemUI/res/values/dimens.xml | 17 + packages/SystemUI/res/values/strings.xml | 21 ++ .../src/com/android/systemui/Dependency.java | 3 + .../systemui/appops/AppOpsControllerImpl.java | 2 - .../systemui/privacy/OngoingPrivacyChip.kt | 110 +++++++ .../systemui/privacy/PrivacyChipBuilder.kt | 51 +++ .../systemui/privacy/PrivacyChipEvent.kt | 30 ++ .../android/systemui/privacy/PrivacyItem.kt | 38 +++ .../systemui/privacy/PrivacyItemController.kt | 299 ++++++++++++++++++ .../systemui/qs/QuickStatusBarHeader.java | 126 +++++++- .../statusbar/phone/PhoneStatusBarPolicy.java | 66 +++- .../privacy/PrivacyChipBuilderTest.kt | 77 +++++ .../privacy/PrivacyItemControllerTest.kt | 290 +++++++++++++++++ 19 files changed, 1235 insertions(+), 11 deletions(-) create mode 100644 packages/SystemUI/res/drawable/privacy_chip_bg.xml create mode 100644 packages/SystemUI/res/layout/ongoing_privacy_chip.xml create mode 100644 packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt create mode 100644 packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt create mode 100644 packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipEvent.kt create mode 100644 packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt create mode 100644 packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyChipBuilderTest.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java index d238d0eb916d..ea3d2de13ce6 100644 --- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java @@ -120,6 +120,13 @@ public final class SystemUiDeviceConfigFlags { */ public static final String HASH_SALT_MAX_DAYS = "hash_salt_max_days"; + // Flag related to Privacy Indicators + + /** + * Whether the Permissions Hub is showing. + */ + public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_2_enabled"; + // Flags related to Assistant /** diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml index cb321cdc6c4d..8359dac6a30f 100644 --- a/packages/CarSystemUI/res/values/dimens.xml +++ b/packages/CarSystemUI/res/values/dimens.xml @@ -81,6 +81,21 @@ 96dp 128dp + + 48dp + + 15dp + + 24dp + + 12dp + + 6dp + + 4dp + + 12dp + @dimen/car_primary_icon_size @*android:dimen/car_single_line_list_item_height diff --git a/packages/SystemUI/res/drawable/privacy_chip_bg.xml b/packages/SystemUI/res/drawable/privacy_chip_bg.xml new file mode 100644 index 000000000000..827cf4a9d3b6 --- /dev/null +++ b/packages/SystemUI/res/drawable/privacy_chip_bg.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml new file mode 100644 index 000000000000..3c306322d21f --- /dev/null +++ b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml @@ -0,0 +1,40 @@ + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml index be86e5f5abc5..3c7480181877 100644 --- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml +++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml @@ -14,7 +14,7 @@ ** See the License for the specific language governing permissions and ** limitations under the License. --> - + + + + + + + + + - + + diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 72f623e5fcab..5e5df6bfd988 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -510,6 +510,8 @@ com.android.systemui + 5 + com.android.launcher3 diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index eb8758c0d921..5984d8d3322e 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1175,6 +1175,23 @@ 0px + + + 32dp + + 8dp + + 8dp + + 0dp + + 2dp + + @dimen/status_bar_icon_drawing_size + + 16dp + + 1dp diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index db45a60ab7c0..16688b41f2c6 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2608,6 +2608,27 @@ app for debugging. Will not be seen by users. [CHAR LIMIT=20] --> Dump SysUI Heap + + %1$s is using your %2$s. + + + Applications are using your %s. + + + ,\u0020 + + + \u0020and\u0020 + + + camera + + + location + + + microphone + Sensors off diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 02d2b8e4ef0f..59580bbf1ae2 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -54,6 +54,7 @@ import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.power.PowerUI; +import com.android.systemui.privacy.PrivacyItemController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; import com.android.systemui.screenrecord.RecordingController; @@ -294,6 +295,7 @@ public class Dependency { @Inject Lazy mSensorPrivacyManager; @Inject Lazy mAutoHideController; @Inject Lazy mForegroundServiceNotificationListener; + @Inject Lazy mPrivacyItemController; @Inject @Background Lazy mBgLooper; @Inject @Background Lazy mBgHandler; @Inject @Main Lazy mMainLooper; @@ -491,6 +493,7 @@ public class Dependency { mProviders.put(ForegroundServiceNotificationListener.class, mForegroundServiceNotificationListener::get); mProviders.put(ClockManager.class, mClockManager::get); + mProviders.put(PrivacyItemController.class, mPrivacyItemController::get); mProviders.put(ActivityManagerWrapper.class, mActivityManagerWrapper::get); mProviders.put(DevicePolicyManagerWrapper.class, mDevicePolicyManagerWrapper::get); mProviders.put(PackageManagerWrapper.class, mPackageManagerWrapper::get); diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index 941de2dc63ec..fc7cc7ee55d3 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -57,7 +57,6 @@ public class AppOpsControllerImpl implements AppOpsController, private static final long NOTED_OP_TIME_DELAY_MS = 5000; private static final String TAG = "AppOpsControllerImpl"; private static final boolean DEBUG = false; - private final Context mContext; private final AppOpsManager mAppOps; private H mBGHandler; @@ -83,7 +82,6 @@ public class AppOpsControllerImpl implements AppOpsController, Context context, @Background Looper bgLooper, DumpManager dumpManager) { - mContext = context; mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); mBGHandler = new H(bgLooper); final int numOps = OPS.length; diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt new file mode 100644 index 000000000000..48769cda8481 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2020 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.privacy + +import android.content.Context +import android.util.AttributeSet +import android.view.Gravity +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.LinearLayout +import com.android.systemui.R + +class OngoingPrivacyChip @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttrs: Int = 0, + defStyleRes: Int = 0 +) : FrameLayout(context, attrs, defStyleAttrs, defStyleRes) { + + private val iconMarginExpanded = context.resources.getDimensionPixelSize( + R.dimen.ongoing_appops_chip_icon_margin_expanded) + private val iconMarginCollapsed = context.resources.getDimensionPixelSize( + R.dimen.ongoing_appops_chip_icon_margin_collapsed) + private val iconSize = + context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_size) + private val iconColor = context.resources.getColor( + R.color.status_bar_clock_color, context.theme) + private val sidePadding = + context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding) + private val backgroundDrawable = context.getDrawable(R.drawable.privacy_chip_bg) + private lateinit var iconsContainer: LinearLayout + private lateinit var back: FrameLayout + var expanded = false + set(value) { + if (value != field) { + field = value + updateView() + } + } + + var builder = PrivacyChipBuilder(context, emptyList()) + var privacyList = emptyList() + set(value) { + field = value + builder = PrivacyChipBuilder(context, value) + updateView() + } + + override fun onFinishInflate() { + super.onFinishInflate() + + back = requireViewById(R.id.background) + iconsContainer = requireViewById(R.id.icons_container) + } + + // Should only be called if the builder icons or app changed + private fun updateView() { + back.background = if (expanded) backgroundDrawable else null + val padding = if (expanded) sidePadding else 0 + back.setPaddingRelative(padding, 0, padding, 0) + fun setIcons(chipBuilder: PrivacyChipBuilder, iconsContainer: ViewGroup) { + iconsContainer.removeAllViews() + chipBuilder.generateIcons().forEachIndexed { i, it -> + it.mutate() + it.setTint(iconColor) + val image = ImageView(context).apply { + setImageDrawable(it) + scaleType = ImageView.ScaleType.CENTER_INSIDE + } + iconsContainer.addView(image, iconSize, iconSize) + if (i != 0) { + val lp = image.layoutParams as MarginLayoutParams + lp.marginStart = if (expanded) iconMarginExpanded else iconMarginCollapsed + image.layoutParams = lp + } + } + } + + if (!privacyList.isEmpty()) { + generateContentDescription() + setIcons(builder, iconsContainer) + val lp = iconsContainer.layoutParams as FrameLayout.LayoutParams + lp.gravity = Gravity.CENTER_VERTICAL or + (if (expanded) Gravity.CENTER_HORIZONTAL else Gravity.END) + iconsContainer.layoutParams = lp + } else { + iconsContainer.removeAllViews() + } + requestLayout() + } + + private fun generateContentDescription() { + val typesText = builder.joinTypes() + contentDescription = context.getString( + R.string.ongoing_privacy_chip_content_multiple_apps, typesText) + } +} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt new file mode 100644 index 000000000000..1d2e74703b42 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 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.privacy + +import android.content.Context +import com.android.systemui.R + +class PrivacyChipBuilder(private val context: Context, itemsList: List) { + + val appsAndTypes: List>> + val types: List + private val separator = context.getString(R.string.ongoing_privacy_dialog_separator) + private val lastSeparator = context.getString(R.string.ongoing_privacy_dialog_last_separator) + + init { + appsAndTypes = itemsList.groupBy({ it.application }, { it.privacyType }) + .toList() + .sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps + { it.second.min() })) // Sort by "smallest" AppOpp (Location is largest) + types = itemsList.map { it.privacyType }.distinct().sorted() + } + + fun generateIcons() = types.map { it.getIcon(context) } + + private fun List.joinWithAnd(): StringBuilder { + return subList(0, size - 1).joinTo(StringBuilder(), separator = separator).apply { + append(lastSeparator) + append(this@joinWithAnd.last()) + } + } + + fun joinTypes(): String { + return when (types.size) { + 0 -> "" + 1 -> types[0].getName(context) + else -> types.map { it.getName(context) }.joinWithAnd().toString() + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipEvent.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipEvent.kt new file mode 100644 index 000000000000..1f24fde1377e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipEvent.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 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.privacy + +import com.android.internal.logging.UiEvent +import com.android.internal.logging.UiEventLogger + +enum class PrivacyChipEvent(private val _id: Int) : UiEventLogger.UiEventEnum { + @UiEvent(doc = "Privacy chip is viewed by the user. Logged at most once per time QS is visible") + ONGOING_INDICATORS_CHIP_VIEW(601), + + @UiEvent(doc = "Privacy chip is clicked") + ONGOING_INDICATORS_CHIP_CLICK(602); + + override fun getId() = _id +} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt new file mode 100644 index 000000000000..3da1363f2a56 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 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.privacy + +import android.content.Context +import com.android.systemui.R + +typealias Privacy = PrivacyType + +enum class PrivacyType(val nameId: Int, val iconId: Int) { + // This is uses the icons used by the corresponding permission groups in the AndroidManifest + TYPE_CAMERA(R.string.privacy_type_camera, + com.android.internal.R.drawable.perm_group_camera), + TYPE_MICROPHONE(R.string.privacy_type_microphone, + com.android.internal.R.drawable.perm_group_microphone), + TYPE_LOCATION(R.string.privacy_type_location, + com.android.internal.R.drawable.perm_group_location); + + fun getName(context: Context) = context.resources.getString(nameId) + + fun getIcon(context: Context) = context.resources.getDrawable(iconId, context.theme) +} + +data class PrivacyItem(val privacyType: PrivacyType, val application: PrivacyApplication) + +data class PrivacyApplication(val packageName: String, val uid: Int) diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt new file mode 100644 index 000000000000..8001ecc9697d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2020 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.privacy + +import android.app.ActivityManager +import android.app.AppOpsManager +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.os.UserHandle +import android.os.UserManager +import android.provider.DeviceConfig +import com.android.internal.annotations.VisibleForTesting +import com.android.internal.config.sysui.SystemUiDeviceConfigFlags +import com.android.systemui.Dumpable +import com.android.systemui.appops.AppOpItem +import com.android.systemui.appops.AppOpsController +import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.dump.DumpManager +import com.android.systemui.util.DeviceConfigProxy +import com.android.systemui.util.concurrency.DelayableExecutor +import java.io.FileDescriptor +import java.io.PrintWriter +import java.lang.ref.WeakReference +import java.util.concurrent.Executor +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class PrivacyItemController @Inject constructor( + context: Context, + private val appOpsController: AppOpsController, + @Main uiExecutor: DelayableExecutor, + @Background private val bgExecutor: Executor, + private val broadcastDispatcher: BroadcastDispatcher, + private val deviceConfigProxy: DeviceConfigProxy, + dumpManager: DumpManager +) : Dumpable { + + @VisibleForTesting + internal companion object { + val OPS = intArrayOf(AppOpsManager.OP_CAMERA, + AppOpsManager.OP_RECORD_AUDIO, + AppOpsManager.OP_COARSE_LOCATION, + AppOpsManager.OP_FINE_LOCATION) + val intentFilter = IntentFilter().apply { + addAction(Intent.ACTION_USER_SWITCHED) + addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) + addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) + } + const val TAG = "PrivacyItemController" + } + + @VisibleForTesting + internal var privacyList = emptyList() + @Synchronized get() = field.toList() // Returns a shallow copy of the list + @Synchronized set + + fun isPermissionsHubEnabled(): Boolean { + return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, + SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false) + } + + private val userManager = context.getSystemService(UserManager::class.java) + private var currentUserIds = emptyList() + private var listening = false + private val callbacks = mutableListOf>() + private val internalUiExecutor = MyExecutor(WeakReference(this), uiExecutor) + + private val notifyChanges = Runnable { + val list = privacyList + callbacks.forEach { it.get()?.privacyChanged(list) } + } + + private val updateListAndNotifyChanges = Runnable { + updatePrivacyList() + uiExecutor.execute(notifyChanges) + } + + private var indicatorsAvailable = isPermissionsHubEnabled() + @VisibleForTesting + internal val devicePropertiesChangedListener = + object : DeviceConfig.OnPropertiesChangedListener { + override fun onPropertiesChanged(properties: DeviceConfig.Properties) { + if (DeviceConfig.NAMESPACE_PRIVACY.equals(properties.getNamespace()) && + properties.getKeyset().contains( + SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED)) { + indicatorsAvailable = properties.getBoolean( + SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false) + internalUiExecutor.updateListeningState() + } + } + } + + private val cb = object : AppOpsController.Callback { + override fun onActiveStateChanged( + code: Int, + uid: Int, + packageName: String, + active: Boolean + ) { + val userId = UserHandle.getUserId(uid) + if (userId in currentUserIds) { + update(false) + } + } + } + + @VisibleForTesting + internal var userSwitcherReceiver = Receiver() + set(value) { + unregisterReceiver() + field = value + if (listening) registerReceiver() + } + + init { + deviceConfigProxy.addOnPropertiesChangedListener( + DeviceConfig.NAMESPACE_PRIVACY, + uiExecutor, + devicePropertiesChangedListener) + dumpManager.registerDumpable(TAG, this) + } + + private fun unregisterReceiver() { + broadcastDispatcher.unregisterReceiver(userSwitcherReceiver) + } + + private fun registerReceiver() { + broadcastDispatcher.registerReceiver(userSwitcherReceiver, intentFilter, + null /* handler */, UserHandle.ALL) + } + + private fun update(updateUsers: Boolean) { + bgExecutor.execute { + if (updateUsers) { + val currentUser = ActivityManager.getCurrentUser() + currentUserIds = userManager.getProfiles(currentUser).map { it.id } + } + updateListAndNotifyChanges.run() + } + } + + /** + * Updates listening status based on whether there are callbacks and the indicators are enabled + * + * This is only called from private (add/remove)Callback and from the config listener, all in + * main thread. + */ + private fun setListeningState() { + val listen = !callbacks.isEmpty() and indicatorsAvailable + if (listening == listen) return + listening = listen + if (listening) { + appOpsController.addCallback(OPS, cb) + registerReceiver() + update(true) + } else { + appOpsController.removeCallback(OPS, cb) + unregisterReceiver() + // Make sure that we remove all indicators and notify listeners if we are not + // listening anymore due to indicators being disabled + update(false) + } + } + + private fun addCallback(callback: WeakReference) { + callbacks.add(callback) + if (callbacks.isNotEmpty() && !listening) { + internalUiExecutor.updateListeningState() + } + // Notify this callback if we didn't set to listening + else if (listening) { + internalUiExecutor.execute(NotifyChangesToCallback(callback.get(), privacyList)) + } + } + + private fun removeCallback(callback: WeakReference) { + // Removes also if the callback is null + callbacks.removeIf { it.get()?.equals(callback.get()) ?: true } + if (callbacks.isEmpty()) { + internalUiExecutor.updateListeningState() + } + } + + fun addCallback(callback: Callback) { + internalUiExecutor.addCallback(callback) + } + + fun removeCallback(callback: Callback) { + internalUiExecutor.removeCallback(callback) + } + + private fun updatePrivacyList() { + if (!listening) { + privacyList = emptyList() + return + } + val list = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) } + .mapNotNull { toPrivacyItem(it) }.distinct() + privacyList = list + } + + private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? { + val type: PrivacyType = when (appOpItem.code) { + AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_CAMERA + AppOpsManager.OP_COARSE_LOCATION -> PrivacyType.TYPE_LOCATION + AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION + AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE + else -> return null + } + val app = PrivacyApplication(appOpItem.packageName, appOpItem.uid) + return PrivacyItem(type, app) + } + + // Used by containing class to get notified of changes + interface Callback { + fun privacyChanged(privacyItems: List) + } + + internal inner class Receiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intentFilter.hasAction(intent.action)) { + update(true) + } + } + } + + private class NotifyChangesToCallback( + private val callback: Callback?, + private val list: List + ) : Runnable { + override fun run() { + callback?.privacyChanged(list) + } + } + + override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array) { + pw.println("PrivacyItemController state:") + pw.println(" Listening: $listening") + pw.println(" Current user ids: $currentUserIds") + pw.println(" Privacy Items:") + privacyList.forEach { + pw.print(" ") + pw.println(it.toString()) + } + pw.println(" Callbacks:") + callbacks.forEach { + it.get()?.let { + pw.print(" ") + pw.println(it.toString()) + } + } + } + + private class MyExecutor( + private val outerClass: WeakReference, + private val delegate: DelayableExecutor + ) : Executor { + + private var listeningCanceller: Runnable? = null + + override fun execute(command: Runnable) { + delegate.execute(command) + } + + fun updateListeningState() { + listeningCanceller?.run() + listeningCanceller = delegate.executeDelayed({ + outerClass.get()?.setListeningState() + }, 0L) + } + + fun addCallback(callback: Callback) { + outerClass.get()?.addCallback(WeakReference(callback)) + } + + fun removeCallback(callback: Callback) { + outerClass.get()?.removeCallback(WeakReference(callback)) + } + } +} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index b07b1a9561ff..a559a5467663 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -31,7 +31,9 @@ import android.graphics.Color; import android.graphics.Rect; import android.media.AudioManager; import android.os.Handler; +import android.os.Looper; import android.provider.AlarmClock; +import android.provider.DeviceConfig; import android.provider.Settings; import android.service.notification.ZenModeConfig; import android.text.format.DateUtils; @@ -46,7 +48,9 @@ import android.view.ViewGroup; import android.view.WindowInsets; import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.RelativeLayout; +import android.widget.Space; import android.widget.TextView; import androidx.annotation.NonNull; @@ -55,6 +59,8 @@ import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleRegistry; +import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; +import com.android.internal.logging.UiEventLogger; import com.android.settingslib.Utils; import com.android.systemui.BatteryMeterView; import com.android.systemui.DualToneHandler; @@ -63,6 +69,11 @@ import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; +import com.android.systemui.privacy.OngoingPrivacyChip; +import com.android.systemui.privacy.PrivacyChipBuilder; +import com.android.systemui.privacy.PrivacyChipEvent; +import com.android.systemui.privacy.PrivacyItem; +import com.android.systemui.privacy.PrivacyItemController; import com.android.systemui.qs.QSDetail.Callback; import com.android.systemui.qs.carrier.QSCarrierGroup; import com.android.systemui.statusbar.CommandQueue; @@ -101,7 +112,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements private static final int TOOLTIP_NOT_YET_SHOWN_COUNT = 0; public static final int MAX_TOOLTIP_SHOWN_COUNT = 2; - private final Handler mHandler = new Handler(); private final NextAlarmController mAlarmController; private final ZenModeController mZenController; private final StatusBarIconController mStatusBarIconController; @@ -140,9 +150,14 @@ public class QuickStatusBarHeader extends RelativeLayout implements private View mRingerContainer; private Clock mClockView; private DateView mDateView; + private OngoingPrivacyChip mPrivacyChip; + private Space mSpace; private BatteryMeterView mBatteryRemainingIcon; private RingerModeTracker mRingerModeTracker; + private boolean mPermissionsHubEnabled; + private PrivacyItemController mPrivacyItemController; + private final UiEventLogger mUiEventLogger; // Used for RingerModeTracker private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this); @@ -156,22 +171,49 @@ public class QuickStatusBarHeader extends RelativeLayout implements private int mCutOutPaddingRight; private float mExpandedHeaderAlpha = 1.0f; private float mKeyguardExpansionFraction; + private boolean mPrivacyChipLogged = false; + + private final DeviceConfig.OnPropertiesChangedListener mPropertiesListener = + new DeviceConfig.OnPropertiesChangedListener() { + @Override + public void onPropertiesChanged(DeviceConfig.Properties properties) { + if (DeviceConfig.NAMESPACE_PRIVACY.equals(properties.getNamespace()) + && properties.getKeyset() + .contains(SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED)) { + mPermissionsHubEnabled = properties.getBoolean( + SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false); + StatusIconContainer iconContainer = findViewById(R.id.statusIcons); + iconContainer.setIgnoredSlots(getIgnoredIconSlots()); + } + } + }; + + private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() { + @Override + public void privacyChanged(List privacyItems) { + mPrivacyChip.setPrivacyList(privacyItems); + setChipVisibility(!privacyItems.isEmpty()); + } + }; @Inject public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, NextAlarmController nextAlarmController, ZenModeController zenModeController, StatusBarIconController statusBarIconController, - ActivityStarter activityStarter, - CommandQueue commandQueue, RingerModeTracker ringerModeTracker) { + ActivityStarter activityStarter, PrivacyItemController privacyItemController, + CommandQueue commandQueue, RingerModeTracker ringerModeTracker, + UiEventLogger uiEventLogger) { super(context, attrs); mAlarmController = nextAlarmController; mZenController = zenModeController; mStatusBarIconController = statusBarIconController; mActivityStarter = activityStarter; + mPrivacyItemController = privacyItemController; mDualToneHandler = new DualToneHandler( new ContextThemeWrapper(context, R.style.QSHeaderTheme)); mCommandQueue = commandQueue; mRingerModeTracker = ringerModeTracker; + mUiEventLogger = uiEventLogger; } @Override @@ -198,8 +240,11 @@ public class QuickStatusBarHeader extends RelativeLayout implements mRingerModeTextView = findViewById(R.id.ringer_mode_text); mRingerContainer = findViewById(R.id.ringer_container); mRingerContainer.setOnClickListener(this::onClick); + mPrivacyChip = findViewById(R.id.privacy_chip); + mPrivacyChip.setOnClickListener(this::onClick); mCarrierGroup = findViewById(R.id.carrier_group); + updateResources(); Rect tintArea = new Rect(0, 0, 0, 0); @@ -219,6 +264,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements mClockView = findViewById(R.id.clock); mClockView.setOnClickListener(this); mDateView = findViewById(R.id.date); + mSpace = findViewById(R.id.space); // Tint for the battery icons are handled in setupHost() mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon); @@ -229,6 +275,8 @@ public class QuickStatusBarHeader extends RelativeLayout implements mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE); mRingerModeTextView.setSelected(true); mNextAlarmTextView.setSelected(true); + + mPermissionsHubEnabled = mPrivacyItemController.isPermissionsHubEnabled(); } public QuickQSPanel getHeaderQsPanel() { @@ -241,6 +289,10 @@ public class QuickStatusBarHeader extends RelativeLayout implements com.android.internal.R.string.status_bar_camera)); ignored.add(mContext.getResources().getString( com.android.internal.R.string.status_bar_microphone)); + if (mPermissionsHubEnabled) { + ignored.add(mContext.getResources().getString( + com.android.internal.R.string.status_bar_location)); + } return ignored; } @@ -256,6 +308,20 @@ public class QuickStatusBarHeader extends RelativeLayout implements } } + private void setChipVisibility(boolean chipVisible) { + if (chipVisible && mPermissionsHubEnabled) { + mPrivacyChip.setVisibility(View.VISIBLE); + // Makes sure that the chip is logged as viewed at most once each time QS is opened + // mListening makes sure that the callback didn't return after the user closed QS + if (!mPrivacyChipLogged && mListening) { + mPrivacyChipLogged = true; + mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_VIEW); + } + } else { + mPrivacyChip.setVisibility(View.GONE); + } + } + private boolean updateRingerStatus() { boolean isOriginalVisible = mRingerModeTextView.getVisibility() == View.VISIBLE; CharSequence originalRingerText = mRingerModeTextView.getText(); @@ -363,6 +429,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements updateStatusIconAlphaAnimator(); updateHeaderTextContainerAlphaAnimator(); + updatePrivacyChipAlphaAnimator(); } private void updateStatusIconAlphaAnimator() { @@ -377,6 +444,12 @@ public class QuickStatusBarHeader extends RelativeLayout implements .build(); } + private void updatePrivacyChipAlphaAnimator() { + mPrivacyChipAlphaAnimator = new TouchAnimator.Builder() + .addFloat(mPrivacyChip, "alpha", 1, 0, 1) + .build(); + } + public void setExpanded(boolean expanded) { if (mExpanded == expanded) return; mExpanded = expanded; @@ -415,6 +488,10 @@ public class QuickStatusBarHeader extends RelativeLayout implements mHeaderTextContainerView.setVisibility(INVISIBLE); } } + if (mPrivacyChipAlphaAnimator != null) { + mPrivacyChip.setExpanded(expansionFraction > 0.5); + mPrivacyChipAlphaAnimator.setPosition(keyguardExpansionFraction); + } if (expansionFraction < 1 && expansionFraction > 0.99) { if (mHeaderQsPanel.switchTileLayout()) { updateResources(); @@ -442,6 +519,9 @@ public class QuickStatusBarHeader extends RelativeLayout implements }); mStatusBarIconController.addIconGroup(mIconManager); requestApplyInsets(); + // Change the ignored slots when DeviceConfig flag changes + DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_PRIVACY, + mContext.getMainExecutor(), mPropertiesListener); } @Override @@ -453,6 +533,31 @@ public class QuickStatusBarHeader extends RelativeLayout implements Pair padding = StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner( cutout, cornerCutoutPadding, -1); + if (padding == null) { + mSystemIconsView.setPaddingRelative( + getResources().getDimensionPixelSize(R.dimen.status_bar_padding_start), 0, + getResources().getDimensionPixelSize(R.dimen.status_bar_padding_end), 0); + } else { + mSystemIconsView.setPadding(padding.first, 0, padding.second, 0); + + } + LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mSpace.getLayoutParams(); + boolean cornerCutout = cornerCutoutPadding != null + && (cornerCutoutPadding.first == 0 || cornerCutoutPadding.second == 0); + if (cutout != null) { + Rect topCutout = cutout.getBoundingRectTop(); + if (topCutout.isEmpty() || cornerCutout) { + mHasTopCutout = false; + lp.width = 0; + mSpace.setVisibility(View.GONE); + } else { + mHasTopCutout = true; + lp.width = topCutout.width(); + mSpace.setVisibility(View.VISIBLE); + } + } + mSpace.setLayoutParams(lp); + setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE); mCutOutPaddingLeft = padding.first; mCutOutPaddingRight = padding.second; mWaterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top; @@ -496,6 +601,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements setListening(false); mRingerModeTracker.getRingerModeInternal().removeObservers(this); mStatusBarIconController.removeIconGroup(mIconManager); + DeviceConfig.removeOnPropertiesChangedListener(mPropertiesListener); super.onDetachedFromWindow(); } @@ -513,10 +619,13 @@ public class QuickStatusBarHeader extends RelativeLayout implements mZenController.addCallback(this); mAlarmController.addCallback(this); mLifecycle.setCurrentState(Lifecycle.State.RESUMED); + mPrivacyItemController.addCallback(mPICCallback); } else { mZenController.removeCallback(this); mAlarmController.removeCallback(this); mLifecycle.setCurrentState(Lifecycle.State.CREATED); + mPrivacyItemController.removeCallback(mPICCallback); + mPrivacyChipLogged = false; } } @@ -534,6 +643,17 @@ public class QuickStatusBarHeader extends RelativeLayout implements mActivityStarter.postStartActivityDismissingKeyguard(new Intent( AlarmClock.ACTION_SHOW_ALARMS), 0); } + } else if (v == mPrivacyChip) { + // Makes sure that the builder is grabbed as soon as the chip is pressed + PrivacyChipBuilder builder = mPrivacyChip.getBuilder(); + if (builder.getAppsAndTypes().size() == 0) return; + Handler mUiHandler = new Handler(Looper.getMainLooper()); + mUiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_CLICK); + mUiHandler.post(() -> { + mActivityStarter.postStartActivityDismissingKeyguard( + new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0); + mHost.collapsePanels(); + }); } else if (v == mRingerContainer && mRingerContainer.isVisibleToUser()) { mActivityStarter.postStartActivityDismissingKeyguard(new Intent( Settings.ACTION_SOUND_SETTINGS), 0); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index 5bb8fab8a62e..01b6fbf1f361 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -47,6 +47,9 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.DisplayId; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; +import com.android.systemui.privacy.PrivacyItem; +import com.android.systemui.privacy.PrivacyItemController; +import com.android.systemui.privacy.PrivacyType; import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.qs.tiles.RotationLockTile; import com.android.systemui.screenrecord.RecordingController; @@ -70,6 +73,9 @@ import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.RingerModeTracker; import com.android.systemui.util.time.DateFormatUtil; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.List; import java.util.Locale; import java.util.concurrent.Executor; @@ -87,13 +93,13 @@ public class PhoneStatusBarPolicy ZenModeController.Callback, DeviceProvisionedListener, KeyguardStateController.Callback, + PrivacyItemController.Callback, LocationController.LocationChangeCallback, RecordingController.RecordingStateChangeCallback { private static final String TAG = "PhoneStatusBarPolicy"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - static final int LOCATION_STATUS_ICON_ID = - com.android.internal.R.drawable.perm_group_location; + static final int LOCATION_STATUS_ICON_ID = PrivacyType.TYPE_LOCATION.getIconId(); private final String mSlotCast; private final String mSlotHotspot; @@ -107,6 +113,8 @@ public class PhoneStatusBarPolicy private final String mSlotHeadset; private final String mSlotDataSaver; private final String mSlotLocation; + private final String mSlotMicrophone; + private final String mSlotCamera; private final String mSlotSensorsOff; private final String mSlotScreenRecord; private final int mDisplayId; @@ -132,6 +140,7 @@ public class PhoneStatusBarPolicy private final DeviceProvisionedController mProvisionedController; private final KeyguardStateController mKeyguardStateController; private final LocationController mLocationController; + private final PrivacyItemController mPrivacyItemController; private final Executor mUiBgExecutor; private final SensorPrivacyController mSensorPrivacyController; private final RecordingController mRecordingController; @@ -162,7 +171,8 @@ public class PhoneStatusBarPolicy RecordingController recordingController, @Nullable TelecomManager telecomManager, @DisplayId int displayId, @Main SharedPreferences sharedPreferences, DateFormatUtil dateFormatUtil, - RingerModeTracker ringerModeTracker) { + RingerModeTracker ringerModeTracker, + PrivacyItemController privacyItemController) { mIconController = iconController; mCommandQueue = commandQueue; mBroadcastDispatcher = broadcastDispatcher; @@ -181,6 +191,7 @@ public class PhoneStatusBarPolicy mProvisionedController = deviceProvisionedController; mKeyguardStateController = keyguardStateController; mLocationController = locationController; + mPrivacyItemController = privacyItemController; mSensorPrivacyController = sensorPrivacyController; mRecordingController = recordingController; mUiBgExecutor = uiBgExecutor; @@ -200,6 +211,8 @@ public class PhoneStatusBarPolicy mSlotHeadset = resources.getString(com.android.internal.R.string.status_bar_headset); mSlotDataSaver = resources.getString(com.android.internal.R.string.status_bar_data_saver); mSlotLocation = resources.getString(com.android.internal.R.string.status_bar_location); + mSlotMicrophone = resources.getString(com.android.internal.R.string.status_bar_microphone); + mSlotCamera = resources.getString(com.android.internal.R.string.status_bar_camera); mSlotSensorsOff = resources.getString(com.android.internal.R.string.status_bar_sensors_off); mSlotScreenRecord = resources.getString( com.android.internal.R.string.status_bar_screen_record); @@ -271,6 +284,13 @@ public class PhoneStatusBarPolicy mResources.getString(R.string.accessibility_data_saver_on)); mIconController.setIconVisibility(mSlotDataSaver, false); + // privacy items + mIconController.setIcon(mSlotMicrophone, PrivacyType.TYPE_MICROPHONE.getIconId(), + mResources.getString(PrivacyType.TYPE_MICROPHONE.getNameId())); + mIconController.setIconVisibility(mSlotMicrophone, false); + mIconController.setIcon(mSlotCamera, PrivacyType.TYPE_CAMERA.getIconId(), + mResources.getString(PrivacyType.TYPE_CAMERA.getNameId())); + mIconController.setIconVisibility(mSlotCamera, false); mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID, mResources.getString(R.string.accessibility_location_active)); mIconController.setIconVisibility(mSlotLocation, false); @@ -294,6 +314,7 @@ public class PhoneStatusBarPolicy mNextAlarmController.addCallback(mNextAlarmCallback); mDataSaver.addCallback(this); mKeyguardStateController.addCallback(this); + mPrivacyItemController.addCallback(this); mSensorPrivacyController.addCallback(mSensorPrivacyListener); mLocationController.addCallback(this); mRecordingController.addCallback(this); @@ -609,9 +630,46 @@ public class PhoneStatusBarPolicy mIconController.setIconVisibility(mSlotDataSaver, isDataSaving); } + @Override // PrivacyItemController.Callback + public void privacyChanged(List privacyItems) { + updatePrivacyItems(privacyItems); + } + + private void updatePrivacyItems(List items) { + boolean showCamera = false; + boolean showMicrophone = false; + boolean showLocation = false; + for (PrivacyItem item : items) { + if (item == null /* b/124234367 */) { + if (DEBUG) { + Log.e(TAG, "updatePrivacyItems - null item found"); + StringWriter out = new StringWriter(); + mPrivacyItemController.dump(null, new PrintWriter(out), null); + Log.e(TAG, out.toString()); + } + continue; + } + switch (item.getPrivacyType()) { + case TYPE_CAMERA: + showCamera = true; + break; + case TYPE_LOCATION: + showLocation = true; + break; + case TYPE_MICROPHONE: + showMicrophone = true; + break; + } + } + + mIconController.setIconVisibility(mSlotCamera, showCamera); + mIconController.setIconVisibility(mSlotMicrophone, showMicrophone); + mIconController.setIconVisibility(mSlotLocation, showLocation); + } + @Override public void onLocationActiveChanged(boolean active) { - updateLocation(); + if (!mPrivacyItemController.isPermissionsHubEnabled()) updateLocation(); } // Updates the status view based on the current state of location requests. diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyChipBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyChipBuilderTest.kt new file mode 100644 index 000000000000..dcee5a716ceb --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyChipBuilderTest.kt @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 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.privacy + +import androidx.test.filters.SmallTest +import androidx.test.runner.AndroidJUnit4 +import com.android.systemui.SysuiTestCase +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +@SmallTest +class PrivacyChipBuilderTest : SysuiTestCase() { + + companion object { + val TEST_UID = 1 + } + + @Test + fun testGenerateAppsList() { + val bar2 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication( + "Bar", TEST_UID)) + val bar3 = PrivacyItem(Privacy.TYPE_LOCATION, PrivacyApplication( + "Bar", TEST_UID)) + val foo0 = PrivacyItem(Privacy.TYPE_MICROPHONE, PrivacyApplication( + "Foo", TEST_UID)) + val baz1 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication( + "Baz", TEST_UID)) + + val items = listOf(bar2, foo0, baz1, bar3) + + val textBuilder = PrivacyChipBuilder(context, items) + + val list = textBuilder.appsAndTypes + assertEquals(3, list.size) + val appsList = list.map { it.first } + val typesList = list.map { it.second } + // List is sorted by number of types and then by types + assertEquals(listOf("Bar", "Baz", "Foo"), appsList.map { it.packageName }) + assertEquals(listOf(Privacy.TYPE_CAMERA, Privacy.TYPE_LOCATION), typesList[0]) + assertEquals(listOf(Privacy.TYPE_CAMERA), typesList[1]) + assertEquals(listOf(Privacy.TYPE_MICROPHONE), typesList[2]) + } + + @Test + fun testOrder() { + // We want location to always go last, so it will go in the "+ other apps" + val appCamera = PrivacyItem(PrivacyType.TYPE_CAMERA, + PrivacyApplication("Camera", TEST_UID)) + val appMicrophone = + PrivacyItem(PrivacyType.TYPE_MICROPHONE, + PrivacyApplication("Microphone", TEST_UID)) + val appLocation = + PrivacyItem(PrivacyType.TYPE_LOCATION, + PrivacyApplication("Location", TEST_UID)) + + val items = listOf(appLocation, appMicrophone, appCamera) + val textBuilder = PrivacyChipBuilder(context, items) + val appList = textBuilder.appsAndTypes.map { it.first }.map { it.packageName } + assertEquals(listOf("Camera", "Microphone", "Location"), appList) + } +} \ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt new file mode 100644 index 000000000000..1f7baa9c4fcd --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2020 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.privacy + +import android.app.ActivityManager +import android.app.AppOpsManager +import android.content.Context +import android.content.Intent +import android.content.pm.UserInfo +import android.os.UserHandle +import android.os.UserManager +import android.provider.DeviceConfig +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper.RunWithLooper +import androidx.test.filters.SmallTest +import com.android.internal.config.sysui.SystemUiDeviceConfigFlags +import com.android.systemui.SysuiTestCase +import com.android.systemui.appops.AppOpItem +import com.android.systemui.appops.AppOpsController +import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.dump.DumpManager +import com.android.systemui.util.DeviceConfigProxy +import com.android.systemui.util.DeviceConfigProxyFake +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.time.FakeSystemClock +import org.hamcrest.Matchers.hasItem +import org.hamcrest.Matchers.not +import org.hamcrest.Matchers.nullValue +import org.junit.Assert.assertEquals +import org.junit.Assert.assertThat +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.anyList +import org.mockito.Captor +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.atLeastOnce +import org.mockito.Mockito.doReturn +import org.mockito.Mockito.mock +import org.mockito.Mockito.never +import org.mockito.Mockito.reset +import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyNoMoreInteractions +import org.mockito.MockitoAnnotations + +@RunWith(AndroidTestingRunner::class) +@SmallTest +@RunWithLooper +class PrivacyItemControllerTest : SysuiTestCase() { + + companion object { + val CURRENT_USER_ID = ActivityManager.getCurrentUser() + val TEST_UID = CURRENT_USER_ID * UserHandle.PER_USER_RANGE + const val SYSTEM_UID = 1000 + const val TEST_PACKAGE_NAME = "test" + const val DEVICE_SERVICES_STRING = "Device services" + const val TAG = "PrivacyItemControllerTest" + fun capture(argumentCaptor: ArgumentCaptor): T = argumentCaptor.capture() + fun eq(value: T): T = Mockito.eq(value) ?: value + fun any(): T = Mockito.any() + } + + @Mock + private lateinit var appOpsController: AppOpsController + @Mock + private lateinit var callback: PrivacyItemController.Callback + @Mock + private lateinit var userManager: UserManager + @Mock + private lateinit var broadcastDispatcher: BroadcastDispatcher + @Mock + private lateinit var dumpManager: DumpManager + @Captor + private lateinit var argCaptor: ArgumentCaptor> + @Captor + private lateinit var argCaptorCallback: ArgumentCaptor + + private lateinit var privacyItemController: PrivacyItemController + private lateinit var executor: FakeExecutor + private lateinit var deviceConfigProxy: DeviceConfigProxy + + fun PrivacyItemController(context: Context): PrivacyItemController { + return PrivacyItemController( + context, + appOpsController, + executor, + executor, + broadcastDispatcher, + deviceConfigProxy, + dumpManager + ) + } + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + executor = FakeExecutor(FakeSystemClock()) + deviceConfigProxy = DeviceConfigProxyFake() + + appOpsController = mDependency.injectMockDependency(AppOpsController::class.java) + mContext.addMockSystemService(UserManager::class.java, userManager) + + deviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_PRIVACY, + SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, + "true", false) + + doReturn(listOf(object : UserInfo() { + init { + id = CURRENT_USER_ID + } + })).`when`(userManager).getProfiles(anyInt()) + + privacyItemController = PrivacyItemController(mContext) + } + + @Test + fun testSetListeningTrueByAddingCallback() { + privacyItemController.addCallback(callback) + executor.runAllReady() + verify(appOpsController).addCallback(eq(PrivacyItemController.OPS), + any()) + verify(callback).privacyChanged(anyList()) + } + + @Test + fun testSetListeningFalseByRemovingLastCallback() { + privacyItemController.addCallback(callback) + executor.runAllReady() + verify(appOpsController, never()).removeCallback(any(), + any()) + privacyItemController.removeCallback(callback) + executor.runAllReady() + verify(appOpsController).removeCallback(eq(PrivacyItemController.OPS), + any()) + verify(callback).privacyChanged(emptyList()) + } + + @Test + fun testDistinctItems() { + doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 0), + AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 1))) + .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) + + privacyItemController.addCallback(callback) + executor.runAllReady() + verify(callback).privacyChanged(capture(argCaptor)) + assertEquals(1, argCaptor.value.size) + } + + @Test + fun testRegisterReceiver_allUsers() { + privacyItemController.addCallback(callback) + executor.runAllReady() + verify(broadcastDispatcher, atLeastOnce()).registerReceiver( + eq(privacyItemController.userSwitcherReceiver), any(), eq(null), eq(UserHandle.ALL)) + verify(broadcastDispatcher, never()) + .unregisterReceiver(eq(privacyItemController.userSwitcherReceiver)) + } + + @Test + fun testReceiver_ACTION_USER_FOREGROUND() { + privacyItemController.userSwitcherReceiver.onReceive(context, + Intent(Intent.ACTION_USER_SWITCHED)) + executor.runAllReady() + verify(userManager).getProfiles(anyInt()) + } + + @Test + fun testReceiver_ACTION_MANAGED_PROFILE_ADDED() { + privacyItemController.userSwitcherReceiver.onReceive(context, + Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)) + executor.runAllReady() + verify(userManager).getProfiles(anyInt()) + } + + @Test + fun testReceiver_ACTION_MANAGED_PROFILE_REMOVED() { + privacyItemController.userSwitcherReceiver.onReceive(context, + Intent(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) + executor.runAllReady() + verify(userManager).getProfiles(anyInt()) + } + + @Test + fun testAddMultipleCallbacks() { + val otherCallback = mock(PrivacyItemController.Callback::class.java) + privacyItemController.addCallback(callback) + executor.runAllReady() + verify(callback).privacyChanged(anyList()) + + privacyItemController.addCallback(otherCallback) + executor.runAllReady() + verify(otherCallback).privacyChanged(anyList()) + // Adding a callback should not unnecessarily call previous ones + verifyNoMoreInteractions(callback) + } + + @Test + fun testMultipleCallbacksAreUpdated() { + doReturn(emptyList()).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) + + val otherCallback = mock(PrivacyItemController.Callback::class.java) + privacyItemController.addCallback(callback) + privacyItemController.addCallback(otherCallback) + executor.runAllReady() + reset(callback) + reset(otherCallback) + + verify(appOpsController).addCallback(any(), capture(argCaptorCallback)) + argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true) + executor.runAllReady() + verify(callback).privacyChanged(anyList()) + verify(otherCallback).privacyChanged(anyList()) + } + + @Test + fun testRemoveCallback() { + doReturn(emptyList()).`when`(appOpsController).getActiveAppOpsForUser(anyInt()) + val otherCallback = mock(PrivacyItemController.Callback::class.java) + privacyItemController.addCallback(callback) + privacyItemController.addCallback(otherCallback) + executor.runAllReady() + executor.runAllReady() + reset(callback) + reset(otherCallback) + + verify(appOpsController).addCallback(any(), capture(argCaptorCallback)) + privacyItemController.removeCallback(callback) + argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true) + executor.runAllReady() + verify(callback, never()).privacyChanged(anyList()) + verify(otherCallback).privacyChanged(anyList()) + } + + @Test + fun testListShouldNotHaveNull() { + doReturn(listOf(AppOpItem(AppOpsManager.OP_ACTIVATE_VPN, TEST_UID, "", 0), + AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0))) + .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) + privacyItemController.addCallback(callback) + executor.runAllReady() + executor.runAllReady() + + verify(callback).privacyChanged(capture(argCaptor)) + assertEquals(1, argCaptor.value.size) + assertThat(argCaptor.value, not(hasItem(nullValue()))) + } + + @Test + fun testListShouldBeCopy() { + val list = listOf(PrivacyItem(PrivacyType.TYPE_CAMERA, + PrivacyApplication("", TEST_UID))) + privacyItemController.privacyList = list + val privacyList = privacyItemController.privacyList + assertEquals(list, privacyList) + assertTrue(list !== privacyList) + } + + @Test + fun testNotListeningWhenIndicatorsDisabled() { + deviceConfigProxy.setProperty( + DeviceConfig.NAMESPACE_PRIVACY, + SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, + "false", + false + ) + privacyItemController.addCallback(callback) + executor.runAllReady() + verify(appOpsController, never()).addCallback(eq(PrivacyItemController.OPS), + any()) + } +} \ No newline at end of file -- GitLab From fd89d72b13e23087fabdfeddb99d9d97727dd785 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Thu, 9 Jul 2020 09:23:37 -0400 Subject: [PATCH 061/536] Restricts notified app ops based on flags AppOps that are received by SystemUI and notified to listeners of AppOpsControllerImpl are filtered based on the permission flag PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED. As calls to obtain this flag require an IPC, three things are done to mitigate impact: * PermissionFlagsCache keeps track of requested flags and will update those (in a background thread), when a change is notified for a given uid. * Calls to getActiveAppOps/getActiveAppOpsForUser should be made from a background thread. * notifySubscribers is always called in the background thread. Bug: 160966908 Test: atest PermissionFlagsCacheTest AppOpsControllerTest Change-Id: I871094c32ce5ec940d779626333caa0ca500a4e3 Merged-In: I871094c32ce5ec940d779626333caa0ca500a4e3 --- data/etc/com.android.systemui.xml | 1 + packages/SystemUI/AndroidManifest.xml | 1 + .../systemui/appops/AppOpsControllerImpl.java | 76 ++++++++- .../systemui/appops/PermissionFlagsCache.kt | 85 ++++++++++ .../systemui/appops/AppOpsControllerTest.java | 46 +++++- .../appops/PermissionFlagsCacheTest.kt | 145 ++++++++++++++++++ 6 files changed, 348 insertions(+), 6 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/appops/PermissionFlagsCache.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/appops/PermissionFlagsCacheTest.kt diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml index a5a2221e5532..ada8b000a26b 100644 --- a/data/etc/com.android.systemui.xml +++ b/data/etc/com.android.systemui.xml @@ -39,6 +39,7 @@ + diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index a7ef5e6f58f0..46cb795941c9 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -239,6 +239,7 @@ + diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index fc7cc7ee55d3..ce8e285ff52f 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -18,6 +18,7 @@ package com.android.systemui.appops; import android.app.AppOpsManager; import android.content.Context; +import android.content.pm.PackageManager; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; @@ -25,6 +26,8 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; +import androidx.annotation.WorkerThread; + import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dumpable; @@ -62,6 +65,7 @@ public class AppOpsControllerImpl implements AppOpsController, private H mBGHandler; private final List mCallbacks = new ArrayList<>(); private final ArrayMap> mCallbacksByCode = new ArrayMap<>(); + private final PermissionFlagsCache mFlagsCache; private boolean mListening; @GuardedBy("mActiveItems") @@ -81,8 +85,11 @@ public class AppOpsControllerImpl implements AppOpsController, public AppOpsControllerImpl( Context context, @Background Looper bgLooper, - DumpManager dumpManager) { + DumpManager dumpManager, + PermissionFlagsCache cache + ) { mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); + mFlagsCache = cache; mBGHandler = new H(bgLooper); final int numOps = OPS.length; for (int i = 0; i < numOps; i++) { @@ -228,11 +235,67 @@ public class AppOpsControllerImpl implements AppOpsController, return createdNew; } + /** + * Does the app-op code refer to a user sensitive permission for the specified user id + * and package. Only user sensitive permission should be shown to the user by default. + * + * @param appOpCode The code of the app-op. + * @param uid The uid of the user. + * @param packageName The name of the package. + * + * @return {@code true} iff the app-op item is user sensitive + */ + private boolean isUserSensitive(int appOpCode, int uid, String packageName) { + String permission = AppOpsManager.opToPermission(appOpCode); + if (permission == null) { + return false; + } + int permFlags = mFlagsCache.getPermissionFlags(permission, + packageName, uid); + return (permFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0; + } + + /** + * Does the app-op item refer to an operation that should be shown to the user. + * Only specficic ops (like SYSTEM_ALERT_WINDOW) or ops that refer to user sensitive + * permission should be shown to the user by default. + * + * @param item The item + * + * @return {@code true} iff the app-op item should be shown to the user + */ + private boolean isUserVisible(AppOpItem item) { + return isUserVisible(item.getCode(), item.getUid(), item.getPackageName()); + } + + + /** + * Does the app-op, uid and package name, refer to an operation that should be shown to the + * user. Only specficic ops (like {@link AppOpsManager.OP_SYSTEM_ALERT_WINDOW}) or + * ops that refer to user sensitive permission should be shown to the user by default. + * + * @param item The item + * + * @return {@code true} iff the app-op for should be shown to the user + */ + private boolean isUserVisible(int appOpCode, int uid, String packageName) { + // currently OP_SYSTEM_ALERT_WINDOW does not correspond to a platform permission + // which may be user senstive, so for now always show it to the user. + if (appOpCode == AppOpsManager.OP_SYSTEM_ALERT_WINDOW) { + return true; + } + + return isUserSensitive(appOpCode, uid, packageName); + } + /** * Returns a copy of the list containing all the active AppOps that the controller tracks. * + * Call from a worker thread as it may perform long operations. + * * @return List of active AppOps information */ + @WorkerThread public List getActiveAppOps() { return getActiveAppOpsForUser(UserHandle.USER_ALL); } @@ -241,10 +304,13 @@ public class AppOpsControllerImpl implements AppOpsController, * Returns a copy of the list containing all the active AppOps that the controller tracks, for * a given user id. * + * Call from a worker thread as it may perform long operations. + * * @param userId User id to track, can be {@link UserHandle#USER_ALL} * * @return List of active AppOps information for that user id */ + @WorkerThread public List getActiveAppOpsForUser(int userId) { List list = new ArrayList<>(); synchronized (mActiveItems) { @@ -252,7 +318,8 @@ public class AppOpsControllerImpl implements AppOpsController, for (int i = 0; i < numActiveItems; i++) { AppOpItem item = mActiveItems.get(i); if ((userId == UserHandle.USER_ALL - || UserHandle.getUserId(item.getUid()) == userId)) { + || UserHandle.getUserId(item.getUid()) == userId) + && isUserVisible(item)) { list.add(item); } } @@ -262,7 +329,8 @@ public class AppOpsControllerImpl implements AppOpsController, for (int i = 0; i < numNotedItems; i++) { AppOpItem item = mNotedItems.get(i); if ((userId == UserHandle.USER_ALL - || UserHandle.getUserId(item.getUid()) == userId)) { + || UserHandle.getUserId(item.getUid()) == userId) + && isUserVisible(item)) { list.add(item); } } @@ -310,7 +378,7 @@ public class AppOpsControllerImpl implements AppOpsController, } private void notifySuscribers(int code, int uid, String packageName, boolean active) { - if (mCallbacksByCode.containsKey(code)) { + if (mCallbacksByCode.containsKey(code) && isUserVisible(code, uid, packageName)) { if (DEBUG) Log.d(TAG, "Notifying of change in package " + packageName); for (Callback cb: mCallbacksByCode.get(code)) { cb.onActiveStateChanged(code, uid, packageName, active); diff --git a/packages/SystemUI/src/com/android/systemui/appops/PermissionFlagsCache.kt b/packages/SystemUI/src/com/android/systemui/appops/PermissionFlagsCache.kt new file mode 100644 index 000000000000..9248b4f88a36 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/appops/PermissionFlagsCache.kt @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 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.appops + +import android.content.pm.PackageManager +import android.os.UserHandle +import androidx.annotation.WorkerThread +import com.android.systemui.dagger.qualifiers.Background +import java.util.concurrent.Executor +import javax.inject.Inject +import javax.inject.Singleton + +private data class PermissionFlagKey( + val permission: String, + val packageName: String, + val uid: Int +) + +/** + * Cache for PackageManager's PermissionFlags. + * + * After a specific `{permission, package, uid}` has been requested, updates to it will be tracked, + * and changes to the uid will trigger new requests (in the background). + */ +@Singleton +class PermissionFlagsCache @Inject constructor( + private val packageManager: PackageManager, + @Background private val executor: Executor +) : PackageManager.OnPermissionsChangedListener { + + private val permissionFlagsCache = + mutableMapOf>() + private var listening = false + + override fun onPermissionsChanged(uid: Int) { + executor.execute { + // Only track those that we've seen before + val keys = permissionFlagsCache.get(uid) + if (keys != null) { + keys.mapValuesTo(keys) { + getFlags(it.key) + } + } + } + } + + /** + * Retrieve permission flags from cache or PackageManager. There parameters will be passed + * directly to [PackageManager]. + * + * Calls to this method should be done from a background thread. + */ + @WorkerThread + fun getPermissionFlags(permission: String, packageName: String, uid: Int): Int { + if (!listening) { + listening = true + packageManager.addOnPermissionsChangeListener(this) + } + val key = PermissionFlagKey(permission, packageName, uid) + return permissionFlagsCache.getOrPut(uid, { mutableMapOf() }).get(key) ?: run { + getFlags(key).also { + permissionFlagsCache.get(uid)?.put(key, it) + } + } + } + + private fun getFlags(key: PermissionFlagKey): Int { + return packageManager.getPermissionFlags(key.permission, key.packageName, + UserHandle.getUserHandleForUid(key.uid)) + } +} \ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java index e0049d1349f1..4fdc06e64e2c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java @@ -26,11 +26,14 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.app.AppOpsManager; +import android.content.pm.PackageManager; import android.os.Looper; import android.os.UserHandle; import android.testing.AndroidTestingRunner; @@ -56,6 +59,7 @@ public class AppOpsControllerTest extends SysuiTestCase { private static final String TEST_PACKAGE_NAME = "test"; private static final int TEST_UID = UserHandle.getUid(0, 0); private static final int TEST_UID_OTHER = UserHandle.getUid(1, 0); + private static final int TEST_UID_NON_USER_SENSITIVE = UserHandle.getUid(2, 0); @Mock private AppOpsManager mAppOpsManager; @@ -65,6 +69,10 @@ public class AppOpsControllerTest extends SysuiTestCase { private AppOpsControllerImpl.H mMockHandler; @Mock private DumpManager mDumpManager; + @Mock + private PermissionFlagsCache mFlagsCache; + @Mock + private PackageManager mPackageManager; private AppOpsControllerImpl mController; private TestableLooper mTestableLooper; @@ -76,8 +84,22 @@ public class AppOpsControllerTest extends SysuiTestCase { getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager); - mController = - new AppOpsControllerImpl(mContext, mTestableLooper.getLooper(), mDumpManager); + // All permissions of TEST_UID and TEST_UID_OTHER are user sensitive. None of + // TEST_UID_NON_USER_SENSITIVE are user sensitive. + getContext().setMockPackageManager(mPackageManager); + when(mFlagsCache.getPermissionFlags(anyString(), anyString(), eq(TEST_UID))).thenReturn( + PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED); + when(mFlagsCache.getPermissionFlags(anyString(), anyString(), eq(TEST_UID_OTHER))) + .thenReturn(PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED); + when(mFlagsCache.getPermissionFlags(anyString(), anyString(), + eq(TEST_UID_NON_USER_SENSITIVE))).thenReturn(0); + + mController = new AppOpsControllerImpl( + mContext, + mTestableLooper.getLooper(), + mDumpManager, + mFlagsCache + ); } @Test @@ -172,6 +194,26 @@ public class AppOpsControllerTest extends SysuiTestCase { mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID_OTHER)).size()); } + @Test + public void nonUserSensitiveOpsAreIgnored() { + mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO, + TEST_UID_NON_USER_SENSITIVE, TEST_PACKAGE_NAME, true); + assertEquals(0, mController.getActiveAppOpsForUser( + UserHandle.getUserId(TEST_UID_NON_USER_SENSITIVE)).size()); + } + + @Test + public void nonUserSensitiveOpsNotNotified() { + mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback); + mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO, + TEST_UID_NON_USER_SENSITIVE, TEST_PACKAGE_NAME, true); + + mTestableLooper.processAllMessages(); + + verify(mCallback, never()) + .onActiveStateChanged(anyInt(), anyInt(), anyString(), anyBoolean()); + } + @Test public void opNotedScheduledForRemoval() { mController.setBGHandler(mMockHandler); diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/PermissionFlagsCacheTest.kt b/packages/SystemUI/tests/src/com/android/systemui/appops/PermissionFlagsCacheTest.kt new file mode 100644 index 000000000000..0fb0ce087ee3 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/appops/PermissionFlagsCacheTest.kt @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2020 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.appops + +import android.content.pm.PackageManager +import android.os.UserHandle +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.time.FakeSystemClock +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotEquals +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyString +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.never +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class PermissionFlagsCacheTest : SysuiTestCase() { + + companion object { + const val TEST_PERMISSION = "test_permission" + const val TEST_PACKAGE = "test_package" + const val TEST_UID1 = 1000 + const val TEST_UID2 = UserHandle.PER_USER_RANGE + 1000 + } + + @Mock + private lateinit var packageManager: PackageManager + + private lateinit var executor: FakeExecutor + private lateinit var flagsCache: PermissionFlagsCache + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + executor = FakeExecutor(FakeSystemClock()) + + flagsCache = PermissionFlagsCache(packageManager, executor) + executor.runAllReady() + } + + @Test + fun testNotListeningByDefault() { + verify(packageManager, never()).addOnPermissionsChangeListener(any()) + } + + @Test + fun testGetCorrectFlags() { + `when`(packageManager.getPermissionFlags(anyString(), anyString(), any())).thenReturn(0) + `when`(packageManager.getPermissionFlags( + TEST_PERMISSION, + TEST_PACKAGE, + UserHandle.getUserHandleForUid(TEST_UID1)) + ).thenReturn(1) + + assertEquals(1, flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, TEST_UID1)) + assertNotEquals(1, flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, TEST_UID2)) + } + + @Test + fun testFlagIsCached() { + flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, TEST_UID1) + + flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, TEST_UID1) + + verify(packageManager, times(1)).getPermissionFlags( + TEST_PERMISSION, + TEST_PACKAGE, + UserHandle.getUserHandleForUid(TEST_UID1) + ) + } + + @Test + fun testListeningAfterFirstRequest() { + flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, TEST_UID1) + + verify(packageManager).addOnPermissionsChangeListener(any()) + } + + @Test + fun testListeningOnlyOnce() { + flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, TEST_UID1) + + flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, TEST_UID2) + + verify(packageManager, times(1)).addOnPermissionsChangeListener(any()) + } + + @Test + fun testUpdateFlag() { + assertEquals(0, flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, TEST_UID1)) + + `when`(packageManager.getPermissionFlags( + TEST_PERMISSION, + TEST_PACKAGE, + UserHandle.getUserHandleForUid(TEST_UID1)) + ).thenReturn(1) + + flagsCache.onPermissionsChanged(TEST_UID1) + + executor.runAllReady() + + assertEquals(1, flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, TEST_UID1)) + } + + @Test + fun testUpdateFlag_notUpdatedIfUidHasNotBeenRequestedBefore() { + flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, TEST_UID1) + + flagsCache.onPermissionsChanged(TEST_UID2) + + executor.runAllReady() + + verify(packageManager, never()).getPermissionFlags( + TEST_PERMISSION, + TEST_PACKAGE, + UserHandle.getUserHandleForUid(TEST_UID2) + ) + } +} \ No newline at end of file -- GitLab From b46f97157356ab27224e70cd8184f2d5cfb24721 Mon Sep 17 00:00:00 2001 From: Curtis Belmonte Date: Mon, 20 Jul 2020 17:22:06 -0700 Subject: [PATCH 062/536] Don't auto-restart face auth after successful auth Currently, face auth sends a message to restart face authentication 500ms after a successful authentication attempt. This is a holdover from fingerprint and is unnecessary for face, since the latter is entirely interrupt-driven. It is also leading to issues where face auth will scan repeatedly when SystemUI freezes or is slow to respond. Thus, this commit removes the restart behavior after the user has authenticated. Test: atest com.android.keyguard Test: Manually verified face auth functionality in Keyguard. Bug: 157630051 Change-Id: I8bfb7870d3c68f6d40fdbf7209446782c5805f8f --- .../com/android/keyguard/KeyguardUpdateMonitor.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index c07c982b7451..60541eb56afc 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -286,11 +286,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private final Executor mBackgroundExecutor; /** - * Short delay before restarting biometric authentication after a successful try - * This should be slightly longer than the time between onAuthenticated - * (e.g. onFingerprintAuthenticated) and setKeyguardGoingAway(true). + * Short delay before restarting fingerprint authentication after a successful try. This should + * be slightly longer than the time between onFingerprintAuthenticated and + * setKeyguardGoingAway(true). */ - private static final int BIOMETRIC_CONTINUE_DELAY_MS = 500; + private static final int FINGERPRINT_CONTINUE_DELAY_MS = 500; // If the HAL dies or is unable to authenticate, keyguard should retry after a short delay private int mHardwareFingerprintUnavailableRetryCount = 0; @@ -598,7 +598,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE), - BIOMETRIC_CONTINUE_DELAY_MS); + FINGERPRINT_CONTINUE_DELAY_MS); // Only authenticate fingerprint once when assistant is visible mAssistantVisible = false; @@ -780,9 +780,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } - mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE), - BIOMETRIC_CONTINUE_DELAY_MS); - // Only authenticate face once when assistant is visible mAssistantVisible = false; -- GitLab From 782bdfc3828bcbf753ff4550f8378653298c191f Mon Sep 17 00:00:00 2001 From: yawanng Date: Tue, 14 Jul 2020 23:58:07 +0000 Subject: [PATCH 063/536] EventSequenceValidator: Only record the debug log in debugging level. The stack trace log may confuse other developers and mistakenly points to IORap as the bug cause. cherry-pick from ef5e1a6dbee8c7b2db4f150ea9463a8523a207ec Bug: 161145462 Test: Make and check the logcat. Merged-In: I3cb24cace060cff381ab3c5770ff6c1c948a2d89 Change-Id: I3cb24cace060cff381ab3c5770ff6c1c948a2d89 --- .../startop/iorap/EventSequenceValidator.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java b/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java index 67e1b440e28a..9b7a62b3a1df 100644 --- a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java +++ b/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java @@ -96,7 +96,8 @@ import java.io.PrintWriter; */ public class EventSequenceValidator implements ActivityMetricsLaunchObserver { static final String TAG = "EventSequenceValidator"; - + /** $> adb shell 'setprop log.tag.EventSequenceValidator VERBOSE' */ + public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private State state = State.INIT; private long accIntentStartedEvents = 0; @@ -255,9 +256,11 @@ public class EventSequenceValidator implements ActivityMetricsLaunchObserver { } private void logWarningWithStackTrace(String log) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - new Throwable("EventSequenceValidator#getStackTrace").printStackTrace(pw); - Log.d(TAG, String.format("%s\n%s", log, sw)); + if (DEBUG) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + new Throwable("EventSequenceValidator#getStackTrace").printStackTrace(pw); + Log.wtf(TAG, String.format("%s\n%s", log, sw)); + } } } -- GitLab From ca643c5c337a910559e5c1d25cb3f692bdd272ff Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Thu, 16 Jul 2020 13:07:08 -0700 Subject: [PATCH 064/536] DO NOT MERGE Add permission checks before delivery PendingIntent.send() only checks permissions for broadcast intents, and not for activity/service intents. In order to ensure permissions are checked for all types of intents, we need to add permission checks earlier in the process. Bug: 161456367 Test: presubmits + manual Change-Id: Ib56a382f4a2a8d25aa23a8230e0b82edf024a6fd --- .../android/server/location/AppOpsHelper.java | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/location/AppOpsHelper.java b/services/core/java/com/android/server/location/AppOpsHelper.java index c598fb1dbe26..d0192cdb93d3 100644 --- a/services/core/java/com/android/server/location/AppOpsHelper.java +++ b/services/core/java/com/android/server/location/AppOpsHelper.java @@ -18,7 +18,9 @@ package com.android.server.location; import static android.app.AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION; import static android.app.AppOpsManager.OP_MONITOR_LOCATION; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static com.android.server.location.CallerIdentity.PERMISSION_NONE; import static com.android.server.location.LocationManagerService.D; import static com.android.server.location.LocationManagerService.TAG; @@ -122,8 +124,18 @@ public class AppOpsHelper { Preconditions.checkState(mAppOps != null); } + if (callerIdentity.permissionLevel == PERMISSION_NONE) { + return false; + } + long identity = Binder.clearCallingIdentity(); try { + if (mContext.checkPermission( + CallerIdentity.asPermission(callerIdentity.permissionLevel), callerIdentity.pid, + callerIdentity.uid) != PERMISSION_GRANTED) { + return false; + } + return mAppOps.checkOpNoThrow( CallerIdentity.asAppOp(callerIdentity.permissionLevel), callerIdentity.uid, @@ -138,8 +150,24 @@ public class AppOpsHelper { * called right before a location is delivered, and if it returns false, the location should not * be delivered. */ - public boolean noteLocationAccess(CallerIdentity identity) { - return noteOpNoThrow(CallerIdentity.asAppOp(identity.permissionLevel), identity); + public boolean noteLocationAccess(CallerIdentity callerIdentity) { + if (callerIdentity.permissionLevel == PERMISSION_NONE) { + return false; + } + + long identity = Binder.clearCallingIdentity(); + try { + if (mContext.checkPermission( + CallerIdentity.asPermission(callerIdentity.permissionLevel), callerIdentity.pid, + callerIdentity.uid) != PERMISSION_GRANTED) { + return false; + } + } finally { + Binder.restoreCallingIdentity(identity); + } + + return noteOpNoThrow(CallerIdentity.asAppOp(callerIdentity.permissionLevel), + callerIdentity); } /** -- GitLab From e830adfef69aee63273ab62e31fff576fe526563 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Fri, 17 Jul 2020 15:01:02 -0700 Subject: [PATCH 065/536] Add ripple and border to emergency call button Bug: 149109279 Test: visual (on walleye and crosshatch) Change-Id: Iaa29965f63ae92c26f6924e4934eb7cb6b2754ce (cherry picked from commit d35002d362474a69305cc28c2e30e8ecb531bc11) --- core/res/res/values/strings.xml | 2 +- .../kg_emergency_button_background.xml | 32 +++++++++++++++++++ .../keyguard_emergency_carrier_area.xml | 9 +++--- .../SystemUI/res-keyguard/values/styles.xml | 8 +++-- 4 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 4f9911fbe387..d6ee28b93f92 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2122,7 +2122,7 @@ Draw pattern to unlock - Emergency + Emergency call Return to call diff --git a/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml new file mode 100644 index 000000000000..cc2089f69287 --- /dev/null +++ b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml index 3018a022e763..370576b43463 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml @@ -33,6 +33,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" style="@style/Keyguard.TextView" + android:layout_marginBottom="8dp" android:singleLine="true" android:ellipsize="marquee" android:visibility="gone" @@ -42,11 +43,9 @@ + style="@style/Keyguard.TextView.EmergencyButton" /> diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml index 5f2a946a1b6d..53eb2343d26a 100644 --- a/packages/SystemUI/res-keyguard/values/styles.xml +++ b/packages/SystemUI/res-keyguard/values/styles.xml @@ -23,10 +23,12 @@ ?attr/wallpaperTextColorSecondary @dimen/kg_status_line_font_size - -- GitLab From 53c36b7e74a94d9d8fa4f2e37442dbc4985bb640 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Tue, 28 Jul 2020 14:10:47 -0400 Subject: [PATCH 171/536] Add EBS interface to BatteryController Also, add a CurrentUserContentResolverProvider for testability and fix a bug in CurrentUserContextTracker Test: no test Bug: 153940148 Change-Id: Ie450194ee34b319cff926a49aca99544dcca0e9c Merged-In: Ie450194ee34b319cff926a49aca99544dcca0e9c (cherry picked from commit c553798e859ca9d623ce58b5db1226317fc7994c) --- .../systemui/qs/tiles/BatterySaverTile.java | 1 + .../CurrentUserContentResolverProvider.kt | 24 +++++++++++++++++++ .../settings/CurrentUserContextTracker.kt | 8 +++++-- .../settings/dagger/SettingsModule.java | 9 ++++++- .../statusbar/policy/BatteryController.java | 10 ++++++++ 5 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/settings/CurrentUserContentResolverProvider.kt diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java index f2495048bf26..7150e4350304 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java @@ -111,6 +111,7 @@ public class BatterySaverTile extends QSTileImpl implements : mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; state.icon = mIcon; state.label = mContext.getString(R.string.battery_detail_switch_title); + state.secondaryLabel = ""; state.contentDescription = state.label; state.value = mPowerSave; state.expandedAccessibilityClassName = Switch.class.getName(); diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContentResolverProvider.kt b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContentResolverProvider.kt new file mode 100644 index 000000000000..9d05843b42bf --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContentResolverProvider.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2020 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.settings + +import android.content.ContentResolver + +interface CurrentUserContentResolverProvider { + + val currentUserContentResolver: ContentResolver +} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt index 825a7f3dbadb..d7c4caaa4f9d 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt +++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt @@ -16,6 +16,7 @@ package com.android.systemui.settings +import android.content.ContentResolver import android.content.Context import android.os.UserHandle import androidx.annotation.VisibleForTesting @@ -31,7 +32,7 @@ import java.lang.IllegalStateException class CurrentUserContextTracker internal constructor( private val sysuiContext: Context, broadcastDispatcher: BroadcastDispatcher -) { +) : CurrentUserContentResolverProvider { private val userTracker: CurrentUserTracker private var initialized = false @@ -44,6 +45,9 @@ class CurrentUserContextTracker internal constructor( return _curUserContext!! } + override val currentUserContentResolver: ContentResolver + get() = currentUserContext.contentResolver + init { userTracker = object : CurrentUserTracker(broadcastDispatcher) { override fun onUserSwitched(newUserId: Int) { @@ -54,8 +58,8 @@ class CurrentUserContextTracker internal constructor( fun initialize() { initialized = true - _curUserContext = makeUserContext(userTracker.currentUserId) userTracker.startTracking() + _curUserContext = makeUserContext(userTracker.currentUserId) } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java b/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java index 2c5c3ceb6e66..eb5bd5c01a78 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java +++ b/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java @@ -19,10 +19,12 @@ package com.android.systemui.settings.dagger; import android.content.Context; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.settings.CurrentUserContentResolverProvider; import com.android.systemui.settings.CurrentUserContextTracker; import javax.inject.Singleton; +import dagger.Binds; import dagger.Module; import dagger.Provides; @@ -30,7 +32,7 @@ import dagger.Provides; * Dagger Module for classes found within the com.android.systemui.settings package. */ @Module -public interface SettingsModule { +public abstract class SettingsModule { /** * Provides and initializes a CurrentUserContextTracker @@ -45,4 +47,9 @@ public interface SettingsModule { tracker.initialize(); return tracker; } + + @Binds + @Singleton + abstract CurrentUserContentResolverProvider bindCurrentUserContentResolverTracker( + CurrentUserContextTracker tracker); } 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 673549ab589f..e5a46797d035 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java @@ -78,6 +78,13 @@ public interface BatteryController extends DemoMode, Dumpable, */ default void setReverseState(boolean isReverse) {} + /** + * Returns {@code true} if extreme battery saver is on. + */ + default boolean isExtremeSaverOn() { + return false; + } + /** * A listener that will be notified whenever a change in battery level or power save mode has * occurred. @@ -92,6 +99,9 @@ public interface BatteryController extends DemoMode, Dumpable, default void onReverseChanged(boolean isReverse, int level, String name) { } + + default void onExtremeBatterySaverChanged(boolean isExtreme) { + } } /** -- GitLab From 2e0f351d3508c9d4dadc206d5cc056afa8adb1ce Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Wed, 29 Jul 2020 16:08:43 -0400 Subject: [PATCH 172/536] Add guts to media player on long press Adds the following: * Button for accessing settings * Button for dismissing player (similar path to when a package is uninstalled) Guts will close automatically if: * QS is collapsed * Media carousel changes pages Also, flattened the view hierarchy to support animations between states. Test: manual Test: atest com.android.systemui.media Bug: 156036025 Change-Id: I340e0b37393573f81a3bf12d5e453eccf5982473 Merged-In: I340e0b37393573f81a3bf12d5e453eccf5982473 (cherry picked from commit 429360fb399f4aa2bb51cbcdf76deb0f319e130f) --- packages/SystemUI/res/layout/media_view.xml | 98 ++++++++++++++++- .../res/layout/qs_media_panel_options.xml | 61 ----------- packages/SystemUI/res/values/strings.xml | 2 +- .../systemui/media/MediaCarouselController.kt | 8 +- .../media/MediaCarouselScrollHandler.kt | 2 + .../systemui/media/MediaControlPanel.java | 58 +++++++++- .../systemui/media/MediaDataManager.kt | 22 ++-- .../systemui/media/MediaHierarchyManager.kt | 7 ++ .../systemui/media/MediaViewController.kt | 69 +++++++++++- .../systemui/media/PlayerViewHolder.kt | 35 +++++- .../NotificationPanelViewController.java | 1 + .../systemui/media/MediaControlPanelTest.kt | 101 +++++++++++++++++- .../systemui/media/MediaDataManagerTest.kt | 14 +++ .../media/MediaHierarchyManagerTest.kt | 7 ++ 14 files changed, 400 insertions(+), 85 deletions(-) delete mode 100644 packages/SystemUI/res/layout/qs_media_panel_options.xml diff --git a/packages/SystemUI/res/layout/media_view.xml b/packages/SystemUI/res/layout/media_view.xml index 3c641afea0d6..ed870f8bb2ef 100644 --- a/packages/SystemUI/res/layout/media_view.xml +++ b/packages/SystemUI/res/layout/media_view.xml @@ -210,8 +210,98 @@ android:layout_width="@dimen/qs_media_icon_size" android:layout_height="@dimen/qs_media_icon_size" /> - - + + + + + + + + + + + + + + + + + + + diff --git a/packages/SystemUI/res/layout/qs_media_panel_options.xml b/packages/SystemUI/res/layout/qs_media_panel_options.xml deleted file mode 100644 index e72c0e85fb26..000000000000 --- a/packages/SystemUI/res/layout/qs_media_panel_options.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 28c1b02fc415..f875ecb9354e 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2822,7 +2822,7 @@ Hide the current session. - Hide + Dismiss Resume diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index 3a8412358221..15c60921cca5 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -151,7 +151,7 @@ class MediaCarouselController @Inject constructor( pageIndicator = mediaFrame.requireViewById(R.id.media_page_indicator) mediaCarouselScrollHandler = MediaCarouselScrollHandler(mediaCarousel, pageIndicator, executor, mediaManager::onSwipeToDismiss, this::updatePageIndicatorLocation, - falsingManager) + this::closeGuts, falsingManager) isRtl = context.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL inflateSettingsButton() mediaContent = mediaCarousel.requireViewById(R.id.media_carousel) @@ -470,6 +470,12 @@ class MediaCarouselController @Inject constructor( } } + fun closeGuts() { + mediaPlayers.values.forEach { + it.closeGuts(true) + } + } + /** * Update the size of the carousel, remeasuring it if necessary. */ diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt index 3096908aca21..77cac5023db3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt @@ -56,6 +56,7 @@ class MediaCarouselScrollHandler( private val mainExecutor: DelayableExecutor, private val dismissCallback: () -> Unit, private var translationChangedListener: () -> Unit, + private val closeGuts: () -> Unit, private val falsingManager: FalsingManager ) { /** @@ -452,6 +453,7 @@ class MediaCarouselScrollHandler( val nowScrolledIn = scrollIntoCurrentMedia != 0 if (newIndex != activeMediaIndex || wasScrolledIn != nowScrolledIn) { activeMediaIndex = newIndex + closeGuts() updatePlayerVisibilities() } val relativeLocation = activeMediaIndex.toFloat() + if (playerWidthPlusPadding > 0) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 3fc162ead6d1..e55678dc986b 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -16,6 +16,8 @@ package com.android.systemui.media; +import static android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS; + import android.app.PendingIntent; import android.content.Context; import android.content.Intent; @@ -45,6 +47,7 @@ import com.android.settingslib.widget.AdaptiveIcon; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.statusbar.phone.KeyguardDismissUtil; import com.android.systemui.util.animation.TransitionLayout; import java.util.List; @@ -52,6 +55,8 @@ import java.util.concurrent.Executor; import javax.inject.Inject; +import dagger.Lazy; + /** * A view controller used for Media Playback. */ @@ -59,6 +64,8 @@ public class MediaControlPanel { private static final String TAG = "MediaControlPanel"; private static final float DISABLED_ALPHA = 0.38f; + private static final Intent SETTINGS_INTENT = new Intent(ACTION_MEDIA_CONTROLS_SETTINGS); + // Button IDs for QS controls static final int[] ACTION_IDS = { R.id.action0, @@ -78,6 +85,8 @@ public class MediaControlPanel { private MediaViewController mMediaViewController; private MediaSession.Token mToken; private MediaController mController; + private KeyguardDismissUtil mKeyguardDismissUtil; + private Lazy mMediaDataManagerLazy; private int mBackgroundColor; private int mAlbumArtSize; private int mAlbumArtRadius; @@ -93,12 +102,15 @@ public class MediaControlPanel { @Inject public MediaControlPanel(Context context, @Background Executor backgroundExecutor, ActivityStarter activityStarter, MediaViewController mediaViewController, - SeekBarViewModel seekBarViewModel) { + SeekBarViewModel seekBarViewModel, Lazy lazyMediaDataManager, + KeyguardDismissUtil keyguardDismissUtil) { mContext = context; mBackgroundExecutor = backgroundExecutor; mActivityStarter = activityStarter; mSeekBarViewModel = seekBarViewModel; mMediaViewController = mediaViewController; + mMediaDataManagerLazy = lazyMediaDataManager; + mKeyguardDismissUtil = keyguardDismissUtil; loadDimens(); mViewOutlineProvider = new ViewOutlineProvider() { @@ -174,6 +186,21 @@ public class MediaControlPanel { mSeekBarViewModel.getProgress().observeForever(mSeekBarObserver); mSeekBarViewModel.attachTouchHandlers(vh.getSeekBar()); mMediaViewController.attach(player); + + mViewHolder.getPlayer().setOnLongClickListener(v -> { + if (!mMediaViewController.isGutsVisible()) { + mMediaViewController.openGuts(); + return true; + } else { + return false; + } + }); + mViewHolder.getCancel().setOnClickListener(v -> { + closeGuts(); + }); + mViewHolder.getSettings().setOnClickListener(v -> { + mActivityStarter.startActivity(SETTINGS_INTENT, true /* dismissShade */); + }); } /** @@ -205,6 +232,7 @@ public class MediaControlPanel { PendingIntent clickIntent = data.getClickIntent(); if (clickIntent != null) { mViewHolder.getPlayer().setOnClickListener(v -> { + if (mMediaViewController.isGutsVisible()) return; mActivityStarter.postStartActivityDismissingKeyguard(clickIntent); }); } @@ -329,14 +357,38 @@ public class MediaControlPanel { final MediaController controller = getController(); mBackgroundExecutor.execute(() -> mSeekBarViewModel.updateController(controller)); - // Set up long press menu - // TODO: b/156036025 bring back media guts + // Dismiss + mViewHolder.getDismiss().setOnClickListener(v -> { + if (data.getNotificationKey() != null) { + closeGuts(); + mKeyguardDismissUtil.executeWhenUnlocked(() -> { + mMediaDataManagerLazy.get().dismissMediaData(data.getNotificationKey(), + MediaViewController.GUTS_ANIMATION_DURATION + 100); + return true; + }, /* requiresShadeOpen */ true); + } else { + Log.w(TAG, "Dismiss media with null notification. Token uid=" + + data.getToken().getUid()); + } + }); // TODO: We don't need to refresh this state constantly, only if the state actually changed // to something which might impact the measurement mMediaViewController.refreshState(); } + /** + * Close the guts for this player. + * @param immediate {@code true} if it should be closed without animation + */ + public void closeGuts(boolean immediate) { + mMediaViewController.closeGuts(immediate); + } + + private void closeGuts() { + closeGuts(false); + } + @UiThread private Drawable scaleDrawable(Icon icon) { if (icon == null) { diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index b3277737f397..64ba5f7cc483 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -48,6 +48,7 @@ import com.android.systemui.statusbar.notification.MediaNotificationProcessor import com.android.systemui.statusbar.notification.row.HybridGroupManager import com.android.systemui.util.Assert import com.android.systemui.util.Utils +import com.android.systemui.util.concurrency.DelayableExecutor import java.io.FileDescriptor import java.io.IOException import java.io.PrintWriter @@ -89,7 +90,7 @@ fun isMediaNotification(sbn: StatusBarNotification): Boolean { class MediaDataManager( private val context: Context, @Background private val backgroundExecutor: Executor, - @Main private val foregroundExecutor: Executor, + @Main private val foregroundExecutor: DelayableExecutor, private val mediaControllerFactory: MediaControllerFactory, private val broadcastDispatcher: BroadcastDispatcher, dumpManager: DumpManager, @@ -106,7 +107,7 @@ class MediaDataManager( constructor( context: Context, @Background backgroundExecutor: Executor, - @Main foregroundExecutor: Executor, + @Main foregroundExecutor: DelayableExecutor, mediaControllerFactory: MediaControllerFactory, dumpManager: DumpManager, broadcastDispatcher: BroadcastDispatcher, @@ -182,10 +183,7 @@ class MediaDataManager( val listenersCopy = listeners.toSet() val toRemove = mediaEntries.filter { it.value.packageName == packageName } toRemove.forEach { - mediaEntries.remove(it.key) - listenersCopy.forEach { listener -> - listener.onMediaDataRemoved(it.key) - } + removeEntry(it.key, listenersCopy) } } @@ -267,6 +265,18 @@ class MediaDataManager( } } + private fun removeEntry(key: String, listenersCopy: Set) { + mediaEntries.remove(key) + listenersCopy.forEach { + it.onMediaDataRemoved(key) + } + } + + fun dismissMediaData(key: String, delay: Long) { + val listenersCopy = listeners.toSet() + foregroundExecutor.executeDelayed({ removeEntry(key, listenersCopy) }, delay) + } + private fun loadMediaDataInBgForResumption( userId: Int, desc: MediaDescription, diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt index fc33391a9ad1..70f01d576a9c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt @@ -293,6 +293,13 @@ class MediaHierarchyManager @Inject constructor( return viewHost } + /** + * Close the guts in all players in [MediaCarouselController]. + */ + fun closeGuts() { + mediaCarouselController.closeGuts() + } + private fun createUniqueObjectHost(): UniqueObjectHostView { val viewHost = UniqueObjectHostView(context) viewHost.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener { diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt index 38817d7b579e..92eeed46388d 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt @@ -37,6 +37,11 @@ class MediaViewController @Inject constructor( private val mediaHostStatesManager: MediaHostStatesManager ) { + companion object { + @JvmField + val GUTS_ANIMATION_DURATION = 500L + } + /** * A listener when the current dimensions of the player change */ @@ -169,6 +174,12 @@ class MediaViewController @Inject constructor( */ val expandedLayout = ConstraintSet() + /** + * Whether the guts are visible for the associated player. + */ + var isGutsVisible = false + private set + init { collapsedLayout.load(context, R.xml.media_collapsed) expandedLayout.load(context, R.xml.media_expanded) @@ -189,6 +200,37 @@ class MediaViewController @Inject constructor( configurationController.removeCallback(configurationListener) } + /** + * Show guts with an animated transition. + */ + fun openGuts() { + if (isGutsVisible) return + isGutsVisible = true + animatePendingStateChange(GUTS_ANIMATION_DURATION, 0L) + setCurrentState(currentStartLocation, + currentEndLocation, + currentTransitionProgress, + applyImmediately = false) + } + + /** + * Close the guts for the associated player. + * + * @param immediate if `false`, it will animate the transition. + */ + @JvmOverloads + fun closeGuts(immediate: Boolean = false) { + if (!isGutsVisible) return + isGutsVisible = false + if (!immediate) { + animatePendingStateChange(GUTS_ANIMATION_DURATION, 0L) + } + setCurrentState(currentStartLocation, + currentEndLocation, + currentTransitionProgress, + applyImmediately = immediate) + } + private fun ensureAllMeasurements() { val mediaStates = mediaHostStatesManager.mediaHostStates for (entry in mediaStates) { @@ -202,6 +244,24 @@ class MediaViewController @Inject constructor( private fun constraintSetForExpansion(expansion: Float): ConstraintSet = if (expansion > 0) expandedLayout else collapsedLayout + /** + * Set the views to be showing/hidden based on the [isGutsVisible] for a given + * [TransitionViewState]. + */ + private fun setGutsViewState(viewState: TransitionViewState) { + PlayerViewHolder.controlsIds.forEach { id -> + viewState.widgetStates.get(id)?.let { state -> + // Make sure to use the unmodified state if guts are not visible + state.alpha = if (isGutsVisible) 0f else state.alpha + state.gone = if (isGutsVisible) true else state.gone + } + } + PlayerViewHolder.gutsIds.forEach { id -> + viewState.widgetStates.get(id)?.alpha = if (isGutsVisible) 1f else 0f + viewState.widgetStates.get(id)?.gone = !isGutsVisible + } + } + /** * Obtain a new viewState for a given media state. This usually returns a cached state, but if * it's not available, it will recreate one by measuring, which may be expensive. @@ -211,7 +271,7 @@ class MediaViewController @Inject constructor( return null } // Only a subset of the state is relevant to get a valid viewState. Let's get the cachekey - var cacheKey = getKey(state, tmpKey) + var cacheKey = getKey(state, isGutsVisible, tmpKey) val viewState = viewStates[cacheKey] if (viewState != null) { // we already have cached this measurement, let's continue @@ -228,6 +288,7 @@ class MediaViewController @Inject constructor( constraintSetForExpansion(state.expansion), TransitionViewState()) + setGutsViewState(result) // We don't want to cache interpolated or null states as this could quickly fill up // our cache. We only cache the start and the end states since the interpolation // is cheap @@ -252,11 +313,12 @@ class MediaViewController @Inject constructor( return result } - private fun getKey(state: MediaHostState, result: CacheKey): CacheKey { + private fun getKey(state: MediaHostState, guts: Boolean, result: CacheKey): CacheKey { result.apply { heightMeasureSpec = state.measurementInput?.heightMeasureSpec ?: 0 widthMeasureSpec = state.measurementInput?.widthMeasureSpec ?: 0 expansion = state.expansion + gutsVisible = guts } return result } @@ -432,5 +494,6 @@ class MediaViewController @Inject constructor( private data class CacheKey( var widthMeasureSpec: Int = -1, var heightMeasureSpec: Int = -1, - var expansion: Float = 0.0f + var expansion: Float = 0.0f, + var gutsVisible: Boolean = false ) diff --git a/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt index 600fdc27ef89..666a6038a8b6 100644 --- a/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt @@ -59,6 +59,11 @@ class PlayerViewHolder private constructor(itemView: View) { val action3 = itemView.requireViewById(R.id.action3) val action4 = itemView.requireViewById(R.id.action4) + // Settings screen + val cancel = itemView.requireViewById(R.id.cancel) + val dismiss = itemView.requireViewById(R.id.dismiss) + val settings = itemView.requireViewById(R.id.settings) + init { (player.background as IlluminationDrawable).let { it.registerLightSource(seamless) @@ -67,6 +72,9 @@ class PlayerViewHolder private constructor(itemView: View) { it.registerLightSource(action2) it.registerLightSource(action3) it.registerLightSource(action4) + it.registerLightSource(cancel) + it.registerLightSource(dismiss) + it.registerLightSource(settings) } } @@ -83,9 +91,6 @@ class PlayerViewHolder private constructor(itemView: View) { } } - // Settings screen - val options = itemView.requireViewById(R.id.qs_media_controls_options) - companion object { /** * Creates a PlayerViewHolder. @@ -105,5 +110,29 @@ class PlayerViewHolder private constructor(itemView: View) { progressTimes.layoutDirection = View.LAYOUT_DIRECTION_LTR } } + + val controlsIds = setOf( + R.id.icon, + R.id.app_name, + R.id.album_art, + R.id.header_title, + R.id.header_artist, + R.id.media_seamless, + R.id.notification_media_progress_time, + R.id.media_progress_bar, + R.id.action0, + R.id.action1, + R.id.action2, + R.id.action3, + R.id.action4, + R.id.icon + ) + val gutsIds = setOf( + R.id.media_text, + R.id.remove_text, + R.id.cancel, + R.id.dismiss, + R.id.settings + ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 64202d221b2d..799e16cc6d8d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -2612,6 +2612,7 @@ public class NotificationPanelViewController extends PanelViewController { super.onClosingFinished(); resetHorizontalPanelPosition(); setClosingWithAlphaFadeout(false); + mMediaHierarchyManager.closeGuts(); } private void setClosingWithAlphaFadeout(boolean closing) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt index c63781cb110a..8a30b00e609d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt @@ -16,6 +16,7 @@ package com.android.systemui.media +import android.content.Intent import android.content.res.ColorStateList import android.graphics.Color import android.graphics.drawable.GradientDrawable @@ -23,6 +24,7 @@ import android.graphics.drawable.RippleDrawable import android.media.MediaMetadata import android.media.session.MediaSession import android.media.session.PlaybackState +import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.view.View @@ -35,24 +37,31 @@ import android.widget.TextView import androidx.constraintlayout.widget.ConstraintSet import androidx.lifecycle.LiveData import androidx.test.filters.SmallTest -import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.statusbar.phone.KeyguardDismissUtil import com.android.systemui.util.animation.TransitionLayout import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.eq +import com.android.systemui.util.mockito.any import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat +import dagger.Lazy import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor +import org.mockito.ArgumentMatchers +import org.mockito.ArgumentMatchers.anyLong import org.mockito.Mock +import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.mock +import org.mockito.Mockito.never import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` as whenever import org.mockito.junit.MockitoJUnit +import org.mockito.Mockito.`when` as whenever private const val KEY = "TEST_KEY" private const val APP = "APP" @@ -81,6 +90,8 @@ public class MediaControlPanelTest : SysuiTestCase() { @Mock private lateinit var seekBarViewModel: SeekBarViewModel @Mock private lateinit var seekBarData: LiveData @Mock private lateinit var mediaViewController: MediaViewController + @Mock private lateinit var keyguardDismissUtil: KeyguardDismissUtil + @Mock private lateinit var mediaDataManager: MediaDataManager @Mock private lateinit var expandedSet: ConstraintSet @Mock private lateinit var collapsedSet: ConstraintSet private lateinit var appIcon: ImageView @@ -100,6 +111,9 @@ public class MediaControlPanelTest : SysuiTestCase() { private lateinit var action2: ImageButton private lateinit var action3: ImageButton private lateinit var action4: ImageButton + private lateinit var settings: View + private lateinit var cancel: View + private lateinit var dismiss: View private lateinit var session: MediaSession private val device = MediaDeviceData(true, null, DEVICE_NAME) @@ -114,7 +128,7 @@ public class MediaControlPanelTest : SysuiTestCase() { whenever(mediaViewController.collapsedLayout).thenReturn(collapsedSet) player = MediaControlPanel(context, bgExecutor, activityStarter, mediaViewController, - seekBarViewModel) + seekBarViewModel, Lazy { mediaDataManager }, keyguardDismissUtil) whenever(seekBarViewModel.progress).thenReturn(seekBarData) // Mock out a view holder for the player to attach to. @@ -156,6 +170,12 @@ public class MediaControlPanelTest : SysuiTestCase() { whenever(holder.action3).thenReturn(action3) action4 = ImageButton(context) whenever(holder.action4).thenReturn(action4) + settings = View(context) + whenever(holder.settings).thenReturn(settings) + cancel = View(context) + whenever(holder.cancel).thenReturn(cancel) + dismiss = View(context) + whenever(holder.dismiss).thenReturn(dismiss) // Create media session val metadataBuilder = MediaMetadata.Builder().apply { @@ -254,4 +274,79 @@ public class MediaControlPanelTest : SysuiTestCase() { assertThat(seamlessText.getText()).isEqualTo(DEVICE_NAME) assertThat(seamless.isEnabled()).isFalse() } + + @Test + fun longClick_gutsClosed() { + player.attach(holder) + whenever(mediaViewController.isGutsVisible).thenReturn(false) + + val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java) + verify(holder.player).setOnLongClickListener(captor.capture()) + + captor.value.onLongClick(holder.player) + verify(mediaViewController).openGuts() + } + + @Test + fun longClick_gutsOpen() { + player.attach(holder) + whenever(mediaViewController.isGutsVisible).thenReturn(true) + + val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java) + verify(holder.player).setOnLongClickListener(captor.capture()) + + captor.value.onLongClick(holder.player) + verify(mediaViewController, never()).openGuts() + } + + @Test + fun cancelButtonClick_animation() { + player.attach(holder) + + cancel.callOnClick() + + verify(mediaViewController).closeGuts(false) + } + + @Test + fun settingsButtonClick() { + player.attach(holder) + + settings.callOnClick() + + val captor = ArgumentCaptor.forClass(Intent::class.java) + verify(activityStarter).startActivity(captor.capture(), eq(true)) + + assertThat(captor.value.action).isEqualTo(ACTION_MEDIA_CONTROLS_SETTINGS) + } + + @Test + fun dismissButtonClick() { + player.attach(holder) + val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), + emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null, + notificationKey = KEY) + player.bind(state) + + dismiss.callOnClick() + val captor = ArgumentCaptor.forClass(ActivityStarter.OnDismissAction::class.java) + verify(keyguardDismissUtil).executeWhenUnlocked(captor.capture(), anyBoolean()) + + captor.value.onDismiss() + verify(mediaDataManager).dismissMediaData(eq(KEY), anyLong()) + } + + @Test + fun dismissButtonClick_nullNotificationKey() { + player.attach(holder) + val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), + emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null) + player.bind(state) + + verify(keyguardDismissUtil, never()) + .executeWhenUnlocked( + any(ActivityStarter.OnDismissAction::class.java), + ArgumentMatchers.anyBoolean() + ) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt index 59c2d0e86c56..3789e6ef1f65 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt @@ -217,6 +217,20 @@ class MediaDataManagerTest : SysuiTestCase() { assertThat(data.actions).hasSize(1) } + @Test + fun testDismissMedia_listenerCalled() { + val listener = mock(MediaDataManager.Listener::class.java) + mediaDataManager.addListener(listener) + mediaDataManager.onNotificationAdded(KEY, mediaNotification) + mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = mock(MediaData::class.java)) + mediaDataManager.dismissMediaData(KEY, 0L) + + foregroundExecutor.advanceClockToLast() + foregroundExecutor.runAllReady() + + verify(listener).onMediaDataRemoved(eq(KEY)) + } + /** * Simple implementation of [MediaDataManager.Listener] for the test. * diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt index 91c5ff8ee627..d86dfa5fa5f7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt @@ -142,4 +142,11 @@ class MediaHierarchyManagerTest : SysuiTestCase() { verify(mediaCarouselController).onDesiredLocationChanged(ArgumentMatchers.anyInt(), any(MediaHostState::class.java), anyBoolean(), anyLong(), anyLong()) } + + @Test + fun testCloseGutsRelayToCarousel() { + mediaHiearchyManager.closeGuts() + + verify(mediaCarouselController).closeGuts() + } } \ No newline at end of file -- GitLab From 83f4bc398ec6d6cfe1f8d0b243ecaceb484d6f3b Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Fri, 7 Aug 2020 11:49:47 -0700 Subject: [PATCH 173/536] Change date format for better 'ja' compatibility eeeMMd doesn't properly translate dates in Japanese. According to ICU team, we should be using EEEMMd instead. The date output will be different in ja, ko, th out of 728 locales. Test: visual Fixes: 161186825 Change-Id: Ib551d532f08b89be3a0679c44c51b65f493f1a65 (cherry picked from commit 18bd42434f8c0d6624650e3accffe01f6cf7184a) --- core/res/res/values/donottranslate.xml | 2 +- packages/SystemUI/res/values/donottranslate.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/res/res/values/donottranslate.xml b/core/res/res/values/donottranslate.xml index 3a1679c19fc8..f46f70c2debf 100644 --- a/core/res/res/values/donottranslate.xml +++ b/core/res/res/values/donottranslate.xml @@ -23,7 +23,7 @@ square - eeeMMMMd + EEEMMMMd @string/icu_abbrev_wday_month_day_no_year - eeeMMMd + @*android:string/system_ui_date_pattern -- GitLab From 789432b5d1a9071afee5eff4dae60a3ae3797d8b Mon Sep 17 00:00:00 2001 From: Mattias Nilsson Date: Fri, 24 Jan 2020 17:49:49 +0100 Subject: [PATCH 174/536] Move config_inflateSignalStrength to CC Sim based customizations should not be resources because of two reasons: 1. The MCC/MNC value in AssetManager for Dual sim devices is undefined 2. There is no support for MVNOs. For dual sim devices there is only one value for MCC/MNC in AssetManager and that value is updated from multiple places without deciding if it should be the default voice sim card, the default data sim card or whatnot. This means that when frameworks is trying to decide what resource to use there is no guarantee that the resource that arrives is for the particular subscription we are asking for. MVNOs cannot be separated through only MCC/MNC but need more parameters like service provider, imsi, GID1 etc. MVNO support is available in CarrierConfig. When we now have support for ADCP updates of customizations and start using carrier id this is better placed in CarrierConfig, we then get support for MVNOs at the same time. Bug: 148483577 Test: Customize for sim card x and not for sim card y, insert both sim cards in a dual sim device and see the difference. Merged-In: I067d55b9ae5e1346dd3b3cd50a0097b05b100055 Change-Id: I067d55b9ae5e1346dd3b3cd50a0097b05b100055 --- .../android/settingslib/net/SignalStrengthUtil.java | 13 ++++++++++--- .../statusbar/policy/NetworkControllerImpl.java | 3 --- .../android/telephony/CarrierConfigManager.java | 10 ++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java b/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java index 246f2ceac87c..e1174fa05ea5 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java @@ -17,7 +17,8 @@ package com.android.settingslib.net; import android.content.Context; -import android.telephony.SubscriptionManager; +import android.os.PersistableBundle; +import android.telephony.CarrierConfigManager; /** * Utilities for dealing with signal strength. @@ -28,7 +29,13 @@ public class SignalStrengthUtil { * bar for the subscription with the given id */ public static boolean shouldInflateSignalStrength(Context context, int subscriptionId) { - return SubscriptionManager.getResourcesForSubId(context, subscriptionId) - .getBoolean(com.android.internal.R.bool.config_inflateSignalStrength); + final CarrierConfigManager carrierConfigMgr = + context.getSystemService(CarrierConfigManager.class); + PersistableBundle bundle = null; + if (carrierConfigMgr != null) { + bundle = carrierConfigMgr.getConfigForSubId(subscriptionId); + } + return (bundle != null && bundle.getBoolean( + CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false)); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 4ac3a9b6b40a..32c4aec39923 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -1191,7 +1191,6 @@ public class NetworkControllerImpl extends BroadcastReceiver boolean show4gForLte = false; boolean hideLtePlus = false; boolean hspaDataDistinguishable; - boolean inflateSignalStrengths = false; boolean alwaysShowDataRatIcon = false; static Config readConfig(Context context) { @@ -1203,8 +1202,6 @@ public class NetworkControllerImpl extends BroadcastReceiver res.getBoolean(com.android.internal.R.bool.config_alwaysUseCdmaRssi); config.hspaDataDistinguishable = res.getBoolean(R.bool.config_hspa_data_distinguishable); - config.inflateSignalStrengths = res.getBoolean( - com.android.internal.R.bool.config_inflateSignalStrength); CarrierConfigManager configMgr = (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 870b9a4dd667..ab659440e348 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1084,6 +1084,15 @@ public class CarrierConfigManager { public static final String KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL = "show_signal_strength_in_sim_status_bool"; + /** + * Flag specifying if we should interpret all signal strength as one bar higher + * This is a replacement for the resource config_inflateSignalStrength + * The default value is false. + * @hide + */ + public static final String KEY_INFLATE_SIGNAL_STRENGTH_BOOL = + "inflate_signal_strength_bool"; + /** * Flag specifying whether an additional (client initiated) intent needs to be sent on System * update @@ -3989,6 +3998,7 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY, null); sDefaults.putBoolean(KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL, false); sDefaults.putBoolean(KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL, true); + sDefaults.putBoolean(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false); sDefaults.putBoolean(KEY_CI_ACTION_ON_SYS_UPDATE_BOOL, false); sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING, ""); sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING, ""); -- GitLab From 7dcda7d6163d44bfadd97d6c311e1a0e72dedf12 Mon Sep 17 00:00:00 2001 From: Mattias Nilsson Date: Fri, 24 Jan 2020 18:33:21 +0100 Subject: [PATCH 175/536] Remove config_inflateSignalStrength This resource has moved to CarrierConfig to support dual sim devices and MVNOs. Bug: 148483577 Test: Manual Merged-In: I494cb93a2c72ff3df2ef45ad737c5606132e32d1 Change-Id: I494cb93a2c72ff3df2ef45ad737c5606132e32d1 --- core/res/res/values-mcc310-mnc030/config.xml | 26 ------------------- core/res/res/values-mcc310-mnc070/config.xml | 26 ------------------- core/res/res/values-mcc310-mnc170/config.xml | 26 ------------------- core/res/res/values-mcc310-mnc280/config.xml | 26 ------------------- core/res/res/values-mcc310-mnc380/config.xml | 26 ------------------- core/res/res/values-mcc310-mnc410/config.xml | 4 --- core/res/res/values-mcc310-mnc560/config.xml | 26 ------------------- core/res/res/values-mcc310-mnc950/config.xml | 26 ------------------- core/res/res/values-mcc311-mnc180/config.xml | 26 ------------------- core/res/res/values-mcc311-mnc480/config.xml | 3 --- core/res/res/values/config.xml | 4 --- core/res/res/values/symbols.xml | 1 - .../telephony/CarrierConfigManager.java | 2 +- 13 files changed, 1 insertion(+), 221 deletions(-) delete mode 100644 core/res/res/values-mcc310-mnc030/config.xml delete mode 100644 core/res/res/values-mcc310-mnc070/config.xml delete mode 100644 core/res/res/values-mcc310-mnc170/config.xml delete mode 100644 core/res/res/values-mcc310-mnc280/config.xml delete mode 100644 core/res/res/values-mcc310-mnc380/config.xml delete mode 100644 core/res/res/values-mcc310-mnc560/config.xml delete mode 100644 core/res/res/values-mcc310-mnc950/config.xml delete mode 100644 core/res/res/values-mcc311-mnc180/config.xml diff --git a/core/res/res/values-mcc310-mnc030/config.xml b/core/res/res/values-mcc310-mnc030/config.xml deleted file mode 100644 index 26b9192e0cc3..000000000000 --- a/core/res/res/values-mcc310-mnc030/config.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - true - - diff --git a/core/res/res/values-mcc310-mnc070/config.xml b/core/res/res/values-mcc310-mnc070/config.xml deleted file mode 100644 index 26b9192e0cc3..000000000000 --- a/core/res/res/values-mcc310-mnc070/config.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - true - - diff --git a/core/res/res/values-mcc310-mnc170/config.xml b/core/res/res/values-mcc310-mnc170/config.xml deleted file mode 100644 index 26b9192e0cc3..000000000000 --- a/core/res/res/values-mcc310-mnc170/config.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - true - - diff --git a/core/res/res/values-mcc310-mnc280/config.xml b/core/res/res/values-mcc310-mnc280/config.xml deleted file mode 100644 index 26b9192e0cc3..000000000000 --- a/core/res/res/values-mcc310-mnc280/config.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - true - - diff --git a/core/res/res/values-mcc310-mnc380/config.xml b/core/res/res/values-mcc310-mnc380/config.xml deleted file mode 100644 index 26b9192e0cc3..000000000000 --- a/core/res/res/values-mcc310-mnc380/config.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - true - - diff --git a/core/res/res/values-mcc310-mnc410/config.xml b/core/res/res/values-mcc310-mnc410/config.xml index 53e4193c7f38..d76b9be324a6 100644 --- a/core/res/res/values-mcc310-mnc410/config.xml +++ b/core/res/res/values-mcc310-mnc410/config.xml @@ -23,8 +23,4 @@ 1410 - - - true - diff --git a/core/res/res/values-mcc310-mnc560/config.xml b/core/res/res/values-mcc310-mnc560/config.xml deleted file mode 100644 index 26b9192e0cc3..000000000000 --- a/core/res/res/values-mcc310-mnc560/config.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - true - - diff --git a/core/res/res/values-mcc310-mnc950/config.xml b/core/res/res/values-mcc310-mnc950/config.xml deleted file mode 100644 index 26b9192e0cc3..000000000000 --- a/core/res/res/values-mcc310-mnc950/config.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - true - - diff --git a/core/res/res/values-mcc311-mnc180/config.xml b/core/res/res/values-mcc311-mnc180/config.xml deleted file mode 100644 index 26b9192e0cc3..000000000000 --- a/core/res/res/values-mcc311-mnc180/config.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - true - - diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml index 336e30e45b00..db2f8d01f93a 100755 --- a/core/res/res/values-mcc311-mnc480/config.xml +++ b/core/res/res/values-mcc311-mnc480/config.xml @@ -40,7 +40,4 @@ true - - true - diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index a689f5c6a9fa..17b156155ecf 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4218,10 +4218,6 @@ only. The component must be part of a system app. --> - - false - 2000000 diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index c49588d0cdc2..b130b91b2cd2 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3826,7 +3826,6 @@ - diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index ab659440e348..56ac8fc2ca66 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1086,7 +1086,7 @@ public class CarrierConfigManager { /** * Flag specifying if we should interpret all signal strength as one bar higher - * This is a replacement for the resource config_inflateSignalStrength + * This is a replacement for the former resource config_inflateSignalStrength * The default value is false. * @hide */ -- GitLab From e88a27f8276edf4307d2947d0f11d3549e5df8a5 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Mon, 10 Aug 2020 15:25:10 -0400 Subject: [PATCH 176/536] Change description of privacy icons in Statusbar Use the more verbose description "Applications are using your..." for camera and microphone. Test: manual, TB Fixes: 163172684 Change-Id: I53dff2972a2b2315982e3ff13a88e50c7abc0063 --- .../statusbar/phone/PhoneStatusBarPolicy.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index 1ae574711866..4e71a7ea8dae 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -284,13 +284,22 @@ public class PhoneStatusBarPolicy mResources.getString(R.string.accessibility_data_saver_on)); mIconController.setIconVisibility(mSlotDataSaver, false); + // privacy items + String microphoneString = mResources.getString(PrivacyType.TYPE_MICROPHONE.getNameId()); + String microphoneDesc = mResources.getString( + R.string.ongoing_privacy_chip_content_multiple_apps, microphoneString); mIconController.setIcon(mSlotMicrophone, PrivacyType.TYPE_MICROPHONE.getIconId(), - mResources.getString(PrivacyType.TYPE_MICROPHONE.getNameId())); + microphoneDesc); mIconController.setIconVisibility(mSlotMicrophone, false); + + String cameraString = mResources.getString(PrivacyType.TYPE_CAMERA.getNameId()); + String cameraDesc = mResources.getString( + R.string.ongoing_privacy_chip_content_multiple_apps, cameraString); mIconController.setIcon(mSlotCamera, PrivacyType.TYPE_CAMERA.getIconId(), - mResources.getString(PrivacyType.TYPE_CAMERA.getNameId())); + cameraDesc); mIconController.setIconVisibility(mSlotCamera, false); + mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID, mResources.getString(R.string.accessibility_location_active)); mIconController.setIconVisibility(mSlotLocation, false); -- GitLab From e5f5be9fd24cf4fa79839172029c078f76195e52 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Mon, 10 Aug 2020 16:01:57 -0700 Subject: [PATCH 177/536] Shorten month on AOD date Test: visual Fixes: 161186825 Fixes: 163309955 Change-Id: I8e62eef0f32812380bc1d19d87d7611bd395eabb --- packages/SystemUI/res/values/donottranslate.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/res/values/donottranslate.xml b/packages/SystemUI/res/values/donottranslate.xml index a1c52e55082a..f05be066d2e2 100644 --- a/packages/SystemUI/res/values/donottranslate.xml +++ b/packages/SystemUI/res/values/donottranslate.xml @@ -21,5 +21,5 @@ @*android:string/system_ui_date_pattern - @*android:string/system_ui_date_pattern + EEEMMMd -- GitLab From e5a64d49da480f419aaf4424dda094763089d121 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Fri, 7 Aug 2020 06:39:05 +0000 Subject: [PATCH 178/536] Fix fd leak in KeepaliveTracker. The semantics of FileDescriptor in AIDL are that the callee must close the file descriptor it receives manually. Fix: 157789860 Bug: 155136951 Test: treehugger Change-Id: Ice9fc9abe2959a84ad138a95c900dff676653665 Merged-In: Ice9fc9abe2959a84ad138a95c900dff676653665 (cherry picked from commit db8ae41da255caad7640fc2c1b58d16aafb0e62b) --- .../android/server/ConnectivityService.java | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 77cd5d2ffdab..03c31a6971a8 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -220,6 +220,8 @@ import com.android.server.utils.PriorityDump; import com.google.android.collect.Lists; +import libcore.io.IoUtils; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -7519,18 +7521,34 @@ public class ConnectivityService extends IConnectivityManager.Stub public void startNattKeepaliveWithFd(Network network, FileDescriptor fd, int resourceId, int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, String dstAddr) { - mKeepaliveTracker.startNattKeepalive( - getNetworkAgentInfoForNetwork(network), fd, resourceId, - intervalSeconds, cb, - srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT); + try { + mKeepaliveTracker.startNattKeepalive( + getNetworkAgentInfoForNetwork(network), fd, resourceId, + intervalSeconds, cb, + srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT); + } finally { + // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks. + // startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately. + if (fd != null && Binder.getCallingPid() != Process.myPid()) { + IoUtils.closeQuietly(fd); + } + } } @Override public void startTcpKeepalive(Network network, FileDescriptor fd, int intervalSeconds, ISocketKeepaliveCallback cb) { - enforceKeepalivePermission(); - mKeepaliveTracker.startTcpKeepalive( - getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb); + try { + enforceKeepalivePermission(); + mKeepaliveTracker.startTcpKeepalive( + getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb); + } finally { + // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks. + // startTcpKeepalive calls Os.dup(fd) before returning, so we can close immediately. + if (fd != null && Binder.getCallingPid() != Process.myPid()) { + IoUtils.closeQuietly(fd); + } + } } @Override -- GitLab From 9c62ef63fdafcb806c0ca8486429fc44bd9454ea Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Mon, 10 Aug 2020 16:21:16 +0800 Subject: [PATCH 179/536] Resume next activity if pausing app died If the top activity is crashed before showing any window, when its process reported dead, it will be regarded as no visible activity and no need to resume next activity. That may lead to the next top activity remains in paused state and may be unresponsive. Bug: 159951007 Test: atest ActivityTaskManagerServiceTests# \ testResumeNextActivityOnCrashedAppDied Change-Id: I635fceb9cf7b782f6ffbb9ebef7cb69053f64a0b Merged-In: I635fceb9cf7b782f6ffbb9ebef7cb69053f64a0b (cherry picked from commit f2e7da7a641ae6bf2b49fa487cc56e6fe20b3336) --- .../com/android/server/wm/ActivityStack.java | 7 ++++-- .../wm/ActivityTaskManagerServiceTests.java | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index e9768a26f571..e7e08f3f68d8 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -2726,13 +2726,15 @@ class ActivityStack extends Task { /** * Reset local parameters because an app's activity died. * @param app The app of the activity that died. - * @return result from removeHistoryRecordsForAppLocked. + * @return {@code true} if the process has any visible activity. */ boolean handleAppDied(WindowProcessController app) { + boolean isPausingDied = false; if (mPausingActivity != null && mPausingActivity.app == app) { if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE, "App died while pausing: " + mPausingActivity); mPausingActivity = null; + isPausingDied = true; } if (mLastPausedActivity != null && mLastPausedActivity.app == app) { mLastPausedActivity = null; @@ -2740,7 +2742,8 @@ class ActivityStack extends Task { } mStackSupervisor.removeHistoryRecords(app); - return mRemoveHistoryRecordsForApp.process(app); + final boolean hadVisibleActivities = mRemoveHistoryRecordsForApp.process(app); + return hadVisibleActivities || isPausingDied; } boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index f65d6e0c82af..48be58f42253 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -225,5 +225,27 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase { mockSession.finishMocking(); } + + @Test + public void testResumeNextActivityOnCrashedAppDied() { + mSupervisor.beginDeferResume(); + final ActivityRecord homeActivity = new ActivityBuilder(mService) + .setTask(mRootWindowContainer.getDefaultTaskDisplayArea().getOrCreateRootHomeTask()) + .build(); + final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true).build(); + mSupervisor.endDeferResume(); + // Assume the activity is finishing and hidden because it was crashed. + activity.finishing = true; + activity.mVisibleRequested = false; + activity.setVisible(false); + activity.getRootTask().mPausingActivity = activity; + homeActivity.setState(ActivityStack.ActivityState.PAUSED, "test"); + + // Even the visibility states are invisible, the next activity should be resumed because + // the crashed activity was pausing. + mService.mInternal.handleAppDied(activity.app, false /* restarting */, + null /* finishInstrumentationCallback */); + assertEquals(ActivityStack.ActivityState.RESUMED, homeActivity.getState()); + } } -- GitLab From 9b0a74f0a3ae653954f432bf8892533aa2522015 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Tue, 11 Aug 2020 12:54:40 +0100 Subject: [PATCH 180/536] Revert "Add bp-based disting of android stubs" This reverts commit d116c6038365732a22de293ad8440e808b0f2f3e. Bug: 162595755 Test: unzip -l out/dist/android_system.jar | grep resources.arsc Change-Id: I1445bc742ea2f895291ffd80bdc0cf86e1b8878a --- StubLibraries.bp | 49 +++------------------------------------------ services/Android.bp | 4 ---- 2 files changed, 3 insertions(+), 50 deletions(-) diff --git a/StubLibraries.bp b/StubLibraries.bp index 6b989951d331..a9e6e5af47f1 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -311,15 +311,6 @@ java_defaults { compile_dex: true, } -java_defaults { - name: "android_stubs_dists_default", - dist: { - targets: ["sdk", "win_sdk"], - tag: ".jar", - dest: "android.jar", - }, -} - java_library_static { name: "android_monolith_stubs_current", srcs: [ ":api-stubs-docs" ], @@ -354,21 +345,7 @@ java_library_static { name: "android_system_monolith_stubs_current", srcs: [ ":system-api-stubs-docs" ], static_libs: [ "private-stub-annotations-jar" ], - defaults: [ - "android_defaults_stubs_current", - "android_stubs_dists_default", - ], - dist: { - dir: "apistubs/android/system", - }, - dists: [ - { - // Legacy dist path - targets: ["sdk", "win_sdk"], - tag: ".jar", - dest: "android_system.jar", - }, - ], + defaults: ["android_defaults_stubs_current"], } java_library_static { @@ -398,34 +375,14 @@ java_library_static { name: "android_test_stubs_current", srcs: [ ":test-api-stubs-docs" ], static_libs: [ "private-stub-annotations-jar" ], - defaults: [ - "android_defaults_stubs_current", - "android_stubs_dists_default", - ], - dist: { - dir: "apistubs/android/test", - }, - dists: [ - { - // Legacy dist path - targets: ["sdk", "win_sdk"], - tag: ".jar", - dest: "android_test.jar", - }, - ], + defaults: ["android_defaults_stubs_current"], } java_library_static { name: "android_module_lib_stubs_current", srcs: [ ":module-lib-api-stubs-docs-non-updatable" ], - defaults: [ - "android_defaults_stubs_current", - "android_stubs_dists_default", - ], + defaults: ["android_defaults_stubs_current"], libs: ["sdk_system_29_android"], - dist: { - dir: "apistubs/android/module-lib", - }, } java_library_static { diff --git a/services/Android.bp b/services/Android.bp index f0144ac1c695..40b925de95d6 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -154,14 +154,10 @@ droidstubs { java_library { name: "android_system_server_stubs_current", - defaults: ["android_stubs_dists_default"], srcs: [":services-stubs.sources"], installable: false, static_libs: ["android_module_lib_stubs_current"], sdk_version: "none", system_modules: "none", java_version: "1.8", - dist: { - dir: "apistubs/android/system-server", - }, } -- GitLab From 6bb575bab19a8ab9be05a1942283010e944d923c Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Mon, 6 Jul 2020 14:16:29 -0400 Subject: [PATCH 181/536] Make screenshot process unbind correctly There's a bug in ScreenshotHelper that causes the process not to unbind properly. Now that the screenshot connection is kept track of by the class, we don't need to compare its value at the beginning and end of the started service before closing the connection. This also fixes an issue where screenshots didn't work right, immediately after switching users (since the process is now closed correctly, a new one can begin for the secondary user). Bug: 158303623 Bug: 160355802 Fix: 158303623 Fix: 160355802 Test: manual; tested single screenshots and multiple in succession; made sure that after switching users screenshots could be taken immediately. Change-Id: Idf25c6a60bdde8ab970c4af68884de798159ef3f --- core/java/com/android/internal/util/ScreenshotHelper.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java index 9bf05135c4c5..a23fc4b57b45 100644 --- a/core/java/com/android/internal/util/ScreenshotHelper.java +++ b/core/java/com/android/internal/util/ScreenshotHelper.java @@ -291,7 +291,7 @@ public class ScreenshotHelper { }; Message msg = Message.obtain(null, screenshotType, screenshotRequest); - final ServiceConnection myConn = mScreenshotConnection; + Handler h = new Handler(handler.getLooper()) { @Override public void handleMessage(Message msg) { @@ -304,8 +304,8 @@ public class ScreenshotHelper { break; case SCREENSHOT_MSG_PROCESS_COMPLETE: synchronized (mScreenshotLock) { - if (myConn != null && mScreenshotConnection == myConn) { - mContext.unbindService(myConn); + if (mScreenshotConnection != null) { + mContext.unbindService(mScreenshotConnection); mScreenshotConnection = null; mScreenshotService = null; } @@ -368,6 +368,7 @@ public class ScreenshotHelper { } } else { Messenger messenger = new Messenger(mScreenshotService); + try { messenger.send(msg); } catch (RemoteException e) { -- GitLab From ad19ed2577d6eae4891b10e8c2baf569ffe142b5 Mon Sep 17 00:00:00 2001 From: Bradley Allen Date: Mon, 10 Aug 2020 22:14:30 +0000 Subject: [PATCH 182/536] docs: Adjusted language to avoid gender-specific terminology. Test: none (docs-only change) Bug: 151156981 Change-Id: I8f06796b2828695f62bf32c033e5406bc3d858ad --- core/res/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 9945057f0e94..d0ca0a86efb0 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1340,7 +1340,7 @@ android:priority="800" /> Date: Mon, 10 Aug 2020 16:01:57 -0700 Subject: [PATCH 183/536] Shorten month on AOD date Test: visual Fixes: 161186825 Fixes: 163309955 Change-Id: I8e62eef0f32812380bc1d19d87d7611bd395eabb (cherry picked from commit e5f5be9fd24cf4fa79839172029c078f76195e52) --- packages/SystemUI/res/values/donottranslate.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/res/values/donottranslate.xml b/packages/SystemUI/res/values/donottranslate.xml index a1c52e55082a..f05be066d2e2 100644 --- a/packages/SystemUI/res/values/donottranslate.xml +++ b/packages/SystemUI/res/values/donottranslate.xml @@ -21,5 +21,5 @@ @*android:string/system_ui_date_pattern - @*android:string/system_ui_date_pattern + EEEMMMd -- GitLab From 462481663cbb012c8d6ecc8ba6a243862509ba54 Mon Sep 17 00:00:00 2001 From: Bradley Allen Date: Mon, 10 Aug 2020 23:16:42 +0000 Subject: [PATCH 184/536] docs: Removed Q preview language and added a link to the Android 10 page on developer.android.com. Test: http://go/forrest-run/L62500000661914456 Bug: 149267624 Change-Id: I73b92cf0af8f78117448db9a89d7685f45bc512d --- core/java/android/os/Build.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index b36aeb89c02a..49a1cb588a3e 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -1006,10 +1006,16 @@ public class Build { /** * Q. - *

- * Why? Why, to give you a taste of your future, a preview of things - * to come. Con permiso, Capitan. The hall is rented, the orchestra - * engaged. It's now time to see if you can dance. + * + *

Applications targeting this or a later release will get these new changes in behavior. + * For more information about this release, see the + * Android 10 overview.

+ * + * */ public static final int Q = 29; -- GitLab From b56228e0c024b604c9e428e4e2b882c5b0ca2bfd Mon Sep 17 00:00:00 2001 From: Anthony Hugh Date: Tue, 4 Aug 2020 14:52:03 -0700 Subject: [PATCH 185/536] Update PermissionManagerService to handle pre-created users Pre-created users are not being returned by the call to UserManagerService.getUserIds(). This is causing PermissionManager to ignore recording pre-grants when a new pre-created user is created. This CL fixes the issue by using a user ID set that contians pre-created users. Presumably the call to getUserIds() was previously done for performance reasons. I have added some system tracing to see if performance is a bottle neck here with the new API call. I ran the test 5 times on an automotive emulator: [1] Start system trace [2] adb shell pm -create-user --pre-create-only [3] Stop system trace Average time to getUsers() before changes: .389ms Average time to getUsers() after changes: 1.82ms Given that this is an infrequent operation and less than 5ms change, performance hit looks negligible. Bug: b/160901158 Test: Manually. Run `adb shell pm -create-user --pre-create-only`. Create a new user and check to see that Assistant has pre-granted permissions via `adb shell dumpsys package com.google.android.carassistant` Change-Id: I52caeb3a71e560d09fcbc167b46becebf779fc3a Merged-In: I52caeb3a71e560d09fcbc167b46becebf779fc3a (cherry picked from commit 432a0377250246632927252c9d2b92411717be52) --- .../permission/PermissionManagerService.java | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index bc7554c54eb0..a4e8b1c01620 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -83,6 +83,7 @@ import android.content.pm.PackageParser; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; +import android.content.pm.UserInfo; import android.content.pm.parsing.component.ParsedPermission; import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.permission.SplitPermissionInfoParcelable; @@ -120,6 +121,7 @@ import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; +import android.util.TimingsTraceLog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -2516,12 +2518,12 @@ public class PermissionManagerService extends IPermissionManager.Stub { final PermissionsState permissionsState = ps.getPermissionsState(); - final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); + final int[] userIds = getAllUserIds(); boolean runtimePermissionsRevoked = false; int[] updatedUserIds = EMPTY_INT_ARRAY; - for (int userId : currentUserIds) { + for (int userId : userIds) { if (permissionsState.isMissing(userId)) { Collection requestedPermissions; int targetSdkVersion; @@ -2587,7 +2589,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { // runtime and revocation of a runtime from a shared user. synchronized (mLock) { updatedUserIds = revokeUnusedSharedUserPermissionsLocked( - ps.getSharedUser(), UserManagerService.getInstance().getUserIds()); + ps.getSharedUser(), userIds); if (!ArrayUtils.isEmpty(updatedUserIds)) { runtimePermissionsRevoked = true; } @@ -2740,7 +2742,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { // a runtime permission being downgraded to an install one. // Also in permission review mode we keep dangerous permissions // for legacy apps - for (int userId : UserManagerService.getInstance().getUserIds()) { + for (int userId : userIds) { if (origPermissions.getRuntimePermissionState( perm, userId) != null) { // Revoke the runtime permission and clear the flags. @@ -2763,7 +2765,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { boolean hardRestricted = bp.isHardRestricted(); boolean softRestricted = bp.isSoftRestricted(); - for (int userId : currentUserIds) { + for (int userId : userIds) { // If permission policy is not ready we don't deal with restricted // permissions as the policy may whitelist some permissions. Once // the policy is initialized we would re-evaluate permissions. @@ -2902,7 +2904,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { boolean hardRestricted = bp.isHardRestricted(); boolean softRestricted = bp.isSoftRestricted(); - for (int userId : currentUserIds) { + for (int userId : userIds) { // If permission policy is not ready we don't deal with restricted // permissions as the policy may whitelist some permissions. Once // the policy is initialized we would re-evaluate permissions. @@ -3070,6 +3072,25 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } + /** + * Returns all relevant user ids. This list include the current set of created user ids as well + * as pre-created user ids. + * @return user ids for created users and pre-created users + */ + private int[] getAllUserIds() { + final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER); + t.traceBegin("getAllUserIds"); + List users = UserManagerService.getInstance().getUsers( + /*excludePartial=*/ true, /*excludeDying=*/ true, /*excludePreCreated=*/ false); + int size = users.size(); + final int[] userIds = new int[size]; + for (int i = 0; i < size; i++) { + userIds[i] = users.get(i).id; + } + t.traceEnd(); + return userIds; + } + /** * Revoke permissions that are not implicit anymore and that have * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set. @@ -3088,7 +3109,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { boolean supportsRuntimePermissions = pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M; - int[] users = UserManagerService.getInstance().getUserIds(); + int[] users = getAllUserIds(); int numUsers = users.length; for (int i = 0; i < numUsers; i++) { int userId = users[i]; @@ -3197,7 +3218,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (replace && pkg.isRequestLegacyExternalStorage() && ( pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE) || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) { - return UserManagerService.getInstance().getUserIds(); + return getAllUserIds(); } return updatedUserIds; @@ -3251,7 +3272,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (!ps.hasInstallPermission(newPerm)) { BasePermission bp = mSettings.getPermissionLocked(newPerm); - int[] users = UserManagerService.getInstance().getUserIds(); + int[] users = getAllUserIds(); int numUsers = users.length; for (int userNum = 0; userNum < numUsers; userNum++) { int userId = users[userNum]; -- GitLab From 9334f7aba717ec75416682b59dffbc88422ee262 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Fri, 7 Aug 2020 17:59:02 -0700 Subject: [PATCH 186/536] Do not log package name on privacy-indicator logs as requested by privacy review. Bug: 162547999 Test: Built Change-Id: I9333facfdc39cc7a344c5671f487928977f5d82e --- cmds/statsd/src/atoms.proto | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 36b46c3d03a3..7d0d97917a4b 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -4420,15 +4420,12 @@ message PrivacyIndicatorsInteracted { UNKNOWN = 0; CHIP_VIEWED = 1; CHIP_CLICKED = 2; - DIALOG_PRIVACY_SETTINGS = 3; + reserved 3; // Used only in beta builds, never shipped DIALOG_DISMISS = 4; DIALOG_LINE_ITEM = 5; } optional Type type = 1 [(state_field_option).exclusive_state = true]; - - // Used if the type is LINE_ITEM - optional string package_name = 2; } /** -- GitLab From 070b491882d297b84177904620c4ea28e3f9c72a Mon Sep 17 00:00:00 2001 From: Nate Myren Date: Tue, 11 Aug 2020 15:56:21 -0700 Subject: [PATCH 187/536] Add changeId to gate R-QPR tests behind Bug: 162551686 Test: none Change-Id: I6df669785db4d4684b8207fa7234d4793d652cb3 --- .../permission/PermissionControllerService.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java index 8ad35e7eb37d..e2e61406ba95 100644 --- a/core/java/android/permission/PermissionControllerService.java +++ b/core/java/android/permission/PermissionControllerService.java @@ -35,6 +35,8 @@ import android.annotation.NonNull; import android.annotation.SystemApi; import android.app.Service; import android.app.admin.DevicePolicyManager.PermissionGrantState; +import android.compat.annotation.ChangeId; +import android.compat.annotation.Disabled; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -82,6 +84,15 @@ public abstract class PermissionControllerService extends Service { */ public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService"; + /** + * A ChangeId indicating that this device supports camera and mic indicators. Will be "false" + * if present, because the CompatChanges#isChangeEnabled method returns true if the change id + * is not present. + */ + @ChangeId + @Disabled + private static final long CAMERA_MIC_INDICATORS_NOT_PRESENT = 162547999L; + /** * Revoke a set of runtime permissions for various apps. * -- GitLab From d75a22bc20675e478b8d230b3db3ab69eb91d9f2 Mon Sep 17 00:00:00 2001 From: junyulai Date: Fri, 7 Aug 2020 23:27:08 +0800 Subject: [PATCH 188/536] Add 5G NSA to collapsed RAT types list Currently, getAllCollapsedRatTypes is used to retrieve all RAT types which will be recorded into NetworkStatsService. However, there is a missing part that 5G NSA virtual RAT type is not added into this list. This makes callers such as statsd do not aware of 5G NSA RAT type and missed to collect data usage of it. Test: atest NetworkStatsSubscriptionsMonitorTest#test5g Test: adb shell cmd stats pull-source 10082 Test: ./out/host/linux-x86/bin/statsd_testdrive 10082 Test: atest UidAtomTests#testMobileBytesTransfer \ UidAtomTests#testMobileBytesTransferByFgBg \ UidAtomTests#testDataUsageBytesTransfer Bug: 163021464 Change-Id: I0faeda20f0506a48ac1131b234c5fc40d95dfbe0 Merged-In: I0faeda20f0506a48ac1131b234c5fc40d95dfbe0 --- core/java/android/net/NetworkTemplate.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index 7234eb1d81cd..cd26079a7bac 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -503,6 +503,10 @@ public class NetworkTemplate implements Parcelable { for (final int ratType : ratTypes) { collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(ratType)); } + // Add NETWORK_TYPE_5G_NSA to the returned list since 5G NSA is a virtual RAT type and + // it is not in TelephonyManager#NETWORK_TYPE_* constants. + // See {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}. + collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(NETWORK_TYPE_5G_NSA)); // Ensure that unknown type is returned. collapsedRatTypes.add(TelephonyManager.NETWORK_TYPE_UNKNOWN); return toIntArray(collapsedRatTypes); -- GitLab From 3fbdd17f4582232568076a79bbe3793c19a9b605 Mon Sep 17 00:00:00 2001 From: Beverly Date: Wed, 12 Aug 2020 08:33:54 -0400 Subject: [PATCH 189/536] No vibrate on initial ringer setting Don't vibrate the device when the initial ringer state is set (ie: mState.ringerModeInternal = -1) Fixes: 160919337 Test: manual 1. Set ringer to vibrate 2. Restart device 3. Observe: when device boots up, no vibration from ringer Change-Id: Id9bcc00731ac166c104d9fd8aa9fa02c70cad70f --- .../src/com/android/systemui/volume/VolumeDialogImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index 3455ff47de8d..6fe11ed1792b 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -935,6 +935,7 @@ public class VolumeDialogImpl implements VolumeDialog, protected void onStateChangedH(State state) { if (D.BUG) Log.d(TAG, "onStateChangedH() state: " + state.toString()); if (mState != null && state != null + && mState.ringerModeInternal != -1 && mState.ringerModeInternal != state.ringerModeInternal && state.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE) { mController.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK)); -- GitLab From 240dd7347b964dee7f7a665b79a3037ba1d5969b Mon Sep 17 00:00:00 2001 From: Weijie Wang Date: Tue, 26 May 2020 16:21:05 +0800 Subject: [PATCH 190/536] SystemUI: Reset PUK StateMachine after PUK is unlocked The PUK state is DONE in StateMachine after PUK is unlocked. If two sim cards are both locked by PUK, the PUK state should be ENTER_PUK after SIM1 PUK is unlocked. Bug: 155135725 Test: manual Change-Id: I0261d8be913a878e65c5240d4d39b248c2e3a5d5 Merged-In: I0261d8be913a878e65c5240d4d39b248c2e3a5d5 (cherry picked from commit 8e9417e87366aecd1c03cca8f8f45c8d2f6cae62) --- .../SystemUI/src/com/android/keyguard/KeyguardSimPukView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java index 10dcbd6f9182..a84664ceee3d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java @@ -448,8 +448,8 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView { if (DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock " + " UpdateSim.onSimCheckResponse: " + " attemptsRemaining=" + result.getAttemptsRemaining()); - mStateMachine.reset(); } + mStateMachine.reset(); mCheckSimPukThread = null; } }); -- GitLab From ef1f570a236edc286b533dbfa4b979c42d183fc9 Mon Sep 17 00:00:00 2001 From: Nate Myren Date: Tue, 11 Aug 2020 17:14:17 -0700 Subject: [PATCH 191/536] Run user sensitive 60 seconds after boot Always update user sensitive permissions on boot, 60 seconds after the PermissionPolicyService starts Bug: 162547999 Test: view logs Change-Id: I29987fc891e3dcd657fb692bc0c065c4699ad9b3 --- .../android/server/policy/PermissionPolicyService.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java index 37f088b170eb..9dd9236c155b 100644 --- a/services/core/java/com/android/server/policy/PermissionPolicyService.java +++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java @@ -88,7 +88,7 @@ import java.util.concurrent.ExecutionException; public final class PermissionPolicyService extends SystemService { private static final String LOG_TAG = PermissionPolicyService.class.getSimpleName(); private static final boolean DEBUG = false; - private static final long USER_SENSITIVE_UPDATE_DELAY_MS = 10000; + private static final long USER_SENSITIVE_UPDATE_DELAY_MS = 60000; private final Object mLock = new Object(); @@ -282,6 +282,11 @@ public final class PermissionPolicyService extends SystemService { manager.updateUserSensitiveForApp(uid); } }, UserHandle.ALL, intentFilter, null, null); + + PermissionControllerManager manager = new PermissionControllerManager( + getUserContext(getContext(), Process.myUserHandle()), FgThread.getHandler()); + FgThread.getHandler().postDelayed(manager::updateUserSensitive, + USER_SENSITIVE_UPDATE_DELAY_MS); } /** @@ -420,8 +425,7 @@ public final class PermissionPolicyService extends SystemService { throw new IllegalStateException(e); } - FgThread.getHandler().postDelayed(permissionControllerManager::updateUserSensitive, - USER_SENSITIVE_UPDATE_DELAY_MS); + permissionControllerManager.updateUserSensitive(); packageManagerInternal.updateRuntimePermissionsFingerprint(userId); } -- GitLab From 41cc05cd4d84be353b7bcf193b82f5c97cf0437f Mon Sep 17 00:00:00 2001 From: Jeffrey Carlyle Date: Tue, 24 Mar 2020 01:13:59 -0700 Subject: [PATCH 192/536] allow KeyguardIndicationController to be more easily overriden Bug: 150239363 Test: overrode computePowerIndication with custom version Signed-off-by: Jeffrey Carlyle Change-Id: Iccbeaa527014abc00107ea1165f93330d80c3791 Merged-In: Iccbeaa527014abc00107ea1165f93330d80c3791 --- .../systemui/statusbar/KeyguardIndicationController.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index a1444532bd5e..7e1dc6634cec 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -140,7 +140,7 @@ public class KeyguardIndicationController implements StateListener, * Creates a new KeyguardIndicationController and registers callbacks. */ @Inject - KeyguardIndicationController(Context context, + public KeyguardIndicationController(Context context, WakeLock.Builder wakeLockBuilder, KeyguardStateController keyguardStateController, StatusBarStateController statusBarStateController, @@ -523,8 +523,7 @@ public class KeyguardIndicationController implements StateListener, }); } - @VisibleForTesting - String computePowerIndication() { + protected String computePowerIndication() { if (mPowerCharged) { return mContext.getResources().getString(R.string.keyguard_charged); } -- GitLab From c527eed1235d0fa81286e08d857e5b31a7d265c8 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Wed, 15 Jul 2020 18:30:49 -0700 Subject: [PATCH 193/536] [Passpoint] Changes to Unique ID Modify Unique ID calculation to use only FQDN for HomeSP hash and modify the hash of the Credential to produce an identical hash for user credential changes, except for username which will result in a different hash, and generate a different hash for SIM credential, Cert credential and realm changes. The result would allow multiple profiles with SIM credential or Cert credential for the same network and overwrite profiles with updates to the user credentials with changes other than the username. Bug: 161008339 Test: atest com.android.server.wifi Test: atest PasspointConfigurationTest CredentialTest Test: Install an OSU profile, then install R1 profile for the same network (HomeSP has a different friendly name), verify the OSU profile has been overwritten Change-Id: Ice11158078b5b86c721747b0d67ecfb09731a3c5 Merged-In: Ice11158078b5b86c721747b0d67ecfb09731a3c5 --- .../net/wifi/hotspot2/pps/Credential.java | 13 +- .../android/net/wifi/hotspot2/pps/HomeSp.java | 4 +- wifi/tests/src/android/net/wifi/FakeKeys.java | 29 +++ .../hotspot2/PasspointConfigurationTest.java | 192 +++++++++++++++++- .../net/wifi/hotspot2/pps/CredentialTest.java | 23 ++- 5 files changed, 247 insertions(+), 14 deletions(-) diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java index fa806e7797cd..282757ac5a14 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java @@ -448,6 +448,16 @@ public final class Credential implements Parcelable { return new UserCredential[size]; } }; + + /** + * Get a unique identifier for UserCredential. + * + * @hide + * @return a Unique identifier for a UserCredential object + */ + public int getUniqueId() { + return Objects.hash(mUsername); + } } private UserCredential mUserCredential = null; /** @@ -1037,7 +1047,8 @@ public final class Credential implements Parcelable { * @return a Unique identifier for a Credential object */ public int getUniqueId() { - return Objects.hash(mUserCredential, mCertCredential, mSimCredential, mRealm); + return Objects.hash(mUserCredential != null ? mUserCredential.getUniqueId() : 0, + mCertCredential, mSimCredential, mRealm); } @Override diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java index 224c4bed9d5b..8f34579f6a5d 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java @@ -313,9 +313,7 @@ public final class HomeSp implements Parcelable { * @return a Unique identifier for a HomeSp object */ public int getUniqueId() { - return Objects.hash(mFqdn, mFriendlyName, mHomeNetworkIds, Arrays.hashCode(mMatchAllOis), - Arrays.hashCode(mMatchAnyOis), Arrays.hashCode(mOtherHomePartners), - Arrays.hashCode(mRoamingConsortiumOis)); + return Objects.hash(mFqdn); } diff --git a/wifi/tests/src/android/net/wifi/FakeKeys.java b/wifi/tests/src/android/net/wifi/FakeKeys.java index c0d60c33f99c..641b891a1f4d 100644 --- a/wifi/tests/src/android/net/wifi/FakeKeys.java +++ b/wifi/tests/src/android/net/wifi/FakeKeys.java @@ -214,6 +214,35 @@ public class FakeKeys { }; public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1); + private static final String CLIENT_SUITE_B_RSA3072_CERT_STRING = + "-----BEGIN CERTIFICATE-----\n" + + "MIIERzCCAq8CFDopjyNgaj+c2TN2k06h7okEWpHJMA0GCSqGSIb3DQEBDAUAMF4x\n" + + "CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQK\n" + + "DAdBbmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4X\n" + + "DTIwMDcyMTAyMjkxMVoXDTMwMDUzMDAyMjkxMVowYjELMAkGA1UEBhMCVVMxCzAJ\n" + + "BgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNV\n" + + "BAsMBVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MIIBojANBgkqhkiG9w0B\n" + + "AQEFAAOCAY8AMIIBigKCAYEAwSK3C5K5udtCKTnE14e8z2cZvwmB4Xe+a8+7QLud\n" + + "Hooc/lQzClgK4MbVUC0D3FE+U32C78SxKoTaRWtvPmNm+UaFT8KkwyUno/dv+2XD\n" + + "pd/zARQ+3FwAfWopAhEyCVSxwsCa+slQ4juRIMIuUC1Mm0NaptZyM3Tj/ICQEfpk\n" + + "o9qVIbiK6eoJMTkY8EWfAn7RTFdfR1OLuO0mVOjgLW9/+upYv6hZ19nAMAxw4QTJ\n" + + "x7lLwALX7B+tDYNEZHDqYL2zyvQWAj2HClere8QYILxkvktgBg2crEJJe4XbDH7L\n" + + "A3rrXmsiqf1ZbfFFEzK9NFqovL+qGh+zIP+588ShJFO9H/RDnDpiTnAFTWXQdTwg\n" + + "szSS0Vw2PB+JqEABAa9DeMvXT1Oy+NY3ItPHyy63nQZVI2rXANw4NhwS0Z6DF+Qs\n" + + "TNrj+GU7e4SG/EGR8SvldjYfQTWFLg1l/UT1hOOkQZwdsaW1zgKyeuiFB2KdMmbA\n" + + "Sq+Ux1L1KICo0IglwWcB/8nnAgMBAAEwDQYJKoZIhvcNAQEMBQADggGBAMYwJkNw\n" + + "BaCviKFmReDTMwWPRy4AMNViEeqAXgERwDEKwM7efjsaj5gctWfKsxX6UdLzkhgg\n" + + "6S/T6PxVWKzJ6l7SoOuTa6tMQOZp+h3R1mdfEQbw8B5cXBxZ+batzAai6Fiy1FKS\n" + + "/ka3INbcGfYuIYghfTrb4/NJKN06ZaQ1bpPwq0e4gN7800T2nbawvSf7r+8ZLcG3\n" + + "6bGCjRMwDSIipNvOwoj3TG315XC7TccX5difQ4sKOY+d2MkVJ3RiO0Ciw2ZbEW8d\n" + + "1FH5vUQJWnBUfSFznosGzLwH3iWfqlP+27jNE+qB2igEwCRFgVAouURx5ou43xuX\n" + + "qf6JkdI3HTJGLIWxkp7gOeln4dEaYzKjYw+P0VqJvKVqQ0IXiLjHgE0J9p0vgyD6\n" + + "HVVcP7U8RgqrbIjL1QgHU4KBhGi+WSUh/mRplUCNvHgcYdcHi/gHpj/j6ubwqIGV\n" + + "z4iSolAHYTmBWcLyE0NgpzE6ntp+53r2KaUJA99l2iGVzbWTwqPSm0XAVw==\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CLIENT_SUITE_B_RSA3072_CERT = + loadCertificate(CLIENT_SUITE_B_RSA3072_CERT_STRING); + private static X509Certificate loadCertificate(String blob) { try { final CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index 638efb9f14ee..8270d643ca65 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -23,6 +23,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; +import android.net.wifi.EAPConstants; +import android.net.wifi.FakeKeys; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSp; import android.os.Parcel; @@ -32,6 +34,11 @@ import androidx.test.filters.SmallTest; import org.junit.Test; import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -383,19 +390,39 @@ public class PasspointConfigurationTest { } /** - * Verify that the unique identifier generated is different for two instances with different - * HomeSp node + * Verify that the unique identifier generated is the same for two instances with different + * HomeSp node but same FQDN * * @throws Exception */ @Test - public void validateUniqueIdDifferentHomeSp() throws Exception { + public void validateUniqueIdDifferentHomeSpSameFqdn() throws Exception { PasspointConfiguration config1 = PasspointTestUtils.createConfig(); - // Modify config2's RCOIs to a different set of values + // Modify config2's RCOIs and friendly name to a different set of values PasspointConfiguration config2 = PasspointTestUtils.createConfig(); HomeSp homeSp = config2.getHomeSp(); homeSp.setRoamingConsortiumOis(new long[] {0xaa, 0xbb}); + homeSp.setFriendlyName("Some other name"); + config2.setHomeSp(homeSp); + + assertEquals(config1.getUniqueId(), config2.getUniqueId()); + } + + /** + * Verify that the unique identifier generated is different for two instances with the same + * HomeSp node but different FQDN + * + * @throws Exception + */ + @Test + public void validateUniqueIdSameHomeSpDifferentFqdn() throws Exception { + PasspointConfiguration config1 = PasspointTestUtils.createConfig(); + + // Modify config2's FQDN to a different value + PasspointConfiguration config2 = PasspointTestUtils.createConfig(); + HomeSp homeSp = config2.getHomeSp(); + homeSp.setFqdn("fqdn2.com"); config2.setHomeSp(homeSp); assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); @@ -403,15 +430,15 @@ public class PasspointConfigurationTest { /** * Verify that the unique identifier generated is different for two instances with different - * Credential node + * SIM Credential node * * @throws Exception */ @Test - public void validateUniqueIdDifferentCredential() throws Exception { + public void validateUniqueIdDifferentSimCredential() throws Exception { PasspointConfiguration config1 = PasspointTestUtils.createConfig(); - // Modify config2's RCOIs to a different set of values + // Modify config2's realm and SIM credential to a different set of values PasspointConfiguration config2 = PasspointTestUtils.createConfig(); Credential credential = config2.getCredential(); credential.setRealm("realm2.example.com"); @@ -421,6 +448,157 @@ public class PasspointConfigurationTest { assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); } + /** + * Verify that the unique identifier generated is different for two instances with different + * Realm in the Credential node + * + * @throws Exception + */ + @Test + public void validateUniqueIdDifferentRealm() throws Exception { + PasspointConfiguration config1 = PasspointTestUtils.createConfig(); + + // Modify config2's realm to a different set of values + PasspointConfiguration config2 = PasspointTestUtils.createConfig(); + Credential credential = config2.getCredential(); + credential.setRealm("realm2.example.com"); + config2.setCredential(credential); + + assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); + } + + /** + * Verify that the unique identifier generated is the same for two instances with different + * password and same username in the User Credential node + * + * @throws Exception + */ + @Test + public void validateUniqueIdSameUserInUserCredential() throws Exception { + PasspointConfiguration config1 = PasspointTestUtils.createConfig(); + Credential credential = createCredentialWithUserCredential("user", "passwd"); + config1.setCredential(credential); + + // Modify config2's Passpowrd to a different set of values + PasspointConfiguration config2 = PasspointTestUtils.createConfig(); + credential = createCredentialWithUserCredential("user", "newpasswd"); + config2.setCredential(credential); + + assertEquals(config1.getUniqueId(), config2.getUniqueId()); + } + + /** + * Verify that the unique identifier generated is different for two instances with different + * username in the User Credential node + * + * @throws Exception + */ + @Test + public void validateUniqueIdDifferentUserCredential() throws Exception { + PasspointConfiguration config1 = PasspointTestUtils.createConfig(); + Credential credential = createCredentialWithUserCredential("user", "passwd"); + config1.setCredential(credential); + + // Modify config2's username to a different value + PasspointConfiguration config2 = PasspointTestUtils.createConfig(); + credential = createCredentialWithUserCredential("user2", "passwd"); + config2.setCredential(credential); + + assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); + } + + /** + * Verify that the unique identifier generated is different for two instances with different + * Cert Credential node + * + * @throws Exception + */ + @Test + public void validateUniqueIdDifferentCertCredential() throws Exception { + PasspointConfiguration config1 = PasspointTestUtils.createConfig(); + Credential credential = createCredentialWithCertificateCredential(true, true); + config1.setCredential(credential); + + // Modify config2's cert credential to a different set of values + PasspointConfiguration config2 = PasspointTestUtils.createConfig(); + credential = createCredentialWithCertificateCredential(false, false); + config2.setCredential(credential); + + assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); + } + + /** + * Helper function for generating certificate credential for testing. + * + * @return {@link Credential} + */ + private static Credential createCredentialWithCertificateCredential(Boolean useCaCert0, + Boolean useCert0) + throws NoSuchAlgorithmException, CertificateEncodingException { + Credential.CertificateCredential certCred = new Credential.CertificateCredential(); + certCred.setCertType("x509v3"); + if (useCert0) { + certCred.setCertSha256Fingerprint( + MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded())); + } else { + certCred.setCertSha256Fingerprint(MessageDigest.getInstance("SHA-256") + .digest(FakeKeys.CLIENT_SUITE_B_RSA3072_CERT.getEncoded())); + } + return createCredential(null, certCred, null, new X509Certificate[] {FakeKeys.CLIENT_CERT}, + FakeKeys.RSA_KEY1, useCaCert0 ? FakeKeys.CA_CERT0 : FakeKeys.CA_CERT1); + } + + /** + * Helper function for generating user credential for testing. + * + * @return {@link Credential} + */ + private static Credential createCredentialWithUserCredential(String username, String password) { + Credential.UserCredential userCred = new Credential.UserCredential(); + userCred.setUsername(username); + userCred.setPassword(password); + userCred.setMachineManaged(true); + userCred.setAbleToShare(true); + userCred.setSoftTokenApp("TestApp"); + userCred.setEapType(EAPConstants.EAP_TTLS); + userCred.setNonEapInnerMethod("MS-CHAP"); + return createCredential(userCred, null, null, null, null, FakeKeys.CA_CERT0); + } + + /** + * Helper function for generating Credential for testing. + * + * @param userCred Instance of UserCredential + * @param certCred Instance of CertificateCredential + * @param simCred Instance of SimCredential + * @param clientCertificateChain Chain of client certificates + * @param clientPrivateKey Client private key + * @param caCerts CA certificates + * @return {@link Credential} + */ + private static Credential createCredential(Credential.UserCredential userCred, + Credential.CertificateCredential certCred, + Credential.SimCredential simCred, + X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey, + X509Certificate... caCerts) { + Credential cred = new Credential(); + cred.setCreationTimeInMillis(123455L); + cred.setExpirationTimeInMillis(2310093L); + cred.setRealm("realm"); + cred.setCheckAaaServerCertStatus(true); + cred.setUserCredential(userCred); + cred.setCertCredential(certCred); + cred.setSimCredential(simCred); + if (caCerts != null && caCerts.length == 1) { + cred.setCaCertificate(caCerts[0]); + } else { + cred.setCaCertificates(caCerts); + } + cred.setClientCertificateChain(clientCertificateChain); + cred.setClientPrivateKey(clientPrivateKey); + return cred; + } + /** * Verify that the unique identifier API generates an exception if HomeSP is not initialized. * diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java index 829d8f0a9a3a..a44df40a8e97 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java @@ -593,10 +593,10 @@ public class CredentialTest { } /** - * Verify that unique identifiers are different for a credential with different values + * Verify that unique identifiers are different for a credential with different username */ @Test - public void testUniqueIdDifferentForUserCredentialsWithDifferentValues() throws Exception { + public void testUniqueIdDifferentForUserCredentialsWithDifferentUsername() throws Exception { Credential userCred1 = createCredentialWithUserCredential(); Credential userCred2 = createCredentialWithUserCredential(); userCred2.getUserCredential().setUsername("anotheruser"); @@ -605,7 +605,24 @@ public class CredentialTest { } /** - * Verify that unique identifiers are different for a credential with different values + * Verify that unique identifiers are different for a credential with different password and + * other values other than username + */ + @Test + public void testUniqueIdSameForUserCredentialsWithDifferentPassword() throws Exception { + Credential userCred1 = createCredentialWithUserCredential(); + Credential userCred2 = createCredentialWithUserCredential(); + userCred2.getUserCredential().setPassword("someotherpassword!"); + userCred2.getUserCredential().setMachineManaged(false); + userCred2.getUserCredential().setAbleToShare(false); + userCred2.getUserCredential().setSoftTokenApp("TestApp2"); + userCred2.getUserCredential().setNonEapInnerMethod("PAP"); + + assertEquals(userCred1.getUniqueId(), userCred2.getUniqueId()); + } + + /** + * Verify that unique identifiers are different for a cert credential with different values */ @Test public void testUniqueIdDifferentForCertCredentialsWithDifferentValues() throws Exception { -- GitLab From 89f122abe2b752becacaa437b5c2624bf52402b6 Mon Sep 17 00:00:00 2001 From: "jorgegil@google.com" Date: Tue, 4 Aug 2020 14:46:55 -0700 Subject: [PATCH 194/536] Use last user-resized size when re-entering PIP Bug: 160799929 Test: enter PIP, resize it, restore to fullscreen then re-enter. The re-entry size should be the same as when exiting. Change-Id: Idb36b5ec51c2d76b9df5f311518652109fa57b37 Merged-In: Idb36b5ec51c2d76b9df5f311518652109fa57b37 (cherry picked from commit 134e7fc4138a479349d95efd4d68177d7b483540) --- .../android/systemui/pip/phone/PipManager.java | 7 +------ .../pip/phone/PipResizeGestureHandler.java | 11 +++++++++++ .../systemui/pip/phone/PipTouchHandler.java | 17 +++++++---------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java index 81eeef549a69..b16b71b3e558 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -377,12 +377,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio * Update the bounds used to save the re-entry size and snap fraction when exiting PIP. */ public void updateReentryBounds() { - // On phones, the expansion animation that happens on pip tap before restoring - // to fullscreen makes it so that the last reported bounds are the expanded - // bounds. We want to restore to the unexpanded bounds when re-entering pip, - // so we use the bounds before expansion (normal) instead of the reported - // bounds. - Rect reentryBounds = mTouchHandler.getNormalBounds(); + final Rect reentryBounds = mTouchHandler.getUserResizeBounds(); // Apply the snap fraction of the current bounds to the normal bounds. final Rect bounds = mPipTaskOrganizer.getLastReportedBounds(); float snapFraction = mPipBoundsHandler.getSnapFraction(bounds); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java index 83c311416800..40699568aee3 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java @@ -89,6 +89,7 @@ public class PipResizeGestureHandler { private final Point mMaxSize = new Point(); private final Point mMinSize = new Point(); private final Rect mLastResizeBounds = new Rect(); + private final Rect mUserResizeBounds = new Rect(); private final Rect mLastDownBounds = new Rect(); private final Rect mDragCornerSize = new Rect(); private final Rect mTmpTopLeftCorner = new Rect(); @@ -185,6 +186,7 @@ public class PipResizeGestureHandler { void onActivityUnpinned() { mIsAttached = false; + mUserResizeBounds.setEmpty(); updateIsEnabled(); } @@ -333,6 +335,7 @@ public class PipResizeGestureHandler { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (!mLastResizeBounds.isEmpty()) { + mUserResizeBounds.set(mLastResizeBounds); mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds, (Rect bounds) -> { new Handler(Looper.getMainLooper()).post(() -> { @@ -357,6 +360,14 @@ public class PipResizeGestureHandler { mThresholdCrossed = false; } + void setUserResizeBounds(Rect bounds) { + mUserResizeBounds.set(bounds); + } + + Rect getUserResizeBounds() { + return mUserResizeBounds; + } + void updateMaxSize(int maxX, int maxY) { mMaxSize.set(maxX, maxY); } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index 9a0cea1ae71a..7c1c2f83a258 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -133,9 +133,6 @@ public class PipTouchHandler { // The current movement bounds private Rect mMovementBounds = new Rect(); - // The current resized bounds, changed by user resize. - // This is used during expand/un-expand to save/restore the user's resized size. - @VisibleForTesting Rect mResizedBounds = new Rect(); // The reference inset bounds, used to determine the dismiss fraction private Rect mInsetBounds = new Rect(); @@ -376,7 +373,6 @@ public class PipTouchHandler { mFloatingContentCoordinator.onContentRemoved(mMotionHelper); } - mResizedBounds.setEmpty(); mPipResizeGestureHandler.onActivityUnpinned(); } @@ -386,9 +382,8 @@ public class PipTouchHandler { mMotionHelper.synchronizePinnedStackBounds(); updateMovementBounds(); if (direction == TRANSITION_DIRECTION_TO_PIP) { - // updates mResizedBounds only if it's an entering PiP animation - // mResized should be otherwise updated in setMenuState. - mResizedBounds.set(mMotionHelper.getBounds()); + // Set the initial bounds as the user resize bounds. + mPipResizeGestureHandler.setUserResizeBounds(mMotionHelper.getBounds()); } if (mShowPipMenuOnAnimationEnd) { @@ -801,9 +796,7 @@ public class PipTouchHandler { // Save the current snap fraction and if we do not drag or move the PiP, then // we store back to this snap fraction. Otherwise, we'll reset the snap // fraction and snap to the closest edge. - // Also save the current resized bounds so when the menu disappears, we can restore it. if (resize) { - mResizedBounds.set(mMotionHelper.getBounds()); Rect expandedBounds = new Rect(mExpandedBounds); mSavedSnapFraction = mMotionHelper.animateToExpandedState(expandedBounds, mMovementBounds, mExpandedMovementBounds, callback); @@ -832,7 +825,7 @@ public class PipTouchHandler { } if (mDeferResizeToNormalBoundsUntilRotation == -1) { - Rect restoreBounds = new Rect(mResizedBounds); + Rect restoreBounds = new Rect(getUserResizeBounds()); Rect restoredMovementBounds = new Rect(); mSnapAlgorithm.getMovementBounds(restoreBounds, mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0); @@ -885,6 +878,10 @@ public class PipTouchHandler { return mNormalBounds; } + Rect getUserResizeBounds() { + return mPipResizeGestureHandler.getUserResizeBounds(); + } + /** * Gesture controlling normal movement of the PIP. */ -- GitLab From d20b0cef5c76814c776268b469f9c0928e9ff593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zhiyin=20Luo=20=28=E7=BD=97=E6=A4=8D=E5=B0=B9=29?= Date: Sat, 11 Jan 2020 17:14:05 +0800 Subject: [PATCH 195/536] Fix CtsIncidentHostTestCases for RVC AAOS emulator Same failure in b/161656795, cherry pick the fix Fix uninitialization issue in JankTracker We should initialize mSwapDeadline in JankTracker, or it can be a very large randomized value and then makes jank tracker not collect concrete jank type of frames appropriately as expected. Bug: 158029827 Test: run cts -m CtsIncidentHostTestCases -t com.android.server.cts.GraphicsStatsValidationTest#testJankyDrawFrame Change-Id: I057a50a74502918619204f9164f6a954f8e9c5de (cherry picked from commit 7a0d224756195ce81875db0b481a77b87f860dd3) (cherry picked from commit 69525945b9f63fe45e2e1cfa7f63320748a3fc25) --- libs/hwui/JankTracker.cpp | 3 +++ libs/hwui/JankTracker.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp index d25fc4b0b03e..b2c39c90071a 100644 --- a/libs/hwui/JankTracker.cpp +++ b/libs/hwui/JankTracker.cpp @@ -139,6 +139,9 @@ void JankTracker::finishFrame(const FrameInfo& frame) { (*mGlobalData)->reportJank(); } + if (mSwapDeadline < 0) { + mSwapDeadline = frame[FrameInfoIndex::IntendedVsync] + mFrameInterval; + } bool isTripleBuffered = (mSwapDeadline - frame[FrameInfoIndex::IntendedVsync]) > (mFrameInterval * 0.1); mSwapDeadline = std::max(mSwapDeadline + mFrameInterval, diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h index 4460266276f9..b3fbbfe98669 100644 --- a/libs/hwui/JankTracker.h +++ b/libs/hwui/JankTracker.h @@ -75,7 +75,7 @@ private: std::array mThresholds; int64_t mFrameInterval; - nsecs_t mSwapDeadline; + nsecs_t mSwapDeadline = -1; // The amount of time we will erase from the total duration to account // for SF vsync offsets with HWC2 blocking dequeueBuffers. // (Vsync + mDequeueBlockTolerance) is the point at which we expect -- GitLab From 75d127dc92490fd6a5a00876b33cb4d9c59320b7 Mon Sep 17 00:00:00 2001 From: Brad Ebinger Date: Wed, 12 Aug 2020 17:28:45 -0700 Subject: [PATCH 196/536] Remove IMS call logs that may leak PII Bug: 160389340 Test: Check logs for PII Change-Id: I203b37d8e643c59d69aa26097d223fc4b3f8e332 --- .../java/android/telephony/ims/ImsConferenceState.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java index 21bef001efae..9bf2f44395c4 100644 --- a/telephony/java/android/telephony/ims/ImsConferenceState.java +++ b/telephony/java/android/telephony/ims/ImsConferenceState.java @@ -203,10 +203,10 @@ public final class ImsConferenceState implements Parcelable { for (String key : participantData.keySet()) { sb.append(key); sb.append("="); - if (ENDPOINT.equals(key) || USER.equals(key)) { - sb.append(Rlog.pii(TAG, participantData.get(key))); - } else { + if (STATUS.equals(key)) { sb.append(participantData.get(key)); + } else { + sb.append(Rlog.pii(TAG, participantData.get(key))); } sb.append(", "); } -- GitLab From 57855efc386a84dd8f8fc6cdb0cad4df4bf36f94 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Wed, 22 Jul 2020 11:24:16 -0700 Subject: [PATCH 197/536] Fix WiFi + "x" stil visible The WiFi + "x" still seems to appear under some conditions - code path checking on changes in status not triggered correctly. Also remove one of the calls to the WifiManager#getCurrentNetwork. Partial fix to WifiManager#getCurrentNetwork blocking. Bug: 161011371 Bug: 163425287 Test: atest NetworkControllerWifiTest Test: visual inspection Change-Id: I112bdff85e905807c4e2826c127aeaedcdb03fd1 --- .../android/settingslib/wifi/WifiStatusTracker.java | 12 ++++++++---- .../statusbar/policy/WifiSignalController.java | 9 ++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java index d7e76a14c768..e77d1a2ccea1 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java @@ -189,10 +189,12 @@ public class WifiStatusTracker { } } updateStatusLabel(); + mCallback.run(); } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) { // Default to -200 as its below WifiManager.MIN_RSSI. updateRssi(intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200)); updateStatusLabel(); + mCallback.run(); } } @@ -215,13 +217,15 @@ public class WifiStatusTracker { private void updateStatusLabel() { NetworkCapabilities networkCapabilities; - final Network currentWifiNetwork = mWifiManager.getCurrentNetwork(); - if (currentWifiNetwork != null && currentWifiNetwork.equals(mDefaultNetwork)) { + isDefaultNetwork = false; + if (mDefaultNetworkCapabilities != null) { + isDefaultNetwork = mDefaultNetworkCapabilities.hasTransport( + NetworkCapabilities.TRANSPORT_WIFI); + } + if (isDefaultNetwork) { // Wifi is connected and the default network. - isDefaultNetwork = true; networkCapabilities = mDefaultNetworkCapabilities; } else { - isDefaultNetwork = false; networkCapabilities = mConnectivityManager.getNetworkCapabilities( mWifiManager.getCurrentNetwork()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java index 5257ce4c6bd9..4ae96651b570 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java @@ -84,7 +84,7 @@ public class WifiSignalController extends R.bool.config_showWifiIndicatorWhenEnabled); boolean wifiVisible = mCurrentState.enabled && ( (mCurrentState.connected && mCurrentState.inetCondition == 1) - || !mHasMobileDataFeature || mWifiTracker.isDefaultNetwork + || !mHasMobileDataFeature || mCurrentState.isDefault || visibleWhenEnabled); String wifiDesc = mCurrentState.connected ? mCurrentState.ssid : null; boolean ssidPresent = wifiVisible && mCurrentState.ssid != null; @@ -107,6 +107,7 @@ public class WifiSignalController extends public void fetchInitialState() { mWifiTracker.fetchInitialState(); mCurrentState.enabled = mWifiTracker.enabled; + mCurrentState.isDefault = mWifiTracker.isDefaultNetwork; mCurrentState.connected = mWifiTracker.connected; mCurrentState.ssid = mWifiTracker.ssid; mCurrentState.rssi = mWifiTracker.rssi; @@ -121,6 +122,7 @@ public class WifiSignalController extends public void handleBroadcast(Intent intent) { mWifiTracker.handleBroadcast(intent); mCurrentState.enabled = mWifiTracker.enabled; + mCurrentState.isDefault = mWifiTracker.isDefaultNetwork; mCurrentState.connected = mWifiTracker.connected; mCurrentState.ssid = mWifiTracker.ssid; mCurrentState.rssi = mWifiTracker.rssi; @@ -131,6 +133,7 @@ public class WifiSignalController extends private void handleStatusUpdated() { mCurrentState.statusLabel = mWifiTracker.statusLabel; + mCurrentState.isDefault = mWifiTracker.isDefaultNetwork; notifyListenersIfNecessary(); } @@ -156,6 +159,7 @@ public class WifiSignalController extends static class WifiState extends SignalController.State { String ssid; boolean isTransient; + boolean isDefault; String statusLabel; @Override @@ -164,6 +168,7 @@ public class WifiSignalController extends WifiState state = (WifiState) s; ssid = state.ssid; isTransient = state.isTransient; + isDefault = state.isDefault; statusLabel = state.statusLabel; } @@ -172,6 +177,7 @@ public class WifiSignalController extends super.toString(builder); builder.append(",ssid=").append(ssid) .append(",isTransient=").append(isTransient) + .append(",isDefault=").append(isDefault) .append(",statusLabel=").append(statusLabel); } @@ -183,6 +189,7 @@ public class WifiSignalController extends WifiState other = (WifiState) o; return Objects.equals(other.ssid, ssid) && other.isTransient == isTransient + && other.isDefault == isDefault && TextUtils.equals(other.statusLabel, statusLabel); } } -- GitLab From a312f8165c84af88d62b2894730c1dbe659ba0da Mon Sep 17 00:00:00 2001 From: bepheis gao Date: Mon, 10 Aug 2020 22:20:47 +0800 Subject: [PATCH 198/536] Avoid deadlock during boot up Cp from aosp/1382500 to fix merge conflict Avoid a deadlock that may occurs during boosting time. if we are starting system ui while another thread is executing the enableScreenAfterBoot function at the same time, the deadlock occurs BUG: 162566198 Change-Id: Ief47cad91cbbc498179cd38e653bd1fa565cee2e Merged-In: Ief47cad91cbbc498179cd38e653bd1fa565cee2e --- .../server/wm/ActivityTaskManagerService.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index a1d0e561ff01..a96e2cb40538 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -5380,15 +5380,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return mAmInternal.isBackgroundActivityStartsEnabled(); } - void enableScreenAfterBoot(boolean booted) { - writeBootProgressEnableScreen(SystemClock.uptimeMillis()); - mWindowManager.enableScreenAfterBoot(); - - synchronized (mGlobalLock) { - updateEventDispatchingLocked(booted); - } - } - static long getInputDispatchingTimeoutLocked(ActivityRecord r) { if (r == null || !r.hasProcess()) { return KEY_DISPATCHING_TIMEOUT_MS; @@ -6474,9 +6465,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void enableScreenAfterBoot(boolean booted) { + writeBootProgressEnableScreen(SystemClock.uptimeMillis()); + mWindowManager.enableScreenAfterBoot(); synchronized (mGlobalLock) { - writeBootProgressEnableScreen(SystemClock.uptimeMillis()); - mWindowManager.enableScreenAfterBoot(); updateEventDispatchingLocked(booted); } } -- GitLab From 79388bdd6fc248362dddc8eb9a9cb633cb821596 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Fri, 31 Jul 2020 14:23:42 +0800 Subject: [PATCH 199/536] Unset activity type for process level configuration The process level configuration was updated and was scheduled to the client when home activity started, in which as home activity type. This may cause inconsistency when a standard type activity is started in the same home process. Bug: 162030251 Test: atest WindowProcessControllerTests Change-Id: I1b3b9a1a9cd164f784142fcacb365240d3522221 (cherry picked from commit e074df1419052678ffef756c26ee46651be1168d) --- .../server/wm/WindowProcessController.java | 22 +++++++++++++++---- .../wm/WindowProcessControllerTests.java | 15 +++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 29cf1776df9c..bd959aba5bb1 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -188,7 +188,6 @@ public class WindowProcessController extends ConfigurationContainer Date: Fri, 31 Jul 2020 02:57:01 -0700 Subject: [PATCH 200/536] =?UTF-8?q?Update=20language=20to=20comply=20with?= =?UTF-8?q?=20Android=E2=80=99s=20inclusive=20language=20guidance.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://source.android.com/setup/contribute/respectful-code for reference Leaving the power save whitelists as is for now. These will be handled in a follow-up cl. Bug: 161896447 Test: atest ./hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java Test: atest ./services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java Change-Id: I5059d8362a02a7b4622c71fdf15297af87c5a3dd Merged-In: I5059d8362a02a7b4622c71fdf15297af87c5a3dd Exempt-From-Owner-Approval: clean cherrypick (cherry picked from commit 76e523aa00a631d50e8035cb012c1ceccccb82bc) --- .../android/os/INetworkManagementService.aidl | 4 +- .../server/NetworkManagementService.java | 36 +-- .../server/net/NetworkPolicyLogger.java | 18 +- .../net/NetworkPolicyManagerService.java | 264 +++++++++--------- ...ict-background-lists-allowlist-format.xml} | 0 ...A-allowlisted-restrict-background-off.xml} | 0 ...dA-allowlisted-restrict-background-on.xml} | 0 ...dA-denylisted-restrict-background-off.xml} | 0 ...idA-denylisted-restrict-background-on.xml} | 0 .../net/NetworkPolicyManagerServiceTest.java | 146 +++++----- 10 files changed, 231 insertions(+), 237 deletions(-) rename services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/{restrict-background-lists-whitelist-format.xml => restrict-background-lists-allowlist-format.xml} (100%) rename services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/{uidA-whitelisted-restrict-background-off.xml => uidA-allowlisted-restrict-background-off.xml} (100%) rename services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/{uidA-whitelisted-restrict-background-on.xml => uidA-allowlisted-restrict-background-on.xml} (100%) rename services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/{uidA-blacklisted-restrict-background-off.xml => uidA-denylisted-restrict-background-off.xml} (100%) rename services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/{uidA-blacklisted-restrict-background-on.xml => uidA-denylisted-restrict-background-on.xml} (100%) diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index 0cce19222d27..8f8d451bbe8e 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -287,8 +287,8 @@ interface INetworkManagementService /** * Control network activity of a UID over interfaces with a quota limit. */ - void setUidMeteredNetworkBlacklist(int uid, boolean enable); - void setUidMeteredNetworkWhitelist(int uid, boolean enable); + void setUidMeteredNetworkDenylist(int uid, boolean enable); + void setUidMeteredNetworkAllowlist(int uid, boolean enable); boolean setDataSaverModeEnabled(boolean enable); void setUidCleartextNetworkPolicy(int uid, int policy); diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 0ddfa1c16a0a..97f3b373f63e 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -185,10 +185,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub { /** Set of interfaces with active alerts. */ @GuardedBy("mQuotaLock") private HashMap mActiveAlerts = Maps.newHashMap(); - /** Set of UIDs blacklisted on metered networks. */ + /** Set of UIDs denylisted on metered networks. */ @GuardedBy("mRulesLock") private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray(); - /** Set of UIDs whitelisted on metered networks. */ + /** Set of UIDs allowlisted on metered networks. */ @GuardedBy("mRulesLock") private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray(); /** Set of UIDs with cleartext penalties. */ @@ -561,27 +561,27 @@ public class NetworkManagementService extends INetworkManagementService.Stub { synchronized (mRulesLock) { size = mUidRejectOnMetered.size(); if (size > 0) { - if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered blacklist rules"); + if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered denylist rules"); uidRejectOnQuota = mUidRejectOnMetered; mUidRejectOnMetered = new SparseBooleanArray(); } size = mUidAllowOnMetered.size(); if (size > 0) { - if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered whitelist rules"); + if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered allowlist rules"); uidAcceptOnQuota = mUidAllowOnMetered; mUidAllowOnMetered = new SparseBooleanArray(); } } if (uidRejectOnQuota != null) { for (int i = 0; i < uidRejectOnQuota.size(); i++) { - setUidMeteredNetworkBlacklist(uidRejectOnQuota.keyAt(i), + setUidMeteredNetworkDenylist(uidRejectOnQuota.keyAt(i), uidRejectOnQuota.valueAt(i)); } } if (uidAcceptOnQuota != null) { for (int i = 0; i < uidAcceptOnQuota.size(); i++) { - setUidMeteredNetworkWhitelist(uidAcceptOnQuota.keyAt(i), + setUidMeteredNetworkAllowlist(uidAcceptOnQuota.keyAt(i), uidAcceptOnQuota.valueAt(i)); } } @@ -1307,14 +1307,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } } - private void setUidOnMeteredNetworkList(int uid, boolean blacklist, boolean enable) { + private void setUidOnMeteredNetworkList(int uid, boolean denylist, boolean enable) { NetworkStack.checkNetworkStackPermission(mContext); synchronized (mQuotaLock) { boolean oldEnable; SparseBooleanArray quotaList; synchronized (mRulesLock) { - quotaList = blacklist ? mUidRejectOnMetered : mUidAllowOnMetered; + quotaList = denylist ? mUidRejectOnMetered : mUidAllowOnMetered; oldEnable = quotaList.get(uid, false); } if (oldEnable == enable) { @@ -1324,7 +1324,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth"); try { - if (blacklist) { + if (denylist) { if (enable) { mNetdService.bandwidthAddNaughtyApp(uid); } else { @@ -1353,12 +1353,12 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } @Override - public void setUidMeteredNetworkBlacklist(int uid, boolean enable) { + public void setUidMeteredNetworkDenylist(int uid, boolean enable) { setUidOnMeteredNetworkList(uid, true, enable); } @Override - public void setUidMeteredNetworkWhitelist(int uid, boolean enable) { + public void setUidMeteredNetworkAllowlist(int uid, boolean enable) { setUidOnMeteredNetworkList(uid, false, enable); } @@ -1626,7 +1626,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } } } - // Normally, whitelist chains only contain deny rules, so numUids == exemptUids.length. + // Normally, allowlist chains only contain deny rules, so numUids == exemptUids.length. // But the code does not guarantee this in any way, and at least in one case - if we add // a UID rule to the firewall, and then disable the firewall - the chains can contain // the wrong type of rule. In this case, don't close connections that we shouldn't. @@ -1691,7 +1691,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub { // Close any sockets that were opened by the affected UIDs. This has to be done after // disabling network connectivity, in case they react to the socket close by reopening // the connection and race with the iptables commands that enable the firewall. All - // whitelist and blacklist chains allow RSTs through. + // allowlist and denylist chains allow RSTs through. if (enable) { closeSocketsForFirewallChainLocked(chain, chainName); } @@ -1828,7 +1828,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } else { ruleName = "deny"; } - } else { // Blacklist mode + } else { // Denylist mode if (rule == FIREWALL_RULE_DENY) { ruleName = "deny"; } else { @@ -1913,8 +1913,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub { pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString()); pw.print("Data saver mode: "); pw.println(mDataSaverMode); synchronized (mRulesLock) { - dumpUidRuleOnQuotaLocked(pw, "blacklist", mUidRejectOnMetered); - dumpUidRuleOnQuotaLocked(pw, "whitelist", mUidAllowOnMetered); + dumpUidRuleOnQuotaLocked(pw, "denylist", mUidRejectOnMetered); + dumpUidRuleOnQuotaLocked(pw, "allowlist", mUidAllowOnMetered); } } @@ -2179,9 +2179,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } } - void setUidOnMeteredNetworkList(boolean blacklist, int uid, boolean enable) { + void setUidOnMeteredNetworkList(boolean denylist, int uid, boolean enable) { synchronized (mRulesLock) { - if (blacklist) { + if (denylist) { mUidRejectOnMetered.put(uid, enable); } else { mUidAllowOnMetered.put(uid, enable); diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java index 3bd18f9a360f..006d78e4a648 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java +++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java @@ -70,9 +70,9 @@ public class NetworkPolicyLogger { static final int NTWK_BLOCKED_POWER = 0; static final int NTWK_ALLOWED_NON_METERED = 1; - static final int NTWK_BLOCKED_BLACKLIST = 2; - static final int NTWK_ALLOWED_WHITELIST = 3; - static final int NTWK_ALLOWED_TMP_WHITELIST = 4; + static final int NTWK_BLOCKED_DENYLIST = 2; + static final int NTWK_ALLOWED_ALLOWLIST = 3; + static final int NTWK_ALLOWED_TMP_ALLOWLIST = 4; static final int NTWK_BLOCKED_BG_RESTRICT = 5; static final int NTWK_ALLOWED_DEFAULT = 6; static final int NTWK_ALLOWED_SYSTEM = 7; @@ -269,12 +269,12 @@ public class NetworkPolicyLogger { return "blocked by power restrictions"; case NTWK_ALLOWED_NON_METERED: return "allowed on unmetered network"; - case NTWK_BLOCKED_BLACKLIST: - return "blacklisted on metered network"; - case NTWK_ALLOWED_WHITELIST: - return "whitelisted on metered network"; - case NTWK_ALLOWED_TMP_WHITELIST: - return "temporary whitelisted on metered network"; + case NTWK_BLOCKED_DENYLIST: + return "denylisted on metered network"; + case NTWK_ALLOWED_ALLOWLIST: + return "allowlisted on metered network"; + case NTWK_ALLOWED_TMP_ALLOWLIST: + return "temporary allowlisted on metered network"; case NTWK_BLOCKED_BG_RESTRICT: return "blocked when background is restricted"; case NTWK_ALLOWED_DEFAULT: diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index d6557f6410ec..295143e76235 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -101,13 +101,13 @@ import static com.android.internal.util.XmlUtils.writeIntAttribute; import static com.android.internal.util.XmlUtils.writeLongAttribute; import static com.android.internal.util.XmlUtils.writeStringAttribute; import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; +import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_ALLOWLIST; import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_DEFAULT; import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_NON_METERED; import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_SYSTEM; -import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_TMP_WHITELIST; -import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_WHITELIST; +import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_TMP_ALLOWLIST; import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_BG_RESTRICT; -import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_BLACKLIST; +import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_DENYLIST; import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_POWER; import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; @@ -507,7 +507,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * UIDs that have been initially white-listed by system to avoid restricted background. */ @GuardedBy("mUidRulesFirstLock") - private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids = + private final SparseBooleanArray mDefaultRestrictBackgroundAllowlistUids = new SparseBooleanArray(); /** @@ -515,7 +515,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * but later revoked by user. */ @GuardedBy("mUidRulesFirstLock") - private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids = + private final SparseBooleanArray mRestrictBackgroundAllowlistRevokedUids = new SparseBooleanArray(); /** Set of ifaces that are metered. */ @@ -582,7 +582,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") private final SparseBooleanArray mInternetPermissionMap = new SparseBooleanArray(); - // TODO: keep whitelist of system-critical services that should never have + // TODO: keep allowlist of system-critical services that should never have // rules enforced, such as system, phone, and radio UIDs. // TODO: migrate notifications to SystemUI @@ -668,26 +668,26 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } /** - * Whitelists pre-defined apps for restrict background, but only if the user didn't already - * revoke the whitelist. + * Allows pre-defined apps for restrict background, but only if the user didn't already + * revoked them. * - * @return whether any uid has been whitelisted. + * @return whether any uid has been allowlisted. */ @GuardedBy("mUidRulesFirstLock") - boolean addDefaultRestrictBackgroundWhitelistUidsUL() { + boolean addDefaultRestrictBackgroundAllowlistUidsUL() { final List users = mUserManager.getUsers(); final int numberUsers = users.size(); boolean changed = false; for (int i = 0; i < numberUsers; i++) { final UserInfo user = users.get(i); - changed = addDefaultRestrictBackgroundWhitelistUidsUL(user.id) || changed; + changed = addDefaultRestrictBackgroundAllowlistUidsUL(user.id) || changed; } return changed; } @GuardedBy("mUidRulesFirstLock") - private boolean addDefaultRestrictBackgroundWhitelistUidsUL(int userId) { + private boolean addDefaultRestrictBackgroundAllowlistUidsUL(int userId) { final SystemConfig sysConfig = SystemConfig.getInstance(); final PackageManager pm = mContext.getPackageManager(); final ArraySet allowDataUsage = sysConfig.getAllowInDataUsageSave(); @@ -695,7 +695,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { for (int i = 0; i < allowDataUsage.size(); i++) { final String pkg = allowDataUsage.valueAt(i); if (LOGD) - Slog.d(TAG, "checking restricted background whitelisting for package " + pkg + Slog.d(TAG, "checking restricted background allowlisting for package " + pkg + " and user " + userId); final ApplicationInfo app; try { @@ -706,20 +706,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { continue; } if (!app.isPrivilegedApp()) { - Slog.e(TAG, "addDefaultRestrictBackgroundWhitelistUidsUL(): " + Slog.e(TAG, "addDefaultRestrictBackgroundAllowlistUidsUL(): " + "skipping non-privileged app " + pkg); continue; } final int uid = UserHandle.getUid(userId, app.uid); - mDefaultRestrictBackgroundWhitelistUids.append(uid, true); + mDefaultRestrictBackgroundAllowlistUids.append(uid, true); if (LOGD) Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted " - + "background whitelist. Revoked status: " - + mRestrictBackgroundWhitelistRevokedUids.get(uid)); - if (!mRestrictBackgroundWhitelistRevokedUids.get(uid)) { + + "background allowlist. Revoked status: " + + mRestrictBackgroundAllowlistRevokedUids.get(uid)); + if (!mRestrictBackgroundAllowlistRevokedUids.get(uid)) { if (LOGD) Slog.d(TAG, "adding default package " + pkg + " (uid " + uid + " for user " - + userId + ") to restrict background whitelist"); + + userId + ") to restrict background allowlist"); setUidPolicyUncheckedUL(uid, POLICY_ALLOW_METERED_BACKGROUND, false); changed = true; } @@ -799,7 +799,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } }); - if (addDefaultRestrictBackgroundWhitelistUidsUL()) { + if (addDefaultRestrictBackgroundAllowlistUidsUL()) { writePolicyAL(); } @@ -1005,14 +1005,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { case ACTION_USER_ADDED: synchronized (mUidRulesFirstLock) { // Remove any persistable state for the given user; both cleaning up after a - // USER_REMOVED, and one last sanity check during USER_ADDED + // USER_REMOVED, and one last check during USER_ADDED removeUserStateUL(userId, true, false); // Removing outside removeUserStateUL since that can also be called when // user resets app preferences. mMeteredRestrictedUids.remove(userId); if (action == ACTION_USER_ADDED) { - // Add apps that are whitelisted by default. - addDefaultRestrictBackgroundWhitelistUidsUL(userId); + // Add apps that are allowlisted by default. + addDefaultRestrictBackgroundAllowlistUidsUL(userId); } // Update global restrict for that user synchronized (mNetworkPoliciesSecondLock) { @@ -2196,12 +2196,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { in.setInput(fis, StandardCharsets.UTF_8.name()); // Must save the tags and convert them to later, - // to skip UIDs that were explicitly blacklisted. - final SparseBooleanArray whitelistedRestrictBackground = new SparseBooleanArray(); + // to skip UIDs that were explicitly denylisted. + final SparseBooleanArray allowlistedRestrictBackground = new SparseBooleanArray(); int type; int version = VERSION_INIT; - boolean insideWhitelist = false; + boolean insideAllowlist = false; while ((type = in.next()) != END_DOCUMENT) { final String tag = in.getName(); if (type == START_TAG) { @@ -2340,28 +2340,28 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); } } else if (TAG_WHITELIST.equals(tag)) { - insideWhitelist = true; - } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { + insideAllowlist = true; + } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideAllowlist) { final int uid = readIntAttribute(in, ATTR_UID); - whitelistedRestrictBackground.append(uid, true); - } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) { + allowlistedRestrictBackground.append(uid, true); + } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideAllowlist) { final int uid = readIntAttribute(in, ATTR_UID); - mRestrictBackgroundWhitelistRevokedUids.put(uid, true); + mRestrictBackgroundAllowlistRevokedUids.put(uid, true); } } else if (type == END_TAG) { if (TAG_WHITELIST.equals(tag)) { - insideWhitelist = false; + insideAllowlist = false; } } } - final int size = whitelistedRestrictBackground.size(); + final int size = allowlistedRestrictBackground.size(); for (int i = 0; i < size; i++) { - final int uid = whitelistedRestrictBackground.keyAt(i); + final int uid = allowlistedRestrictBackground.keyAt(i); final int policy = mUidPolicy.get(uid, POLICY_NONE); if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) { - Slog.w(TAG, "ignoring restrict-background-whitelist for " + uid + Slog.w(TAG, "ignoring restrict-background-allowlist for " + uid + " because its policy is " + uidPoliciesToString(policy)); continue; } @@ -2533,13 +2533,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { out.endTag(null, TAG_POLICY_LIST); - // write all whitelists + // write all allowlists out.startTag(null, TAG_WHITELIST); - // revoked restrict background whitelist - int size = mRestrictBackgroundWhitelistRevokedUids.size(); + // revoked restrict background allowlist + int size = mRestrictBackgroundAllowlistRevokedUids.size(); for (int i = 0; i < size; i++) { - final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i); + final int uid = mRestrictBackgroundAllowlistRevokedUids.keyAt(i); out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); writeIntAttribute(out, ATTR_UID, uid); out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND); @@ -2619,21 +2619,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { setUidPolicyUncheckedUL(uid, policy, false); final boolean notifyApp; - if (!isUidValidForWhitelistRulesUL(uid)) { + if (!isUidValidForAllowlistRulesUL(uid)) { notifyApp = false; } else { - final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND; - final boolean isBlacklisted = policy == POLICY_REJECT_METERED_BACKGROUND; - final boolean wasWhitelisted = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND; - final boolean isWhitelisted = policy == POLICY_ALLOW_METERED_BACKGROUND; - final boolean wasBlocked = wasBlacklisted || (mRestrictBackground && !wasWhitelisted); - final boolean isBlocked = isBlacklisted || (mRestrictBackground && !isWhitelisted); - if ((wasWhitelisted && (!isWhitelisted || isBlacklisted)) - && mDefaultRestrictBackgroundWhitelistUids.get(uid) - && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) { + final boolean wasDenylisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND; + final boolean isDenylisted = policy == POLICY_REJECT_METERED_BACKGROUND; + final boolean wasAllowlisted = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND; + final boolean isAllowlisted = policy == POLICY_ALLOW_METERED_BACKGROUND; + final boolean wasBlocked = wasDenylisted || (mRestrictBackground && !wasAllowlisted); + final boolean isBlocked = isDenylisted || (mRestrictBackground && !isAllowlisted); + if ((wasAllowlisted && (!isAllowlisted || isDenylisted)) + && mDefaultRestrictBackgroundAllowlistUids.get(uid) + && !mRestrictBackgroundAllowlistRevokedUids.get(uid)) { if (LOGD) - Slog.d(TAG, "Adding uid " + uid + " to revoked restrict background whitelist"); - mRestrictBackgroundWhitelistRevokedUids.append(uid, true); + Slog.d(TAG, "Adding uid " + uid + " to revoked restrict background allowlist"); + mRestrictBackgroundAllowlistRevokedUids.append(uid, true); } notifyApp = wasBlocked != isBlocked; } @@ -2700,11 +2700,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mLogger.removingUserState(userId); boolean changed = false; - // Remove entries from revoked default restricted background UID whitelist - for (int i = mRestrictBackgroundWhitelistRevokedUids.size() - 1; i >= 0; i--) { - final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i); + // Remove entries from revoked default restricted background UID allowlist + for (int i = mRestrictBackgroundAllowlistRevokedUids.size() - 1; i >= 0; i--) { + final int uid = mRestrictBackgroundAllowlistRevokedUids.keyAt(i); if (UserHandle.getUserId(uid) == userId) { - mRestrictBackgroundWhitelistRevokedUids.removeAt(i); + mRestrictBackgroundAllowlistRevokedUids.removeAt(i); changed = true; } } @@ -2913,7 +2913,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground + "; reason: " + reason); final boolean oldRestrictBackground = mRestrictBackground; mRestrictBackground = restrictBackground; - // Must whitelist foreground apps before turning data saver mode on. + // Must allowlist foreground apps before turning data saver mode on. // TODO: there is no need to iterate through all apps here, just those in the foreground, // so it could call AM to get the UIDs of such apps, and iterate through them instead. updateRulesForRestrictBackgroundUL(); @@ -2966,7 +2966,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { Binder.restoreCallingIdentity(token); } if (policy == POLICY_REJECT_METERED_BACKGROUND) { - // App is blacklisted. + // App is denylisted. return RESTRICT_BACKGROUND_STATUS_ENABLED; } if (!mRestrictBackground) { @@ -3543,25 +3543,25 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.decreaseIndent(); } - size = mDefaultRestrictBackgroundWhitelistUids.size(); + size = mDefaultRestrictBackgroundAllowlistUids.size(); if (size > 0) { - fout.println("Default restrict background whitelist uids:"); + fout.println("Default restrict background allowlist uids:"); fout.increaseIndent(); for (int i = 0; i < size; i++) { fout.print("UID="); - fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i)); + fout.print(mDefaultRestrictBackgroundAllowlistUids.keyAt(i)); fout.println(); } fout.decreaseIndent(); } - size = mRestrictBackgroundWhitelistRevokedUids.size(); + size = mRestrictBackgroundAllowlistRevokedUids.size(); if (size > 0) { - fout.println("Default restrict background whitelist uids revoked by users:"); + fout.println("Default restrict background allowlist uids revoked by users:"); fout.increaseIndent(); for (int i = 0; i < size; i++) { fout.print("UID="); - fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i)); + fout.print(mRestrictBackgroundAllowlistRevokedUids.keyAt(i)); fout.println(); } fout.decreaseIndent(); @@ -3882,7 +3882,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") void updateRuleForAppIdleUL(int uid) { - if (!isUidValidForBlacklistRulesUL(uid)) return; + if (!isUidValidForDenylistRulesUL(uid)) return; if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRuleForAppIdleUL: " + uid ); @@ -3915,13 +3915,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final SparseIntArray blockedUids = new SparseIntArray(); for (int i = 0; i < ruleCount; i++) { final int uid = mUidFirewallStandbyRules.keyAt(i); - if (!isUidValidForBlacklistRulesUL(uid)) { + if (!isUidValidForDenylistRulesUL(uid)) { continue; } int oldRules = mUidRules.get(uid); if (enableChain) { // Chain wasn't enabled before and the other power-related - // chains are whitelists, so we can clear the + // chains are allowlists, so we can clear the // MASK_ALL_NETWORKS part of the rules and re-inform listeners if // the effective rules result in blocking network access. oldRules &= MASK_METERED_NETWORKS; @@ -4079,10 +4079,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both // methods below could be merged into a isUidValidForRules() method. @GuardedBy("mUidRulesFirstLock") - private boolean isUidValidForBlacklistRulesUL(int uid) { + private boolean isUidValidForDenylistRulesUL(int uid) { // allow rules on specific system services, and any apps if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID - || isUidValidForWhitelistRulesUL(uid)) { + || isUidValidForAllowlistRulesUL(uid)) { return true; } @@ -4090,7 +4090,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } @GuardedBy("mUidRulesFirstLock") - private boolean isUidValidForWhitelistRulesUL(int uid) { + private boolean isUidValidForAllowlistRulesUL(int uid) { return UserHandle.isApp(uid) && hasInternetPermissionUL(uid); } @@ -4235,23 +4235,23 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { /** * Applies network rules to bandwidth controllers based on process state and user-defined - * restrictions (blacklist / whitelist). + * restrictions (allowlist / denylist). * *

* {@code netd} defines 3 firewall chains that govern whether an app has access to metered * networks: *

    - *
  • @{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist). - *
  • @{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're - * also blacklisted. + *
  • @{code bw_penalty_box}: UIDs added to this chain do not have access (denylist). + *
  • @{code bw_happy_box}: UIDs added to this chain have access (allowlist), unless they're + * also denylisted. *
  • @{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}), - * no UIDs other than those whitelisted will have access. + * no UIDs other than those allowlisted will have access. *
      * *

      The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the - * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} / - * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist - * respectively): these methods set the proper internal state (blacklist / whitelist), then call + * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundAllowlistedUid(int)} / + * {@link #removeRestrictBackgroundDenylistedUid(int)} methods (for denylist and allowlist + * respectively): these methods set the proper internal state (denylist / allowlist), then call * this ({@link #updateRulesForDataUsageRestrictionsUL(int)}) to propagate the rules to * {@link INetworkManagementService}, but this method should also be called in events (like * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the @@ -4260,7 +4260,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { *

        *
      • When Data Saver mode is on, the foreground app should be temporarily added to * {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled. - *
      • If the foreground app is blacklisted by the user, it should be temporarily removed from + *
      • If the foreground app is denylisted by the user, it should be temporarily removed from * {@code bw_penalty_box}. *
      • When the app leaves foreground state, the temporary changes above should be reverted. *
      @@ -4285,7 +4285,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } private void updateRulesForDataUsageRestrictionsULInner(int uid) { - if (!isUidValidForWhitelistRulesUL(uid)) { + if (!isUidValidForAllowlistRulesUL(uid)) { if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid); return; } @@ -4295,8 +4295,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid); final boolean isRestrictedByAdmin = isRestrictedByAdminUL(uid); - final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0; - final boolean isWhitelisted = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0; + final boolean isDenylisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0; + final boolean isAllowlisted = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0; final int oldRule = oldUidRules & MASK_METERED_NETWORKS; int newRule = RULE_NONE; @@ -4304,15 +4304,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (isRestrictedByAdmin) { newRule = RULE_REJECT_METERED; } else if (isForeground) { - if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) { + if (isDenylisted || (mRestrictBackground && !isAllowlisted)) { newRule = RULE_TEMPORARY_ALLOW_METERED; - } else if (isWhitelisted) { + } else if (isAllowlisted) { newRule = RULE_ALLOW_METERED; } } else { - if (isBlacklisted) { + if (isDenylisted) { newRule = RULE_REJECT_METERED; - } else if (mRestrictBackground && isWhitelisted) { + } else if (mRestrictBackground && isAllowlisted) { newRule = RULE_ALLOW_METERED; } } @@ -4321,8 +4321,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (LOGV) { Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")" + ": isForeground=" +isForeground - + ", isBlacklisted=" + isBlacklisted - + ", isWhitelisted=" + isWhitelisted + + ", isDenylisted=" + isDenylisted + + ", isAllowlisted=" + isAllowlisted + ", isRestrictedByAdmin=" + isRestrictedByAdmin + ", oldRule=" + uidRulesToString(oldRule) + ", newRule=" + uidRulesToString(newRule) @@ -4339,49 +4339,49 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // Second step: apply bw changes based on change of state. if (newRule != oldRule) { if (hasRule(newRule, RULE_TEMPORARY_ALLOW_METERED)) { - // Temporarily whitelist foreground app, removing from blacklist if necessary + // Temporarily allowlist foreground app, removing from denylist if necessary // (since bw_penalty_box prevails over bw_happy_box). - setMeteredNetworkWhitelist(uid, true); + setMeteredNetworkAllowlist(uid, true); // TODO: if statement below is used to avoid an unnecessary call to netd / iptables, // but ideally it should be just: - // setMeteredNetworkBlacklist(uid, isBlacklisted); - if (isBlacklisted) { - setMeteredNetworkBlacklist(uid, false); + // setMeteredNetworkDenylist(uid, isDenylisted); + if (isDenylisted) { + setMeteredNetworkDenylist(uid, false); } } else if (hasRule(oldRule, RULE_TEMPORARY_ALLOW_METERED)) { - // Remove temporary whitelist from app that is not on foreground anymore. + // Remove temporary allowlist from app that is not on foreground anymore. // TODO: if statements below are used to avoid unnecessary calls to netd / iptables, // but ideally they should be just: - // setMeteredNetworkWhitelist(uid, isWhitelisted); - // setMeteredNetworkBlacklist(uid, isBlacklisted); - if (!isWhitelisted) { - setMeteredNetworkWhitelist(uid, false); + // setMeteredNetworkAllowlist(uid, isAllowlisted); + // setMeteredNetworkDenylist(uid, isDenylisted); + if (!isAllowlisted) { + setMeteredNetworkAllowlist(uid, false); } - if (isBlacklisted || isRestrictedByAdmin) { - setMeteredNetworkBlacklist(uid, true); + if (isDenylisted || isRestrictedByAdmin) { + setMeteredNetworkDenylist(uid, true); } } else if (hasRule(newRule, RULE_REJECT_METERED) || hasRule(oldRule, RULE_REJECT_METERED)) { - // Flip state because app was explicitly added or removed to blacklist. - setMeteredNetworkBlacklist(uid, (isBlacklisted || isRestrictedByAdmin)); - if (hasRule(oldRule, RULE_REJECT_METERED) && isWhitelisted) { - // Since blacklist prevails over whitelist, we need to handle the special case - // where app is whitelisted and blacklisted at the same time (although such - // scenario should be blocked by the UI), then blacklist is removed. - setMeteredNetworkWhitelist(uid, isWhitelisted); + // Flip state because app was explicitly added or removed to denylist. + setMeteredNetworkDenylist(uid, (isDenylisted || isRestrictedByAdmin)); + if (hasRule(oldRule, RULE_REJECT_METERED) && isAllowlisted) { + // Since dneylist prevails over allowlist, we need to handle the special case + // where app is allowlisted and denylisted at the same time (although such + // scenario should be blocked by the UI), then denylist is removed. + setMeteredNetworkAllowlist(uid, isAllowlisted); } } else if (hasRule(newRule, RULE_ALLOW_METERED) || hasRule(oldRule, RULE_ALLOW_METERED)) { - // Flip state because app was explicitly added or removed to whitelist. - setMeteredNetworkWhitelist(uid, isWhitelisted); + // Flip state because app was explicitly added or removed to allowlist. + setMeteredNetworkAllowlist(uid, isAllowlisted); } else { // All scenarios should have been covered above. Log.wtf(TAG, "Unexpected change of metered UID state for " + uid + ": foreground=" + isForeground - + ", whitelisted=" + isWhitelisted - + ", blacklisted=" + isBlacklisted + + ", allowlisted=" + isAllowlisted + + ", denylisted=" + isDenylisted + ", isRestrictedByAdmin=" + isRestrictedByAdmin + ", newRule=" + uidRulesToString(newUidRules) + ", oldRule=" + uidRulesToString(oldUidRules)); @@ -4397,7 +4397,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * listeners in case of change. *

      * There are 3 power-related rules that affects whether an app has background access on - * non-metered networks, and when the condition applies and the UID is not whitelisted for power + * non-metered networks, and when the condition applies and the UID is not allowlisted for power * restriction, it's added to the equivalent firewall chain: *

        *
      • App is idle: {@code fw_standby} firewall chain. @@ -4406,7 +4406,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { *
      *

      * This method updates the power-related part of the {@link #mUidRules} for a given uid based on - * these modes, the UID process state (foreground or not), and the UIDwhitelist state. + * these modes, the UID process state (foreground or not), and the UID allowlist state. *

      * NOTE: This method does not update the firewall rules on {@code netd}. */ @@ -4450,7 +4450,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") private int updateRulesForPowerRestrictionsULInner(int uid, int oldUidRules, boolean isUidIdle) { - if (!isUidValidForBlacklistRulesUL(uid)) { + if (!isUidValidForDenylistRulesUL(uid)) { if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid); return RULE_NONE; } @@ -4859,23 +4859,23 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } - private void setMeteredNetworkBlacklist(int uid, boolean enable) { - if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable); + private void setMeteredNetworkDenylist(int uid, boolean enable) { + if (LOGV) Slog.v(TAG, "setMeteredNetworkDenylist " + uid + ": " + enable); try { - mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable); + mNetworkManager.setUidMeteredNetworkDenylist(uid, enable); } catch (IllegalStateException e) { - Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e); + Log.wtf(TAG, "problem setting denylist (" + enable + ") rules for " + uid, e); } catch (RemoteException e) { // ignored; service lives in system_server } } - private void setMeteredNetworkWhitelist(int uid, boolean enable) { - if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable); + private void setMeteredNetworkAllowlist(int uid, boolean enable) { + if (LOGV) Slog.v(TAG, "setMeteredNetworkAllowlist " + uid + ": " + enable); try { - mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable); + mNetworkManager.setUidMeteredNetworkAllowlist(uid, enable); } catch (IllegalStateException e) { - Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e); + Log.wtf(TAG, "problem setting allowlist (" + enable + ") rules for " + uid, e); } catch (RemoteException e) { // ignored; service lives in system_server } @@ -4936,7 +4936,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } /** - * Add or remove a uid to the firewall blacklist for all network ifaces. + * Add or remove a uid to the firewall denylist for all network ifaces. */ private void setUidFirewallRule(int chain, int uid, int rule) { if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) { @@ -4966,7 +4966,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } /** - * Add or remove a uid to the firewall blacklist for all network ifaces. + * Add or remove a uid to the firewall denylist for all network ifaces. */ @GuardedBy("mUidRulesFirstLock") private void enableFirewallChainUL(int chain, boolean enable) { @@ -4995,8 +4995,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT); mNetworkManager .setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid, FIREWALL_RULE_DEFAULT); - mNetworkManager.setUidMeteredNetworkWhitelist(uid, false); - mNetworkManager.setUidMeteredNetworkBlacklist(uid, false); + mNetworkManager.setUidMeteredNetworkAllowlist(uid, false); + mNetworkManager.setUidMeteredNetworkDenylist(uid, false); } catch (IllegalStateException e) { Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e); } catch (RemoteException e) { @@ -5189,13 +5189,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { reason = NTWK_ALLOWED_NON_METERED; } else if (hasRule(uidRules, RULE_REJECT_METERED)) { - reason = NTWK_BLOCKED_BLACKLIST; + reason = NTWK_BLOCKED_DENYLIST; } else if (hasRule(uidRules, RULE_ALLOW_METERED)) { - reason = NTWK_ALLOWED_WHITELIST; + reason = NTWK_ALLOWED_ALLOWLIST; } else if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) { - reason = NTWK_ALLOWED_TMP_WHITELIST; + reason = NTWK_ALLOWED_TMP_ALLOWLIST; } else if (isBackgroundRestricted) { reason = NTWK_BLOCKED_BG_RESTRICT; @@ -5208,13 +5208,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { switch(reason) { case NTWK_ALLOWED_DEFAULT: case NTWK_ALLOWED_NON_METERED: - case NTWK_ALLOWED_TMP_WHITELIST: - case NTWK_ALLOWED_WHITELIST: + case NTWK_ALLOWED_TMP_ALLOWLIST: + case NTWK_ALLOWED_ALLOWLIST: case NTWK_ALLOWED_SYSTEM: blocked = false; break; case NTWK_BLOCKED_POWER: - case NTWK_BLOCKED_BLACKLIST: + case NTWK_BLOCKED_DENYLIST: case NTWK_BLOCKED_BG_RESTRICT: blocked = true; break; @@ -5234,7 +5234,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { public void resetUserState(int userId) { synchronized (mUidRulesFirstLock) { boolean changed = removeUserStateUL(userId, false, true); - changed = addDefaultRestrictBackgroundWhitelistUidsUL(userId) || changed; + changed = addDefaultRestrictBackgroundAllowlistUidsUL(userId) || changed; if (changed) { synchronized (mNetworkPoliciesSecondLock) { writePolicyAL(); diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/restrict-background-lists-whitelist-format.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/restrict-background-lists-allowlist-format.xml similarity index 100% rename from services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/restrict-background-lists-whitelist-format.xml rename to services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/restrict-background-lists-allowlist-format.xml diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-whitelisted-restrict-background-off.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowlisted-restrict-background-off.xml similarity index 100% rename from services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-whitelisted-restrict-background-off.xml rename to services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowlisted-restrict-background-off.xml diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-whitelisted-restrict-background-on.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowlisted-restrict-background-on.xml similarity index 100% rename from services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-whitelisted-restrict-background-on.xml rename to services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-allowlisted-restrict-background-on.xml diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-blacklisted-restrict-background-off.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denylisted-restrict-background-off.xml similarity index 100% rename from services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-blacklisted-restrict-background-off.xml rename to services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denylisted-restrict-background-off.xml diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-blacklisted-restrict-background-on.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denylisted-restrict-background-on.xml similarity index 100% rename from services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-blacklisted-restrict-background-on.xml rename to services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/uidA-denylisted-restrict-background-on.xml diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index 128177b073b0..58b71d4b702a 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -462,7 +462,7 @@ public class NetworkPolicyManagerServiceTest { @Test public void testTurnRestrictBackgroundOn() throws Exception { - assertRestrictBackgroundOff(); // Sanity check. + assertRestrictBackgroundOff(); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); setRestrictBackground(true); assertRestrictBackgroundChangedReceived(futureIntent, null); @@ -471,7 +471,7 @@ public class NetworkPolicyManagerServiceTest { @Test @NetPolicyXml("restrict-background-on.xml") public void testTurnRestrictBackgroundOff() throws Exception { - assertRestrictBackgroundOn(); // Sanity check. + assertRestrictBackgroundOn(); assertRestrictBackgroundChangedReceived(mFutureIntent, null); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); setRestrictBackground(false); @@ -479,28 +479,27 @@ public class NetworkPolicyManagerServiceTest { } /** - * Adds whitelist when restrict background is on - app should receive an intent. + * Adds allowlist when restrict background is on - app should receive an intent. */ @Test @NetPolicyXml("restrict-background-on.xml") - public void testAddRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception { - assertRestrictBackgroundOn(); // Sanity check. + public void testAddRestrictBackgroundAllowlist_restrictBackgroundOn() throws Exception { + assertRestrictBackgroundOn(); assertRestrictBackgroundChangedReceived(mFutureIntent, null); - addRestrictBackgroundWhitelist(true); + addRestrictBackgroundAllowlist(true); } /** - * Adds whitelist when restrict background is off - app should not receive an intent. + * Adds allowlist when restrict background is off - app should not receive an intent. */ @Test - public void testAddRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception { - assertRestrictBackgroundOff(); // Sanity check. - addRestrictBackgroundWhitelist(false); + public void testAddRestrictBackgroundAllowlist_restrictBackgroundOff() throws Exception { + assertRestrictBackgroundOff(); + addRestrictBackgroundAllowlist(false); } - private void addRestrictBackgroundWhitelist(boolean expectIntent) throws Exception { - // Sanity checks. - assertWhitelistUids(); + private void addRestrictBackgroundAllowlist(boolean expectIntent) throws Exception { + assertAllowlistUids(); assertUidPolicy(UID_A, POLICY_NONE); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); @@ -508,7 +507,7 @@ public class NetworkPolicyManagerServiceTest { mService.setUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); - assertWhitelistUids(UID_A); + assertAllowlistUids(UID_A); assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); mPolicyListener.waitAndVerify() .onUidPoliciesChanged(APP_ID_A, POLICY_ALLOW_METERED_BACKGROUND); @@ -520,24 +519,24 @@ public class NetworkPolicyManagerServiceTest { } /** - * Removes whitelist when restrict background is on - app should receive an intent. + * Removes allowlist when restrict background is on - app should receive an intent. */ @Test - @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml") - public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception { - assertRestrictBackgroundOn(); // Sanity check. + @NetPolicyXml("uidA-allowlisted-restrict-background-on.xml") + public void testRemoveRestrictBackgroundAllowlist_restrictBackgroundOn() throws Exception { + assertRestrictBackgroundOn(); assertRestrictBackgroundChangedReceived(mFutureIntent, null); - removeRestrictBackgroundWhitelist(true); + removeRestrictBackgroundAllowlist(true); } /** - * Removes whitelist when restrict background is off - app should not receive an intent. + * Removes allowlist when restrict background is off - app should not receive an intent. */ @Test - @NetPolicyXml("uidA-whitelisted-restrict-background-off.xml") - public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception { - assertRestrictBackgroundOff(); // Sanity check. - removeRestrictBackgroundWhitelist(false); + @NetPolicyXml("uidA-allowlisted-restrict-background-off.xml") + public void testRemoveRestrictBackgroundAllowlist_restrictBackgroundOff() throws Exception { + assertRestrictBackgroundOff(); + removeRestrictBackgroundAllowlist(false); } @Test @@ -688,9 +687,8 @@ public class NetworkPolicyManagerServiceTest { assertFalse(mService.getRestrictBackground()); } - private void removeRestrictBackgroundWhitelist(boolean expectIntent) throws Exception { - // Sanity checks. - assertWhitelistUids(UID_A); + private void removeRestrictBackgroundAllowlist(boolean expectIntent) throws Exception { + assertAllowlistUids(UID_A); assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); @@ -698,7 +696,7 @@ public class NetworkPolicyManagerServiceTest { mService.setUidPolicy(UID_A, POLICY_NONE); - assertWhitelistUids(); + assertAllowlistUids(); assertUidPolicy(UID_A, POLICY_NONE); mPolicyListener.waitAndVerify().onUidPoliciesChanged(APP_ID_A, POLICY_NONE); if (expectIntent) { @@ -709,27 +707,27 @@ public class NetworkPolicyManagerServiceTest { } /** - * Adds blacklist when restrict background is on - app should not receive an intent. + * Adds denylist when restrict background is on - app should not receive an intent. */ @Test @NetPolicyXml("restrict-background-on.xml") - public void testAddRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { - assertRestrictBackgroundOn(); // Sanity check. + public void testAddRestrictBackgroundDenylist_restrictBackgroundOn() throws Exception { + assertRestrictBackgroundOn(); assertRestrictBackgroundChangedReceived(mFutureIntent, null); - addRestrictBackgroundBlacklist(false); + addRestrictBackgroundDenylist(false); } /** - * Adds blacklist when restrict background is off - app should receive an intent. + * Adds denylist when restrict background is off - app should receive an intent. */ @Test - public void testAddRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception { - assertRestrictBackgroundOff(); // Sanity check. - addRestrictBackgroundBlacklist(true); + public void testAddRestrictBackgroundDenylist_restrictBackgroundOff() throws Exception { + assertRestrictBackgroundOff(); + addRestrictBackgroundDenylist(true); } - private void addRestrictBackgroundBlacklist(boolean expectIntent) throws Exception { - assertUidPolicy(UID_A, POLICY_NONE); // Sanity check. + private void addRestrictBackgroundDenylist(boolean expectIntent) throws Exception { + assertUidPolicy(UID_A, POLICY_NONE); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt()); @@ -746,28 +744,28 @@ public class NetworkPolicyManagerServiceTest { } /** - * Removes blacklist when restrict background is on - app should not receive an intent. + * Removes denylist when restrict background is on - app should not receive an intent. */ @Test - @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml") - public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { - assertRestrictBackgroundOn(); // Sanity check. + @NetPolicyXml("uidA-denylisted-restrict-background-on.xml") + public void testRemoveRestrictBackgroundDenylist_restrictBackgroundOn() throws Exception { + assertRestrictBackgroundOn(); assertRestrictBackgroundChangedReceived(mFutureIntent, null); - removeRestrictBackgroundBlacklist(false); + removeRestrictBackgroundDenylist(false); } /** - * Removes blacklist when restrict background is off - app should receive an intent. + * Removes denylist when restrict background is off - app should receive an intent. */ @Test - @NetPolicyXml("uidA-blacklisted-restrict-background-off.xml") - public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception { - assertRestrictBackgroundOff(); // Sanity check. - removeRestrictBackgroundBlacklist(true); + @NetPolicyXml("uidA-denylisted-restrict-background-off.xml") + public void testRemoveRestrictBackgroundDenylist_restrictBackgroundOff() throws Exception { + assertRestrictBackgroundOff(); + removeRestrictBackgroundDenylist(true); } - private void removeRestrictBackgroundBlacklist(boolean expectIntent) throws Exception { - assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); // Sanity check. + private void removeRestrictBackgroundDenylist(boolean expectIntent) throws Exception { + assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt()); @@ -784,9 +782,8 @@ public class NetworkPolicyManagerServiceTest { } @Test - @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml") - public void testBlacklistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception { - // Sanity checks. + @NetPolicyXml("uidA-denylisted-restrict-background-on.xml") + public void testDenylistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception { assertRestrictBackgroundOn(); assertRestrictBackgroundChangedReceived(mFutureIntent, null); assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); @@ -797,12 +794,11 @@ public class NetworkPolicyManagerServiceTest { } @Test - @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml") - public void testWhitelistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception { - // Sanity checks. + @NetPolicyXml("uidA-allowlisted-restrict-background-on.xml") + public void testAllowlistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception { assertRestrictBackgroundOn(); assertRestrictBackgroundChangedReceived(mFutureIntent, null); - assertWhitelistUids(UID_A); + assertAllowlistUids(UID_A); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); setRestrictBackground(true); @@ -810,12 +806,11 @@ public class NetworkPolicyManagerServiceTest { } @Test - @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml") - public void testWhitelistedAppIsNotifiedWhenBlacklisted() throws Exception { - // Sanity checks. + @NetPolicyXml("uidA-allowlisted-restrict-background-on.xml") + public void testAllowlistedAppIsNotifiedWhenDenylisted() throws Exception { assertRestrictBackgroundOn(); assertRestrictBackgroundChangedReceived(mFutureIntent, null); - assertWhitelistUids(UID_A); + assertAllowlistUids(UID_A); final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); @@ -823,8 +818,8 @@ public class NetworkPolicyManagerServiceTest { } @Test - @NetPolicyXml("restrict-background-lists-whitelist-format.xml") - public void testRestrictBackgroundLists_whitelistFormat() throws Exception { + @NetPolicyXml("restrict-background-lists-allowlist-format.xml") + public void testRestrictBackgroundLists_allowlistFormat() throws Exception { restrictBackgroundListsTest(); } @@ -835,33 +830,33 @@ public class NetworkPolicyManagerServiceTest { } private void restrictBackgroundListsTest() throws Exception { - // UIds that are whitelisted. - assertWhitelistUids(UID_A, UID_B, UID_C); + // UIds that are allowlisted. + assertAllowlistUids(UID_A, UID_B, UID_C); assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); assertUidPolicy(UID_B, POLICY_ALLOW_METERED_BACKGROUND); assertUidPolicy(UID_C, POLICY_ALLOW_METERED_BACKGROUND); - // UIDs that are blacklisted. + // UIDs that are denylisted. assertUidPolicy(UID_D, POLICY_NONE); assertUidPolicy(UID_E, POLICY_REJECT_METERED_BACKGROUND); // UIDS that have legacy policies. assertUidPolicy(UID_F, 2); // POLICY_ALLOW_BACKGROUND_BATTERY_SAVE - // Remove whitelist. + // Remove allowlist. mService.setUidPolicy(UID_A, POLICY_NONE); assertUidPolicy(UID_A, POLICY_NONE); - assertWhitelistUids(UID_B, UID_C); + assertAllowlistUids(UID_B, UID_C); - // Add whitelist when blacklisted. + // Add allowlist when denylisted. mService.setUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND); assertUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND); - assertWhitelistUids(UID_B, UID_C, UID_E); + assertAllowlistUids(UID_B, UID_C, UID_E); - // Add blacklist when whitelisted. + // Add denylist when allowlisted. mService.setUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); - assertWhitelistUids(UID_C, UID_E); + assertAllowlistUids(UID_C, UID_E); } /** @@ -870,9 +865,9 @@ public class NetworkPolicyManagerServiceTest { @Test @NetPolicyXml("restrict-background-lists-mixed-format.xml") public void testRestrictBackgroundLists_mixedFormat() throws Exception { - assertWhitelistUids(UID_A, UID_C, UID_D); + assertAllowlistUids(UID_A, UID_C, UID_D); assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); - assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); // Blacklist prevails. + assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); // Denylist prevails. assertUidPolicy(UID_C, (POLICY_ALLOW_METERED_BACKGROUND | 2)); assertUidPolicy(UID_D, POLICY_ALLOW_METERED_BACKGROUND); } @@ -2045,7 +2040,7 @@ public class NetworkPolicyManagerServiceTest { } } - private void assertWhitelistUids(int... uids) { + private void assertAllowlistUids(int... uids) { assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), uids); } @@ -2133,7 +2128,6 @@ public class NetworkPolicyManagerServiceTest { private void setRestrictBackground(boolean flag) throws Exception { mService.setRestrictBackground(flag); - // Sanity check. assertEquals("restrictBackground not set", flag, mService.getRestrictBackground()); } -- GitLab From 1a53789bc884ead750c270e273b08804ef91ad15 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Thu, 13 Aug 2020 22:43:52 +0800 Subject: [PATCH 201/536] Update requested state after applying pending frames When there is an insets animation, we will stop updating insets source frames until the animation is done. The previous logic didn't update the frames within the requested state while the animation is done. And the frames was relied by InsetsPolicy while playing transient bar animation. If the frames don't match the display, the insets would be wrong, and the animation wouldn't be played correctly. Fix: 161134197 Test: atest InsetsControllerTest Change-Id: Id8f3c1956fbfe3ad16f167ff76297dde6c634e81 --- core/java/android/view/InsetsController.java | 11 +++++++---- .../src/android/view/InsetsControllerTest.java | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 7f45c044408a..403ac3ab29c0 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -629,7 +629,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (DEBUG) Log.d(TAG, "onStateChanged, notifyInsetsChanged"); mHost.notifyInsetsChanged(); } - if (!mState.equals(state, true /* excludingCaptionInsets */, + if (!mState.equals(mLastDispatchedState, true /* excludingCaptionInsets */, true /* excludeInvisibleIme */)) { if (DEBUG) Log.d(TAG, "onStateChanged, send state to WM: " + mState); updateRequestedState(); @@ -1138,15 +1138,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (invokeCallback) { control.cancel(); } + boolean stateChanged = false; for (int i = mRunningAnimations.size() - 1; i >= 0; i--) { RunningAnimation runningAnimation = mRunningAnimations.get(i); if (runningAnimation.runner == control) { mRunningAnimations.remove(i); ArraySet types = toInternalType(control.getTypes()); for (int j = types.size() - 1; j >= 0; j--) { - if (getSourceConsumer(types.valueAt(j)).notifyAnimationFinished()) { - mHost.notifyInsetsChanged(); - } + stateChanged |= getSourceConsumer(types.valueAt(j)).notifyAnimationFinished(); } if (invokeCallback && runningAnimation.startDispatched) { dispatchAnimationEnd(runningAnimation.runner.getAnimation()); @@ -1154,6 +1153,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation break; } } + if (stateChanged) { + mHost.notifyInsetsChanged(); + updateRequestedState(); + } } private void applyLocalVisibilityOverride() { diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index af02b7bdbd90..de128ad6d78e 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -746,6 +746,20 @@ public class InsetsControllerTest { mController.onControlsChanged(createSingletonControl(ITYPE_IME)); assertEquals(newState.getSource(ITYPE_IME), mTestHost.getModifiedState().peekSource(ITYPE_IME)); + + // The modified frames cannot be updated if there is an animation. + mController.onControlsChanged(createSingletonControl(ITYPE_NAVIGATION_BAR)); + mController.hide(navigationBars()); + newState = new InsetsState(mController.getState(), true /* copySource */); + newState.getSource(ITYPE_NAVIGATION_BAR).getFrame().top--; + mController.onStateChanged(newState); + assertNotEquals(newState.getSource(ITYPE_NAVIGATION_BAR), + mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR)); + + // The modified frames can be updated while the animation is done. + mController.cancelExistingAnimations(); + assertEquals(newState.getSource(ITYPE_NAVIGATION_BAR), + mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR)); }); } -- GitLab From 43a326cdb364a01a0bb2ab4d5076b3e6fe87a8bd Mon Sep 17 00:00:00 2001 From: lesl Date: Thu, 13 Aug 2020 14:46:06 +0800 Subject: [PATCH 202/536] wifi: Support SAE_TRANSITION when converting to WifiConfiguration In android R, framework use SoftApConfiguratio to replace WifiConfiguration. The mapping function between WifiConfiguration and SoftApConfiguration was desinged to return Null when the type doesn't support in WifiConfiguration. Likes security type WPA3_SAE_TRANSITION. But it causes the app crash because unexpected Null config. Solution: Add the mapping, SAE_TRANSITION to WPA2, when converting to avoid break the legacy apps since WPA2 config also works normally when LOHS enabled on WPA3_SAE_TRANSITION mode. Bug: 163687359 Test: atest FrameworksWifiTests Test: atest frameworks/base/wifi/tests/ Test: atest -c android.net.wifi.cts.WifiManagerTest#testStartLocalOnlyHotspotSingleRequestByApps Change-Id: I6afba22e4081ba58884ffd1b560b81b1e9960132 --- .../android/net/wifi/SoftApConfiguration.java | 1 + .../net/wifi/SoftApConfigurationTest.java | 17 +++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index a5e76e6c92ee..d2ff658b59bc 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -533,6 +533,7 @@ public final class SoftApConfiguration implements Parcelable { wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); break; case SECURITY_TYPE_WPA2_PSK: + case SECURITY_TYPE_WPA3_SAE_TRANSITION: wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK); break; default: diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index 1a4427034756..d78c942d55e2 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -282,12 +282,6 @@ public class SoftApConfigurationTest { .build(); assertNull(band_6g_config.toWifiConfiguration()); - SoftApConfiguration sae_transition_config = new SoftApConfiguration.Builder() - .setPassphrase("secretsecret", - SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) - .build(); - - assertNull(sae_transition_config.toWifiConfiguration()); } @Test @@ -330,5 +324,16 @@ public class SoftApConfigurationTest { assertThat(wifiConfig_2g5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_ANY); assertThat(wifiConfig_2g5g.apChannel).isEqualTo(0); assertThat(wifiConfig_2g5g.hiddenSSID).isEqualTo(true); + + SoftApConfiguration softApConfig_sae_transition = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) + .build(); + + WifiConfiguration wifiConfig_sae_transition = + softApConfig_sae_transition.toWifiConfiguration(); + assertThat(wifiConfig_sae_transition.getAuthType()) + .isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); + assertThat(wifiConfig_sae_transition.preSharedKey).isEqualTo("secretsecret"); } } -- GitLab From d240baf682662716c3dd7a3fc46352ee8bb3ef02 Mon Sep 17 00:00:00 2001 From: Josh Tsuji Date: Mon, 10 Aug 2020 14:50:22 -0400 Subject: [PATCH 203/536] Dismiss bubbles if shouldBubbleUp returns false (e.g. DND is enabled and configured to hide that bubble). Bug: 159413312 Test: post a bubble, enable dnd, bubble goes away, disable DND, bubble is back! Test: change DND settings from 'no sound' to 'no visual', bubble remains if 'no sound' is selected Test: dismiss bubble, enable DND, disable DND, observe bubble does not re-appear since it was manually disabled Change-Id: I8cb4b62d2cf272e9ac46f4088112a6dad381d40c (cherry picked from commit 160d1eb4acaffd0dfab4a00cb2f471fde4476897) --- .../systemui/bubbles/BubbleController.java | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 3d29037e2afc..2948b47103bf 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -134,7 +134,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi @IntDef({DISMISS_USER_GESTURE, DISMISS_AGED, DISMISS_TASK_FINISHED, DISMISS_BLOCKED, DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION, DISMISS_NO_LONGER_BUBBLE, DISMISS_USER_CHANGED, DISMISS_GROUP_CANCELLED, DISMISS_INVALID_INTENT, - DISMISS_OVERFLOW_MAX_REACHED, DISMISS_SHORTCUT_REMOVED, DISMISS_PACKAGE_REMOVED}) + DISMISS_OVERFLOW_MAX_REACHED, DISMISS_SHORTCUT_REMOVED, DISMISS_PACKAGE_REMOVED, + DISMISS_NO_BUBBLE_UP}) @Target({FIELD, LOCAL_VARIABLE, PARAMETER}) @interface DismissReason {} @@ -151,6 +152,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi static final int DISMISS_OVERFLOW_MAX_REACHED = 11; static final int DISMISS_SHORTCUT_REMOVED = 12; static final int DISMISS_PACKAGE_REMOVED = 13; + static final int DISMISS_NO_BUBBLE_UP = 14; private final Context mContext; private final NotificationEntryManager mNotificationEntryManager; @@ -1243,8 +1245,18 @@ public class BubbleController implements ConfigurationController.ConfigurationLi rankingMap.getRanking(key, mTmpRanking); boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key); if (isActiveBubble && !mTmpRanking.canBubble()) { - mBubbleData.dismissBubbleWithKey(entry.getKey(), - BubbleController.DISMISS_BLOCKED); + // If this entry is no longer allowed to bubble, dismiss with the BLOCKED reason. + // This means that the app or channel's ability to bubble has been revoked. + mBubbleData.dismissBubbleWithKey( + key, BubbleController.DISMISS_BLOCKED); + } else if (isActiveBubble + && !mNotificationInterruptStateProvider.shouldBubbleUp(entry)) { + // If this entry is allowed to bubble, but cannot currently bubble up, dismiss it. + // This happens when DND is enabled and configured to hide bubbles. Dismissing with + // the reason DISMISS_NO_BUBBLE_UP will retain the underlying notification, so that + // the bubble will be re-created if shouldBubbleUp returns true. + mBubbleData.dismissBubbleWithKey( + key, BubbleController.DISMISS_NO_BUBBLE_UP); } else if (entry != null && mTmpRanking.isBubble() && !isActiveBubble) { entry.setFlagBubble(true); onEntryUpdated(entry); @@ -1321,8 +1333,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mStackView.removeBubble(bubble); } - // If the bubble is removed for user switching, leave the notification in place. - if (reason == DISMISS_USER_CHANGED) { + // Leave the notification in place if we're dismissing due to user switching, or + // because DND is suppressing the bubble. In both of those cases, we need to be able + // to restore the bubble from the notification later. + if (reason == DISMISS_USER_CHANGED || reason == DISMISS_NO_BUBBLE_UP) { continue; } if (reason == DISMISS_NOTIF_CANCEL) { -- GitLab From d3a397fe8037a53b6f36ab11ea3b6f6f5569f9b3 Mon Sep 17 00:00:00 2001 From: Brad Ebinger Date: Wed, 12 Aug 2020 17:28:45 -0700 Subject: [PATCH 204/536] Remove IMS call logs that may leak PII Bug: 160389340 Test: Check logs for PII Change-Id: I203b37d8e643c59d69aa26097d223fc4b3f8e332 --- .../java/android/telephony/ims/ImsConferenceState.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java index 21bef001efae..9bf2f44395c4 100644 --- a/telephony/java/android/telephony/ims/ImsConferenceState.java +++ b/telephony/java/android/telephony/ims/ImsConferenceState.java @@ -203,10 +203,10 @@ public final class ImsConferenceState implements Parcelable { for (String key : participantData.keySet()) { sb.append(key); sb.append("="); - if (ENDPOINT.equals(key) || USER.equals(key)) { - sb.append(Rlog.pii(TAG, participantData.get(key))); - } else { + if (STATUS.equals(key)) { sb.append(participantData.get(key)); + } else { + sb.append(Rlog.pii(TAG, participantData.get(key))); } sb.append(", "); } -- GitLab From d77752dbf23fdd34dcdb03d27396dee04ae81fe4 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Fri, 7 Aug 2020 10:58:14 -0700 Subject: [PATCH 205/536] audio: add device definitions for BLE Audio Add device type enums for BLE Audio. Device types for BLE audio headset and BLE audio speaker are added to AudioDeviceInfo class. Conversions to internal device types are added to AudioSystem. Bug: 161358428 Test: make flash and boot Change-Id: I0a39ffc49c0e7e5b36975656a33a2dd2946b60b7 Merged-In: I0a39ffc49c0e7e5b36975656a33a2dd2946b60b7 (cherry picked from commit 6239d7ee87c5948c626b6c338f06a52cd4fa3316) --- api/current.txt | 2 ++ media/java/android/media/AudioDeviceInfo.java | 33 ++++++++++++++++--- media/java/android/media/AudioDevicePort.java | 4 ++- media/java/android/media/AudioManager.java | 12 +++++++ media/java/android/media/AudioSystem.java | 24 ++++++++++++++ non-updatable-api/current.txt | 2 ++ 6 files changed, 72 insertions(+), 5 deletions(-) diff --git a/api/current.txt b/api/current.txt index 07a792072a76..7fe7bb9ddd15 100644 --- a/api/current.txt +++ b/api/current.txt @@ -24029,6 +24029,8 @@ package android.media { method public boolean isSink(); method public boolean isSource(); field public static final int TYPE_AUX_LINE = 19; // 0x13 + field public static final int TYPE_BLE_HEADSET = 26; // 0x1a + field public static final int TYPE_BLE_SPEAKER = 27; // 0x1b field public static final int TYPE_BLUETOOTH_A2DP = 8; // 0x8 field public static final int TYPE_BLUETOOTH_SCO = 7; // 0x7 field public static final int TYPE_BUILTIN_EARPIECE = 1; // 0x1 diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java index 00a4c7e19f34..ff4a25622bca 100644 --- a/media/java/android/media/AudioDeviceInfo.java +++ b/media/java/android/media/AudioDeviceInfo.java @@ -146,6 +146,19 @@ public final class AudioDeviceInfo { @SystemApi public static final int TYPE_REMOTE_SUBMIX = 25; + /** + * A device type describing a Bluetooth Low Energy (BLE) audio headset or headphones. + * Headphones are grouped with headsets when the device is a sink: + * the features of headsets and headphones with regard to playback are the same. + */ + public static final int TYPE_BLE_HEADSET = 26; + + /** + * A device type describing a Bluetooth Low Energy (BLE) audio speaker. + */ + public static final int TYPE_BLE_SPEAKER = 27; + + /** @hide */ @IntDef(flag = false, prefix = "TYPE", value = { TYPE_BUILTIN_EARPIECE, @@ -170,7 +183,9 @@ public final class AudioDeviceInfo { TYPE_HEARING_AID, TYPE_BUILTIN_MIC, TYPE_FM_TUNER, - TYPE_TV_TUNER } + TYPE_TV_TUNER, + TYPE_BLE_HEADSET, + TYPE_BLE_SPEAKER} ) @Retention(RetentionPolicy.SOURCE) public @interface AudioDeviceType {} @@ -192,7 +207,8 @@ public final class AudioDeviceInfo { TYPE_LINE_ANALOG, TYPE_LINE_DIGITAL, TYPE_IP, - TYPE_BUS } + TYPE_BUS, + TYPE_BLE_HEADSET} ) @Retention(RetentionPolicy.SOURCE) public @interface AudioDeviceTypeIn {} @@ -218,7 +234,9 @@ public final class AudioDeviceInfo { TYPE_AUX_LINE, TYPE_IP, TYPE_BUS, - TYPE_HEARING_AID } + TYPE_HEARING_AID, + TYPE_BLE_HEADSET, + TYPE_BLE_SPEAKER} ) @Retention(RetentionPolicy.SOURCE) public @interface AudioDeviceTypeOut {} @@ -247,7 +265,8 @@ public final class AudioDeviceInfo { case TYPE_BUS: case TYPE_HEARING_AID: case TYPE_BUILTIN_SPEAKER_SAFE: - case TYPE_REMOTE_SUBMIX: + case TYPE_BLE_HEADSET: + case TYPE_BLE_SPEAKER: return true; default: return false; @@ -274,6 +293,7 @@ public final class AudioDeviceInfo { case TYPE_IP: case TYPE_BUS: case TYPE_REMOTE_SUBMIX: + case TYPE_BLE_HEADSET: return true; default: return false; @@ -526,6 +546,8 @@ public final class AudioDeviceInfo { INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPEAKER_SAFE, TYPE_BUILTIN_SPEAKER_SAFE); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX, TYPE_REMOTE_SUBMIX); + INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLE_HEADSET, TYPE_BLE_HEADSET); + INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLE_SPEAKER, TYPE_BLE_SPEAKER); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUILTIN_MIC, TYPE_BUILTIN_MIC); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO); @@ -546,6 +568,7 @@ public final class AudioDeviceInfo { INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_IP, TYPE_IP); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUS, TYPE_BUS); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_REMOTE_SUBMIX, TYPE_REMOTE_SUBMIX); + INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLE_HEADSET, TYPE_BLE_HEADSET); // privileges mapping to output device EXT_TO_INT_DEVICE_MAPPING = new SparseIntArray(); @@ -575,6 +598,8 @@ public final class AudioDeviceInfo { EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_SPEAKER_SAFE, AudioSystem.DEVICE_OUT_SPEAKER_SAFE); EXT_TO_INT_DEVICE_MAPPING.put(TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); + EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_OUT_BLE_HEADSET); + EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_SPEAKER, AudioSystem.DEVICE_OUT_BLE_SPEAKER); } } diff --git a/media/java/android/media/AudioDevicePort.java b/media/java/android/media/AudioDevicePort.java index 42d0f0cc13c5..f6b04540c5c7 100644 --- a/media/java/android/media/AudioDevicePort.java +++ b/media/java/android/media/AudioDevicePort.java @@ -70,7 +70,9 @@ public class AudioDevicePort extends AudioPort { * {@link AudioManager#DEVICE_IN_USB_DEVICE}) use an address composed of the ALSA card number * and device number: "card=2;device=1" * - Bluetooth devices ({@link AudioManager#DEVICE_OUT_BLUETOOTH_SCO}, - * {@link AudioManager#DEVICE_OUT_BLUETOOTH_SCO}, {@link AudioManager#DEVICE_OUT_BLUETOOTH_A2DP}) + * {@link AudioManager#DEVICE_OUT_BLUETOOTH_SCO}, + * {@link AudioManager#DEVICE_OUT_BLUETOOTH_A2DP}), + * {@link AudioManager#DEVICE_OUT_BLE_HEADSET}, {@link AudioManager#DEVICE_OUT_BLE_SPEAKER}) * use the MAC address of the bluetooth device in the form "00:11:22:AA:BB:CC" as reported by * {@link BluetoothDevice#getAddress()}. * - Deivces that do not have an address will indicate an empty string "". diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 3ac71b2cff1d..6094af94ab34 100755 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -4411,6 +4411,14 @@ public class AudioManager { * The audio output device code for built-in FM transmitter. */ public static final int DEVICE_OUT_FM = AudioSystem.DEVICE_OUT_FM; + /** @hide + * The audio output device code for a BLE audio headset. + */ + public static final int DEVICE_OUT_BLE_HEADSET = AudioSystem.DEVICE_OUT_BLE_HEADSET; + /** @hide + * The audio output device code for a BLE audio speaker. + */ + public static final int DEVICE_OUT_BLE_SPEAKER = AudioSystem.DEVICE_OUT_BLE_SPEAKER; /** @hide * This is not used as a returned value from {@link #getDevicesForStream}, but could be * used in the future in a set method to select whatever default device is chosen by the @@ -4495,6 +4503,10 @@ public class AudioManager { * The audio input device code for audio loopback */ public static final int DEVICE_IN_LOOPBACK = AudioSystem.DEVICE_IN_LOOPBACK; + /** @hide + * The audio input device code for a BLE audio headset. + */ + public static final int DEVICE_IN_BLE_HEADSET = AudioSystem.DEVICE_IN_BLE_HEADSET; /** * Return true if the device code corresponds to an output device. diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index da52cfef6bc6..90ec39d1a708 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -866,6 +866,10 @@ public class AudioSystem public static final int DEVICE_OUT_USB_HEADSET = 0x4000000; /** @hide */ public static final int DEVICE_OUT_HEARING_AID = 0x8000000; + /** @hide */ + public static final int DEVICE_OUT_BLE_HEADSET = 0x20000000; + /** @hide */ + public static final int DEVICE_OUT_BLE_SPEAKER = 0x20000001; /** @hide */ public static final int DEVICE_OUT_DEFAULT = DEVICE_BIT_DEFAULT; @@ -890,6 +894,8 @@ public class AudioSystem public static final Set DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET; /** @hide */ public static final Set DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET; + /** @hide */ + public static final Set DEVICE_OUT_ALL_BLE_SET; static { DEVICE_OUT_ALL_SET = new HashSet<>(); DEVICE_OUT_ALL_SET.add(DEVICE_OUT_EARPIECE); @@ -920,6 +926,8 @@ public class AudioSystem DEVICE_OUT_ALL_SET.add(DEVICE_OUT_PROXY); DEVICE_OUT_ALL_SET.add(DEVICE_OUT_USB_HEADSET); DEVICE_OUT_ALL_SET.add(DEVICE_OUT_HEARING_AID); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLE_HEADSET); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLE_SPEAKER); DEVICE_OUT_ALL_SET.add(DEVICE_OUT_DEFAULT); DEVICE_OUT_ALL_A2DP_SET = new HashSet<>(); @@ -945,6 +953,10 @@ public class AudioSystem DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET = new HashSet<>(); DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET.addAll(DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET); DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET.add(DEVICE_OUT_SPEAKER); + + DEVICE_OUT_ALL_BLE_SET = new HashSet<>(); + DEVICE_OUT_ALL_BLE_SET.add(DEVICE_OUT_BLE_HEADSET); + DEVICE_OUT_ALL_BLE_SET.add(DEVICE_OUT_BLE_SPEAKER); } // input devices @@ -1019,6 +1031,8 @@ public class AudioSystem /** @hide */ public static final int DEVICE_IN_ECHO_REFERENCE = DEVICE_BIT_IN | 0x10000000; /** @hide */ + public static final int DEVICE_IN_BLE_HEADSET = DEVICE_BIT_IN | 0x20000000; + /** @hide */ @UnsupportedAppUsage public static final int DEVICE_IN_DEFAULT = DEVICE_BIT_IN | DEVICE_BIT_DEFAULT; @@ -1056,6 +1070,7 @@ public class AudioSystem DEVICE_IN_ALL_SET.add(DEVICE_IN_BLUETOOTH_BLE); DEVICE_IN_ALL_SET.add(DEVICE_IN_HDMI_ARC); DEVICE_IN_ALL_SET.add(DEVICE_IN_ECHO_REFERENCE); + DEVICE_IN_ALL_SET.add(DEVICE_IN_BLE_HEADSET); DEVICE_IN_ALL_SET.add(DEVICE_IN_DEFAULT); DEVICE_IN_ALL_SCO_SET = new HashSet<>(); @@ -1118,6 +1133,8 @@ public class AudioSystem /** @hide */ public static final String DEVICE_OUT_PROXY_NAME = "proxy"; /** @hide */ public static final String DEVICE_OUT_USB_HEADSET_NAME = "usb_headset"; /** @hide */ public static final String DEVICE_OUT_HEARING_AID_NAME = "hearing_aid_out"; + /** @hide */ public static final String DEVICE_OUT_BLE_HEADSET_NAME = "ble_headset"; + /** @hide */ public static final String DEVICE_OUT_BLE_SPEAKER_NAME = "ble_speaker"; /** @hide */ public static final String DEVICE_IN_COMMUNICATION_NAME = "communication"; /** @hide */ public static final String DEVICE_IN_AMBIENT_NAME = "ambient"; @@ -1145,6 +1162,7 @@ public class AudioSystem /** @hide */ public static final String DEVICE_IN_BLUETOOTH_BLE_NAME = "bt_ble"; /** @hide */ public static final String DEVICE_IN_ECHO_REFERENCE_NAME = "echo_reference"; /** @hide */ public static final String DEVICE_IN_HDMI_ARC_NAME = "hdmi_arc"; + /** @hide */ public static final String DEVICE_IN_BLE_HEADSET_NAME = "ble_headset"; /** @hide */ @UnsupportedAppUsage @@ -1207,6 +1225,10 @@ public class AudioSystem return DEVICE_OUT_USB_HEADSET_NAME; case DEVICE_OUT_HEARING_AID: return DEVICE_OUT_HEARING_AID_NAME; + case DEVICE_OUT_BLE_HEADSET: + return DEVICE_OUT_BLE_HEADSET_NAME; + case DEVICE_OUT_BLE_SPEAKER: + return DEVICE_OUT_BLE_SPEAKER_NAME; case DEVICE_OUT_DEFAULT: default: return Integer.toString(device); @@ -1269,6 +1291,8 @@ public class AudioSystem return DEVICE_IN_ECHO_REFERENCE_NAME; case DEVICE_IN_HDMI_ARC: return DEVICE_IN_HDMI_ARC_NAME; + case DEVICE_IN_BLE_HEADSET: + return DEVICE_IN_BLE_HEADSET_NAME; case DEVICE_IN_DEFAULT: default: return Integer.toString(device); diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index fa4fc6697bbd..41304c5a8526 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -24029,6 +24029,8 @@ package android.media { method public boolean isSink(); method public boolean isSource(); field public static final int TYPE_AUX_LINE = 19; // 0x13 + field public static final int TYPE_BLE_HEADSET = 26; // 0x1a + field public static final int TYPE_BLE_SPEAKER = 27; // 0x1b field public static final int TYPE_BLUETOOTH_A2DP = 8; // 0x8 field public static final int TYPE_BLUETOOTH_SCO = 7; // 0x7 field public static final int TYPE_BUILTIN_EARPIECE = 1; // 0x1 -- GitLab From b3288fbdd510d4693b1607d399f8bb57085eedab Mon Sep 17 00:00:00 2001 From: Jeongik Cha Date: Fri, 14 Aug 2020 23:18:24 +0900 Subject: [PATCH 206/536] Add '-unstable' to solve ODR violation The interface which is imported by an unstable interface is 'unstable' as well. Until now, the ODR violation checker in aidl has omitted an interface imported, but it will be checked, accordingly, fix the current problem Bug: 146436251 Test: m nothing Change-Id: I3a9ae6e17e49c731e825ef00b9b9574c3f2e2719 --- services/incremental/Android.bp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp index 7534c7c40a3d..e978ed4000e0 100644 --- a/services/incremental/Android.bp +++ b/services/incremental/Android.bp @@ -51,9 +51,9 @@ cc_defaults { static_libs: [ "libbase", "libext2_uuid", - "libdataloader_aidl-cpp", - "libincremental_aidl-cpp", - "libincremental_manager_aidl-cpp", + "libdataloader_aidl-unstable-cpp", + "libincremental_aidl-unstable-cpp", + "libincremental_manager_aidl-unstable-cpp", "libprotobuf-cpp-lite", "service.incremental.proto", "libutils", -- GitLab From 2778b62f1d60ada36655787fa716ee99346f7c68 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Tue, 11 Aug 2020 15:08:29 -0400 Subject: [PATCH 207/536] Remove app ops indicators from notifications Test: atest Bug: 163076432 Change-Id: I5b7514f765811ffd3b0aca63d0108591755974ab Merged-In: I5b7514f765811ffd3b0aca63d0108591755974ab --- core/java/android/app/Notification.java | 8 - .../android/view/NotificationHeaderView.java | 25 -- .../internal/widget/ConversationLayout.java | 44 ---- .../layout/notification_template_header.xml | 37 --- .../statusbar/NotificationMenuRowPlugin.java | 5 - .../systemui/ForegroundServiceController.java | 50 +--- ...ForegroundServiceNotificationListener.java | 16 -- .../NotificationViewHierarchyManager.java | 1 - .../coordinator/AppOpsCoordinator.java | 83 ------- .../notification/row/AppOpsInfo.java | 214 ---------------- .../row/ExpandableNotificationRow.java | 30 --- .../ExpandableNotificationRowController.java | 3 - .../row/NotificationContentView.java | 12 - .../row/NotificationGutsManager.java | 32 --- .../notification/row/NotificationMenuRow.java | 16 -- .../NotificationHeaderViewWrapper.java | 51 ---- .../row/wrapper/NotificationViewWrapper.java | 8 - .../stack/NotificationChildrenContainer.java | 14 -- .../ForegroundServiceControllerTest.java | 82 +------ .../NotificationViewHierarchyManagerTest.java | 13 - .../coordinator/AppOpsCoordinatorTest.java | 144 ----------- .../notification/row/AppOpsInfoTest.java | 230 ------------------ .../row/ExpandableNotificationRowTest.java | 42 ---- .../row/NotificationContentViewTest.java | 26 -- .../row/NotificationTestHelper.java | 1 - 25 files changed, 4 insertions(+), 1183 deletions(-) delete mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 76226888bf1a..b95a402013ec 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -5151,18 +5151,10 @@ public class Notification implements Parcelable bindHeaderChronometerAndTime(contentView, p); bindProfileBadge(contentView, p); bindAlertedIcon(contentView, p); - bindActivePermissions(contentView, p); bindExpandButton(contentView, p); mN.mUsesStandardHeader = true; } - private void bindActivePermissions(RemoteViews contentView, StandardTemplateParams p) { - int color = getNeutralColor(p); - contentView.setDrawableTint(R.id.camera, false, color, PorterDuff.Mode.SRC_ATOP); - contentView.setDrawableTint(R.id.mic, false, color, PorterDuff.Mode.SRC_ATOP); - contentView.setDrawableTint(R.id.overlay, false, color, PorterDuff.Mode.SRC_ATOP); - } - private void bindExpandButton(RemoteViews contentView, StandardTemplateParams p) { int color = isColorized(p) ? getPrimaryTextColor(p) : getSecondaryTextColor(p); contentView.setDrawableTint(R.id.expand_button, false, color, diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java index 0c50cb782c24..7a467d6ad73f 100644 --- a/core/java/android/view/NotificationHeaderView.java +++ b/core/java/android/view/NotificationHeaderView.java @@ -52,13 +52,11 @@ public class NotificationHeaderView extends ViewGroup { private View mHeaderText; private View mSecondaryHeaderText; private OnClickListener mExpandClickListener; - private OnClickListener mAppOpsListener; private HeaderTouchListener mTouchListener = new HeaderTouchListener(); private LinearLayout mTransferChip; private NotificationExpandButton mExpandButton; private CachingIconView mIcon; private View mProfileBadge; - private View mAppOps; private boolean mExpanded; private boolean mShowExpandButtonAtEnd; private boolean mShowWorkBadgeAtEnd; @@ -115,7 +113,6 @@ public class NotificationHeaderView extends ViewGroup { mExpandButton = findViewById(com.android.internal.R.id.expand_button); mIcon = findViewById(com.android.internal.R.id.icon); mProfileBadge = findViewById(com.android.internal.R.id.profile_badge); - mAppOps = findViewById(com.android.internal.R.id.app_ops); } @Override @@ -143,7 +140,6 @@ public class NotificationHeaderView extends ViewGroup { // Icons that should go at the end if ((child == mExpandButton && mShowExpandButtonAtEnd) || child == mProfileBadge - || child == mAppOps || child == mTransferChip) { iconWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth(); } else { @@ -208,7 +204,6 @@ public class NotificationHeaderView extends ViewGroup { // Icons that should go at the end if ((child == mExpandButton && mShowExpandButtonAtEnd) || child == mProfileBadge - || child == mAppOps || child == mTransferChip) { if (end == getMeasuredWidth()) { layoutRight = end - mContentEndMargin; @@ -277,22 +272,10 @@ public class NotificationHeaderView extends ViewGroup { } private void updateTouchListener() { - if (mExpandClickListener == null && mAppOpsListener == null) { - setOnTouchListener(null); - return; - } setOnTouchListener(mTouchListener); mTouchListener.bindTouchRects(); } - /** - * Sets onclick listener for app ops icons. - */ - public void setAppOpsOnClickListener(OnClickListener l) { - mAppOpsListener = l; - updateTouchListener(); - } - @Override public void setOnClickListener(@Nullable OnClickListener l) { mExpandClickListener = l; @@ -380,7 +363,6 @@ public class NotificationHeaderView extends ViewGroup { private final ArrayList mTouchRects = new ArrayList<>(); private Rect mExpandButtonRect; - private Rect mAppOpsRect; private int mTouchSlop; private boolean mTrackGesture; private float mDownX; @@ -393,8 +375,6 @@ public class NotificationHeaderView extends ViewGroup { mTouchRects.clear(); addRectAroundView(mIcon); mExpandButtonRect = addRectAroundView(mExpandButton); - mAppOpsRect = addRectAroundView(mAppOps); - setTouchDelegate(new TouchDelegate(mAppOpsRect, mAppOps)); addWidthRect(); mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); } @@ -455,11 +435,6 @@ public class NotificationHeaderView extends ViewGroup { break; case MotionEvent.ACTION_UP: if (mTrackGesture) { - if (mAppOps.isVisibleToUser() && (mAppOpsRect.contains((int) x, (int) y) - || mAppOpsRect.contains((int) mDownX, (int) mDownY))) { - mAppOps.performClick(); - return true; - } mExpandButton.performClick(); } break; diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java index 0791ed3c42ec..e3a456cc94a4 100644 --- a/core/java/com/android/internal/widget/ConversationLayout.java +++ b/core/java/com/android/internal/widget/ConversationLayout.java @@ -167,8 +167,6 @@ public class ConversationLayout extends FrameLayout private int mFacePileProtectionWidthExpanded; private boolean mImportantConversation; private TextView mUnreadBadge; - private ViewGroup mAppOps; - private Rect mAppOpsTouchRect = new Rect(); private float mMinTouchSize; private Icon mConversationIcon; private Icon mShortcutIcon; @@ -210,7 +208,6 @@ public class ConversationLayout extends FrameLayout mConversationIconView = findViewById(R.id.conversation_icon); mConversationIconContainer = findViewById(R.id.conversation_icon_container); mIcon = findViewById(R.id.icon); - mAppOps = findViewById(com.android.internal.R.id.app_ops); mMinTouchSize = 48 * getResources().getDisplayMetrics().density; mImportanceRingView = findViewById(R.id.conversation_icon_badge_ring); mConversationIconBadge = findViewById(R.id.conversation_icon_badge); @@ -1166,47 +1163,6 @@ public class ConversationLayout extends FrameLayout } }); } - if (mAppOps.getWidth() > 0) { - - // Let's increase the touch size of the app ops view if it's here - mAppOpsTouchRect.set( - mAppOps.getLeft(), - mAppOps.getTop(), - mAppOps.getRight(), - mAppOps.getBottom()); - for (int i = 0; i < mAppOps.getChildCount(); i++) { - View child = mAppOps.getChildAt(i); - if (child.getVisibility() == GONE) { - continue; - } - // Make sure each child has at least a minTouchSize touch target around it - float childTouchLeft = child.getLeft() + child.getWidth() / 2.0f - - mMinTouchSize / 2.0f; - float childTouchRight = childTouchLeft + mMinTouchSize; - mAppOpsTouchRect.left = (int) Math.min(mAppOpsTouchRect.left, - mAppOps.getLeft() + childTouchLeft); - mAppOpsTouchRect.right = (int) Math.max(mAppOpsTouchRect.right, - mAppOps.getLeft() + childTouchRight); - } - - // Increase the height - int heightIncrease = 0; - if (mAppOpsTouchRect.height() < mMinTouchSize) { - heightIncrease = (int) Math.ceil((mMinTouchSize - mAppOpsTouchRect.height()) - / 2.0f); - } - mAppOpsTouchRect.inset(0, -heightIncrease); - - // Let's adjust the hitrect since app ops isn't a direct child - ViewGroup viewGroup = (ViewGroup) mAppOps.getParent(); - while (viewGroup != this) { - mAppOpsTouchRect.offset(viewGroup.getLeft(), viewGroup.getTop()); - viewGroup = (ViewGroup) viewGroup.getParent(); - } - // - // Extend the size of the app opps to be at least 48dp - setTouchDelegate(new TouchDelegate(mAppOpsTouchRect, mAppOps)); - } } public MessagingLinearLayout getMessagingLinearLayout() { diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml index 23b8bd34829e..03e130e8023b 100644 --- a/core/res/res/layout/notification_template_header.xml +++ b/core/res/res/layout/notification_template_header.xml @@ -146,43 +146,6 @@ android:visibility="gone" android:contentDescription="@string/notification_work_profile_content_description" /> - - - - - mUserServices = new SparseArray<>(); private final Object mMutex = new Object(); - private final NotificationEntryManager mEntryManager; private final Handler mMainHandler; @Inject - public ForegroundServiceController(NotificationEntryManager entryManager, - AppOpsController appOpsController, @Main Handler mainHandler) { - mEntryManager = entryManager; + public ForegroundServiceController(AppOpsController appOpsController, + @Main Handler mainHandler) { mMainHandler = mainHandler; appOpsController.addCallback(APP_OPS, (code, uid, packageName, active) -> { mMainHandler.post(() -> { @@ -86,19 +80,6 @@ public class ForegroundServiceController { } } - /** - * Returns the keys for notifications from this package using the standard template, - * if they exist. - */ - @Nullable - public ArraySet getStandardLayoutKeys(int userId, String pkg) { - synchronized (mMutex) { - final ForegroundServicesUserState services = mUserServices.get(userId); - if (services == null) return null; - return services.getStandardLayoutKeys(pkg); - } - } - /** * Gets active app ops for this user and package */ @@ -140,31 +121,6 @@ public class ForegroundServiceController { userServices.removeOp(packageName, appOpCode); } } - - // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by - // AppOpsCoordinator - // Update appOps if there are associated pending or visible notifications - final Set notificationKeys = getStandardLayoutKeys(userId, packageName); - if (notificationKeys != null) { - boolean changed = false; - for (String key : notificationKeys) { - final NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(key); - if (entry != null - && uid == entry.getSbn().getUid() - && packageName.equals(entry.getSbn().getPackageName())) { - synchronized (entry.mActiveAppOps) { - if (active) { - changed |= entry.mActiveAppOps.add(appOpCode); - } else { - changed |= entry.mActiveAppOps.remove(appOpCode); - } - } - } - } - if (changed) { - mEntryManager.updateNotifications("appOpChanged pkg=" + packageName); - } - } } /** diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java index bb445832da93..1515272569d6 100644 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java @@ -172,24 +172,8 @@ public class ForegroundServiceNotificationListener { sbn.getPackageName(), sbn.getKey()); } } - tagAppOps(entry); return true; }, true /* create if not found */); } - - // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by - // AppOpsCoordinator - private void tagAppOps(NotificationEntry entry) { - final StatusBarNotification sbn = entry.getSbn(); - ArraySet activeOps = mForegroundServiceController.getAppOps( - sbn.getUserId(), - sbn.getPackageName()); - synchronized (entry.mActiveAppOps) { - entry.mActiveAppOps.clear(); - if (activeOps != null) { - entry.mActiveAppOps.addAll(activeOps); - } - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java index 5bee9a762f6f..6b8afffa065a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java @@ -486,7 +486,6 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle } } - row.showAppOpsIcons(entry.mActiveAppOps); row.setLastAudiblyAlertedMs(entry.getLastAudiblyAlertedMs()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java index 4b244bb18975..84108b196d72 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java @@ -76,14 +76,9 @@ public class AppOpsCoordinator implements Coordinator { // extend the lifetime of foreground notification services to show for at least 5 seconds mNotifPipeline.addNotificationLifetimeExtender(mForegroundLifetimeExtender); - // listen for new notifications to add appOps - mNotifPipeline.addCollectionListener(mNotifCollectionListener); - // filter out foreground service notifications that aren't necessary anymore mNotifPipeline.addPreGroupFilter(mNotifFilter); - // when appOps change, update any relevant notifications to update appOps for - mAppOpsController.addCallback(ForegroundServiceController.APP_OPS, this::onAppOpsChanged); } /** @@ -174,82 +169,4 @@ public class AppOpsCoordinator implements Coordinator { } } }; - - /** - * Adds appOps to incoming and updating notifications - */ - private NotifCollectionListener mNotifCollectionListener = new NotifCollectionListener() { - @Override - public void onEntryAdded(NotificationEntry entry) { - tagAppOps(entry); - } - - @Override - public void onEntryUpdated(NotificationEntry entry) { - tagAppOps(entry); - } - - private void tagAppOps(NotificationEntry entry) { - final StatusBarNotification sbn = entry.getSbn(); - // note: requires that the ForegroundServiceController is updating their appOps first - ArraySet activeOps = - mForegroundServiceController.getAppOps( - sbn.getUser().getIdentifier(), - sbn.getPackageName()); - - entry.mActiveAppOps.clear(); - if (activeOps != null) { - entry.mActiveAppOps.addAll(activeOps); - } - } - }; - - private void onAppOpsChanged(int code, int uid, String packageName, boolean active) { - mMainExecutor.execute(() -> handleAppOpsChanged(code, uid, packageName, active)); - } - - /** - * Update the appOp for the posted notification associated with the current foreground service - * - * @param code code for appOp to add/remove - * @param uid of user the notification is sent to - * @param packageName package that created the notification - * @param active whether the appOpCode is active or not - */ - private void handleAppOpsChanged(int code, int uid, String packageName, boolean active) { - Assert.isMainThread(); - - int userId = UserHandle.getUserId(uid); - - // Update appOps of the app's posted notifications with standard layouts - final ArraySet notifKeys = - mForegroundServiceController.getStandardLayoutKeys(userId, packageName); - if (notifKeys != null) { - boolean changed = false; - for (int i = 0; i < notifKeys.size(); i++) { - final NotificationEntry entry = findNotificationEntryWithKey(notifKeys.valueAt(i)); - if (entry != null - && uid == entry.getSbn().getUid() - && packageName.equals(entry.getSbn().getPackageName())) { - if (active) { - changed |= entry.mActiveAppOps.add(code); - } else { - changed |= entry.mActiveAppOps.remove(code); - } - } - } - if (changed) { - mNotifFilter.invalidateList(); - } - } - } - - private NotificationEntry findNotificationEntryWithKey(String key) { - for (NotificationEntry entry : mNotifPipeline.getAllNotifs()) { - if (entry.getKey().equals(key)) { - return entry; - } - } - return null; - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java deleted file mode 100644 index 28c53dc6d9b2..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (C) 2018 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.notification.row; - -import android.app.AppOpsManager; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.graphics.drawable.Drawable; -import android.service.notification.StatusBarNotification; -import android.util.ArraySet; -import android.util.AttributeSet; -import android.view.View; -import android.view.accessibility.AccessibilityEvent; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.UiEventLogger; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; - -/** - * The guts of a notification revealed when performing a long press. - */ -public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsContent { - private static final String TAG = "AppOpsGuts"; - - private PackageManager mPm; - - private String mPkg; - private String mAppName; - private int mAppUid; - private StatusBarNotification mSbn; - private ArraySet mAppOps; - private MetricsLogger mMetricsLogger; - private OnSettingsClickListener mOnSettingsClickListener; - private NotificationGuts mGutsContainer; - private UiEventLogger mUiEventLogger; - - private OnClickListener mOnOk = v -> { - mGutsContainer.closeControls(v, false); - }; - - public AppOpsInfo(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public interface OnSettingsClickListener { - void onClick(View v, String pkg, int uid, ArraySet ops); - } - - public void bindGuts(final PackageManager pm, - final OnSettingsClickListener onSettingsClick, - final StatusBarNotification sbn, - final UiEventLogger uiEventLogger, - ArraySet activeOps) { - mPkg = sbn.getPackageName(); - mSbn = sbn; - mPm = pm; - mAppName = mPkg; - mOnSettingsClickListener = onSettingsClick; - mAppOps = activeOps; - mUiEventLogger = uiEventLogger; - - bindHeader(); - bindPrompt(); - bindButtons(); - - logUiEvent(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_OPEN); - mMetricsLogger = new MetricsLogger(); - mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, true); - } - - private void bindHeader() { - // Package name - Drawable pkgicon = null; - ApplicationInfo info; - try { - info = mPm.getApplicationInfo(mPkg, - PackageManager.MATCH_UNINSTALLED_PACKAGES - | PackageManager.MATCH_DISABLED_COMPONENTS - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE - | PackageManager.MATCH_DIRECT_BOOT_AWARE); - if (info != null) { - mAppUid = mSbn.getUid(); - mAppName = String.valueOf(mPm.getApplicationLabel(info)); - pkgicon = mPm.getApplicationIcon(info); - } - } catch (PackageManager.NameNotFoundException e) { - // app is gone, just show package name and generic icon - pkgicon = mPm.getDefaultActivityIcon(); - } - ((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(pkgicon); - ((TextView) findViewById(R.id.pkgname)).setText(mAppName); - } - - private void bindPrompt() { - final TextView prompt = findViewById(R.id.prompt); - prompt.setText(getPrompt()); - } - - private void bindButtons() { - View settings = findViewById(R.id.settings); - settings.setOnClickListener((View view) -> { - mOnSettingsClickListener.onClick(view, mPkg, mAppUid, mAppOps); - }); - TextView ok = findViewById(R.id.ok); - ok.setOnClickListener(mOnOk); - ok.setAccessibilityDelegate(mGutsContainer.getAccessibilityDelegate()); - } - - private String getPrompt() { - if (mAppOps == null || mAppOps.size() == 0) { - return ""; - } else if (mAppOps.size() == 1) { - if (mAppOps.contains(AppOpsManager.OP_CAMERA)) { - return mContext.getString(R.string.appops_camera); - } else if (mAppOps.contains(AppOpsManager.OP_RECORD_AUDIO)) { - return mContext.getString(R.string.appops_microphone); - } else { - return mContext.getString(R.string.appops_overlay); - } - } else if (mAppOps.size() == 2) { - if (mAppOps.contains(AppOpsManager.OP_CAMERA)) { - if (mAppOps.contains(AppOpsManager.OP_RECORD_AUDIO)) { - return mContext.getString(R.string.appops_camera_mic); - } else { - return mContext.getString(R.string.appops_camera_overlay); - } - } else { - return mContext.getString(R.string.appops_mic_overlay); - } - } else { - return mContext.getString(R.string.appops_camera_mic_overlay); - } - } - - @Override - public void onInitializeAccessibilityEvent(AccessibilityEvent event) { - super.onInitializeAccessibilityEvent(event); - if (mGutsContainer != null && - event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { - if (mGutsContainer.isExposed()) { - event.getText().add(mContext.getString( - R.string.notification_channel_controls_opened_accessibility, mAppName)); - } else { - event.getText().add(mContext.getString( - R.string.notification_channel_controls_closed_accessibility, mAppName)); - } - } - } - - @Override - public void setGutsParent(NotificationGuts guts) { - mGutsContainer = guts; - } - - @Override - public boolean willBeRemoved() { - return false; - } - - @Override - public boolean shouldBeSaved() { - return false; - } - - @Override - public boolean needsFalsingProtection() { - return false; - } - - @Override - public View getContentView() { - return this; - } - - @Override - public boolean handleCloseControls(boolean save, boolean force) { - logUiEvent(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_CLOSE); - if (mMetricsLogger != null) { - mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, false); - } - return false; - } - - @Override - public int getActualHeight() { - return getHeight(); - } - - private void logUiEvent(NotificationAppOpsEvent event) { - if (mSbn != null) { - mUiEventLogger.logWithInstanceId(event, - mSbn.getUid(), mSbn.getPackageName(), mSbn.getInstanceId()); - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 94e12e82f850..8ead7bf2322f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -239,7 +239,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private boolean mShowNoBackground; private ExpandableNotificationRow mNotificationParent; private OnExpandClickListener mOnExpandClickListener; - private View.OnClickListener mOnAppOpsClickListener; // Listener will be called when receiving a long click event. // Use #setLongPressPosition to optionally assign positional data with the long press. @@ -1143,7 +1142,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView items.add(NotificationMenuRow.createPartialConversationItem(mContext)); items.add(NotificationMenuRow.createInfoItem(mContext)); items.add(NotificationMenuRow.createSnoozeItem(mContext)); - items.add(NotificationMenuRow.createAppOpsItem(mContext)); mMenuRow.setMenuItems(items); } if (existed) { @@ -1609,7 +1607,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView RowContentBindStage rowContentBindStage, OnExpandClickListener onExpandClickListener, NotificationMediaManager notificationMediaManager, - OnAppOpsClickListener onAppOpsClickListener, FalsingManager falsingManager, StatusBarStateController statusBarStateController, PeopleNotificationIdentifier peopleNotificationIdentifier) { @@ -1629,7 +1626,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mRowContentBindStage = rowContentBindStage; mOnExpandClickListener = onExpandClickListener; mMediaManager = notificationMediaManager; - setAppOpsOnClickListener(onAppOpsClickListener); mFalsingManager = falsingManager; mStatusbarStateController = statusBarStateController; mPeopleNotificationIdentifier = peopleNotificationIdentifier; @@ -1686,14 +1682,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView requestLayout(); } - public void showAppOpsIcons(ArraySet activeOps) { - if (mIsSummaryWithChildren) { - mChildrenContainer.showAppOpsIcons(activeOps); - } - mPrivateLayout.showAppOpsIcons(activeOps); - mPublicLayout.showAppOpsIcons(activeOps); - } - /** Sets the last time the notification being displayed audibly alerted the user. */ public void setLastAudiblyAlertedMs(long lastAudiblyAlertedMs) { if (NotificationUtils.useNewInterruptionModel(mContext)) { @@ -1722,24 +1710,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mPublicLayout.setRecentlyAudiblyAlerted(audiblyAlertedRecently); } - public View.OnClickListener getAppOpsOnClickListener() { - return mOnAppOpsClickListener; - } - - void setAppOpsOnClickListener(ExpandableNotificationRow.OnAppOpsClickListener l) { - mOnAppOpsClickListener = v -> { - createMenu(); - NotificationMenuRowPlugin provider = getProvider(); - if (provider == null) { - return; - } - MenuItem menuItem = provider.getAppOpsMenuItem(mContext); - if (menuItem != null) { - l.onClick(this, v.getWidth() / 2, v.getHeight() / 2, menuItem); - } - }; - } - @Override protected void onFinishInflate() { super.onFinishInflate(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java index 7a6109d2ce78..b132caf56265 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java @@ -63,7 +63,6 @@ public class ExpandableNotificationRowController { private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger = this::logNotificationExpansion; - private final ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener; private final NotificationGutsManager mNotificationGutsManager; private Runnable mOnDismissRunnable; private final FalsingManager mFalsingManager; @@ -101,7 +100,6 @@ public class ExpandableNotificationRowController { mStatusBarStateController = statusBarStateController; mNotificationGutsManager = notificationGutsManager; mOnDismissRunnable = onDismissRunnable; - mOnAppOpsClickListener = mNotificationGutsManager::openGuts; mAllowLongPress = allowLongPress; mFalsingManager = falsingManager; mPeopleNotificationIdentifier = peopleNotificationIdentifier; @@ -122,7 +120,6 @@ public class ExpandableNotificationRowController { mRowContentBindStage, mOnExpandClickListener, mMediaManager, - mOnAppOpsClickListener, mFalsingManager, mStatusBarStateController, mPeopleNotificationIdentifier 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 1f5b063b0aa2..41a9b187129c 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 @@ -1567,18 +1567,6 @@ public class NotificationContentView extends FrameLayout { return header; } - public void showAppOpsIcons(ArraySet activeOps) { - if (mContractedChild != null) { - mContractedWrapper.showAppOpsIcons(activeOps); - } - if (mExpandedChild != null) { - mExpandedWrapper.showAppOpsIcons(activeOps); - } - if (mHeadsUpChild != null) { - mHeadsUpWrapper.showAppOpsIcons(activeOps); - } - } - /** Sets whether the notification being displayed audibly alerted the user. */ public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) { if (mContractedChild != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index 24883f51a984..3eed18a90836 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -264,8 +264,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx try { if (gutsView instanceof NotificationSnooze) { initializeSnoozeView(row, (NotificationSnooze) gutsView); - } else if (gutsView instanceof AppOpsInfo) { - initializeAppOpsInfo(row, (AppOpsInfo) gutsView); } else if (gutsView instanceof NotificationInfo) { initializeNotificationInfo(row, (NotificationInfo) gutsView); } else if (gutsView instanceof NotificationConversationInfo) { @@ -302,36 +300,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx }); } - /** - * Sets up the {@link AppOpsInfo} inside the notification row's guts. - * - * @param row view to set up the guts for - * @param appOpsInfoView view to set up/bind within {@code row} - */ - private void initializeAppOpsInfo( - final ExpandableNotificationRow row, - AppOpsInfo appOpsInfoView) { - NotificationGuts guts = row.getGuts(); - StatusBarNotification sbn = row.getEntry().getSbn(); - UserHandle userHandle = sbn.getUser(); - PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext, - userHandle.getIdentifier()); - - AppOpsInfo.OnSettingsClickListener onSettingsClick = - (View v, String pkg, int uid, ArraySet ops) -> { - mUiEventLogger.logWithInstanceId( - NotificationAppOpsEvent.NOTIFICATION_APP_OPS_SETTINGS_CLICK, - sbn.getUid(), sbn.getPackageName(), sbn.getInstanceId()); - mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_OPS_GUTS_SETTINGS); - guts.resetFalsingCheck(); - startAppOpsSettingsActivity(pkg, uid, ops, row); - }; - if (!row.getEntry().mActiveAppOps.isEmpty()) { - appOpsInfoView.bindGuts(pmUser, onSettingsClick, sbn, mUiEventLogger, - row.getEntry().mActiveAppOps); - } - } - /** * Sets up the {@link NotificationInfo} inside the notification row's guts. * @param row view to set up the guts for diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java index 5e1e3b255867..a167925a6358 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java @@ -76,7 +76,6 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl private Context mContext; private FrameLayout mMenuContainer; private NotificationMenuItem mInfoItem; - private MenuItem mAppOpsItem; private MenuItem mSnoozeItem; private ArrayList mLeftMenuItems; private ArrayList mRightMenuItems; @@ -137,11 +136,6 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl return mInfoItem; } - @Override - public MenuItem getAppOpsMenuItem(Context context) { - return mAppOpsItem; - } - @Override public MenuItem getSnoozeMenuItem(Context context) { return mSnoozeItem; @@ -264,7 +258,6 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl // Only show snooze for non-foreground notifications, and if the setting is on mSnoozeItem = createSnoozeItem(mContext); } - mAppOpsItem = createAppOpsItem(mContext); NotificationEntry entry = mParent.getEntry(); int personNotifType = mPeopleNotificationIdentifier .getPeopleNotificationType(entry.getSbn(), entry.getRanking()); @@ -280,7 +273,6 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl mRightMenuItems.add(mSnoozeItem); } mRightMenuItems.add(mInfoItem); - mRightMenuItems.add(mAppOpsItem); mLeftMenuItems.addAll(mRightMenuItems); populateMenuViews(); @@ -688,14 +680,6 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl R.drawable.ic_settings); } - static MenuItem createAppOpsItem(Context context) { - AppOpsInfo appOpsContent = (AppOpsInfo) LayoutInflater.from(context).inflate( - R.layout.app_ops_info, null, false); - MenuItem info = new NotificationMenuItem(context, null, appOpsContent, - -1 /*don't show in slow swipe menu */); - return info; - } - private void addMenuView(MenuItem item, ViewGroup parent) { View menuView = item.getMenuView(); if (menuView != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java index c747a7c300b7..86fc352f6fe9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java @@ -18,7 +18,6 @@ package com.android.systemui.statusbar.notification.row.wrapper; import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y; -import android.app.AppOpsManager; import android.app.Notification; import android.content.Context; import android.util.ArraySet; @@ -64,10 +63,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { private TextView mHeaderText; private TextView mAppNameText; private ImageView mWorkProfileImage; - private View mCameraIcon; - private View mMicIcon; - private View mOverlayIcon; - private View mAppOps; private View mAudiblyAlertedIcon; private FrameLayout mIconContainer; @@ -108,7 +103,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { } }, TRANSFORMING_VIEW_TITLE); resolveHeaderViews(); - addAppOpsOnClickListener(row); } protected void resolveHeaderViews() { @@ -119,10 +113,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button); mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge); mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header); - mCameraIcon = mView.findViewById(com.android.internal.R.id.camera); - mMicIcon = mView.findViewById(com.android.internal.R.id.mic); - mOverlayIcon = mView.findViewById(com.android.internal.R.id.overlay); - mAppOps = mView.findViewById(com.android.internal.R.id.app_ops); mAudiblyAlertedIcon = mView.findViewById(com.android.internal.R.id.alerted_icon); if (mNotificationHeader != null) { mNotificationHeader.setShowExpandButtonAtEnd(mShowExpandButtonAtEnd); @@ -130,38 +120,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { } } - private void addAppOpsOnClickListener(ExpandableNotificationRow row) { - View.OnClickListener listener = row.getAppOpsOnClickListener(); - if (mNotificationHeader != null) { - mNotificationHeader.setAppOpsOnClickListener(listener); - } - if (mAppOps != null) { - mAppOps.setOnClickListener(listener); - } - } - - /** - * Shows or hides 'app op in use' icons based on app usage. - */ - @Override - public void showAppOpsIcons(ArraySet appOps) { - if (appOps == null) { - return; - } - if (mOverlayIcon != null) { - mOverlayIcon.setVisibility(appOps.contains(AppOpsManager.OP_SYSTEM_ALERT_WINDOW) - ? View.VISIBLE : View.GONE); - } - if (mCameraIcon != null) { - mCameraIcon.setVisibility(appOps.contains(AppOpsManager.OP_CAMERA) - ? View.VISIBLE : View.GONE); - } - if (mMicIcon != null) { - mMicIcon.setVisibility(appOps.contains(AppOpsManager.OP_RECORD_AUDIO) - ? View.VISIBLE : View.GONE); - } - } - @Override public void onContentUpdated(ExpandableNotificationRow row) { super.onContentUpdated(row); @@ -285,15 +243,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper { mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE, mHeaderText); } - if (mCameraIcon != null) { - mTransformationHelper.addViewTransformingToSimilar(mCameraIcon); - } - if (mMicIcon != null) { - mTransformationHelper.addViewTransformingToSimilar(mMicIcon); - } - if (mOverlayIcon != null) { - mTransformationHelper.addViewTransformingToSimilar(mOverlayIcon); - } if (mAudiblyAlertedIcon != null) { mTransformationHelper.addViewTransformingToSimilar(mAudiblyAlertedIcon); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java index 30080e3d8cc2..4bf279444462 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java @@ -96,14 +96,6 @@ public abstract class NotificationViewWrapper implements TransformableView { public void onContentUpdated(ExpandableNotificationRow row) { } - /** - * Show a set of app opp icons in the layout. - * - * @param appOps which app ops to show - */ - public void showAppOpsIcons(ArraySet appOps) { - } - public void onReinflated() { if (shouldClearBackgroundOnReapply()) { mBackgroundColor = 0; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java index 99691b710cc2..5edcde1cd3c7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java @@ -1302,20 +1302,6 @@ public class NotificationChildrenContainer extends ViewGroup { mCurrentHeaderTranslation = (int) ((1.0f - headerVisibleAmount) * mTranslationForHeader); } - /** - * Show a set of app opp icons in the layout. - * - * @param appOps which app ops to show - */ - public void showAppOpsIcons(ArraySet appOps) { - if (mNotificationHeaderWrapper != null) { - mNotificationHeaderWrapper.showAppOpsIcons(appOps); - } - if (mNotificationHeaderWrapperLowPriority != null) { - mNotificationHeaderWrapperLowPriority.showAppOpsIcons(appOps); - } - } - public void setRecentlyAudiblyAlerted(boolean audiblyAlertedRecently) { if (mNotificationHeaderWrapper != null) { mNotificationHeaderWrapper.setRecentlyAudiblyAlerted(audiblyAlertedRecently); diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java index 60f0cd9da5f2..e967a5d607eb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java @@ -82,8 +82,7 @@ public class ForegroundServiceControllerTest extends SysuiTestCase { allowTestableLooperAsMainThread(); MockitoAnnotations.initMocks(this); - mFsc = new ForegroundServiceController( - mEntryManager, mAppOpsController, mMainHandler); + mFsc = new ForegroundServiceController(mAppOpsController, mMainHandler); mListener = new ForegroundServiceNotificationListener( mContext, mFsc, mEntryManager, mNotifPipeline, mock(ForegroundServiceLifetimeExtender.class), mClock); @@ -114,85 +113,6 @@ public class ForegroundServiceControllerTest extends SysuiTestCase { } } - @Test - public void testAppOps_appOpChangedBeforeNotificationExists() { - // GIVEN app op exists, but notification doesn't exist in NEM yet - NotificationEntry entry = createFgEntry(); - mFsc.onAppOpChanged( - AppOpsManager.OP_CAMERA, - entry.getSbn().getUid(), - entry.getSbn().getPackageName(), - true); - assertFalse(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA)); - - // WHEN the notification is added - mEntryListener.onPendingEntryAdded(entry); - - // THEN the app op is added to the entry - Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA)); - } - - @Test - public void testAppOps_appOpAddedToForegroundNotif() { - // GIVEN a notification associated with a foreground service - NotificationEntry entry = addFgEntry(); - when(mEntryManager.getPendingOrActiveNotif(entry.getKey())).thenReturn(entry); - - // WHEN we are notified of a new app op for this notification - mFsc.onAppOpChanged( - AppOpsManager.OP_CAMERA, - entry.getSbn().getUid(), - entry.getSbn().getPackageName(), - true); - - // THEN the app op is added to the entry - Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA)); - - // THEN notification views are updated since the notification is visible - verify(mEntryManager, times(1)).updateNotifications(anyString()); - } - - @Test - public void testAppOpsAlreadyAdded() { - // GIVEN a foreground service associated notification that already has the correct app op - NotificationEntry entry = addFgEntry(); - entry.mActiveAppOps.add(AppOpsManager.OP_CAMERA); - when(mEntryManager.getPendingOrActiveNotif(entry.getKey())).thenReturn(entry); - - // WHEN we are notified of the same app op for this notification - mFsc.onAppOpChanged( - AppOpsManager.OP_CAMERA, - entry.getSbn().getUid(), - entry.getSbn().getPackageName(), - true); - - // THEN the app op still exists in the notification entry - Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA)); - - // THEN notification views aren't updated since nothing changed - verify(mEntryManager, never()).updateNotifications(anyString()); - } - - @Test - public void testAppOps_appOpNotAddedToUnrelatedNotif() { - // GIVEN no notification entries correspond to the newly updated appOp - NotificationEntry entry = addFgEntry(); - when(mEntryManager.getPendingOrActiveNotif(entry.getKey())).thenReturn(null); - - // WHEN a new app op is detected - mFsc.onAppOpChanged( - AppOpsManager.OP_CAMERA, - entry.getSbn().getUid(), - entry.getSbn().getPackageName(), - true); - - // THEN we won't see appOps on the entry - Assert.assertFalse(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA)); - - // THEN notification views aren't updated since nothing changed - verify(mEntryManager, never()).updateNotifications(anyString()); - } - @Test public void testAppOpsCRUD() { // no crash on remove that doesn't exist diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java index 92a2c8738344..80fa8cc7d931 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java @@ -210,19 +210,6 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { assertEquals(View.VISIBLE, entry1.getRow().getVisibility()); } - @Test - public void testUpdateNotificationViews_appOps() throws Exception { - NotificationEntry entry0 = createEntry(); - entry0.setRow(spy(entry0.getRow())); - when(mEntryManager.getVisibleNotifications()).thenReturn( - Lists.newArrayList(entry0)); - mListContainer.addContainerView(entry0.getRow()); - - mViewHierarchyManager.updateNotificationViews(); - - verify(entry0.getRow(), times(1)).showAppOpsIcons(any()); - } - @Test public void testReentrantCallsToOnDynamicPrivacyChangedPostForLater() { // GIVEN a ListContainer that will make a re-entrant call to updateNotificationViews() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java index 314b19140e7a..ae39035e8666 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java @@ -72,8 +72,6 @@ public class AppOpsCoordinatorTest extends SysuiTestCase { private Notification mNotification; private AppOpsCoordinator mAppOpsCoordinator; private NotifFilter mForegroundFilter; - private NotifCollectionListener mNotifCollectionListener; - private AppOpsController.Callback mAppOpsCallback; private NotifLifetimeExtender mForegroundNotifLifetimeExtender; private FakeSystemClock mClock = new FakeSystemClock(); @@ -110,18 +108,6 @@ public class AppOpsCoordinatorTest extends SysuiTestCase { lifetimeExtenderCaptor.capture()); mForegroundNotifLifetimeExtender = lifetimeExtenderCaptor.getValue(); - // capture notifCollectionListener - ArgumentCaptor notifCollectionCaptor = - ArgumentCaptor.forClass(NotifCollectionListener.class); - verify(mNotifPipeline, times(1)).addCollectionListener( - notifCollectionCaptor.capture()); - mNotifCollectionListener = notifCollectionCaptor.getValue(); - - // capture app ops callback - ArgumentCaptor appOpsCaptor = - ArgumentCaptor.forClass(AppOpsController.Callback.class); - verify(mAppOpsController).addCallback(any(int[].class), appOpsCaptor.capture()); - mAppOpsCallback = appOpsCaptor.getValue(); } @Test @@ -215,134 +201,4 @@ public class AppOpsCoordinatorTest extends SysuiTestCase { assertFalse(mForegroundNotifLifetimeExtender .shouldExtendLifetime(mEntry, NotificationListenerService.REASON_CLICK)); } - - @Test - public void testAppOpsUpdateOnlyAppliedToRelevantNotificationWithStandardLayout() { - // GIVEN three current notifications, two with the same key but from different users - NotificationEntry entry1 = new NotificationEntryBuilder() - .setUser(new UserHandle(NOTIF_USER_ID)) - .setPkg(TEST_PKG) - .setId(1) - .build(); - NotificationEntry entry2 = new NotificationEntryBuilder() - .setUser(new UserHandle(NOTIF_USER_ID)) - .setPkg(TEST_PKG) - .setId(2) - .build(); - NotificationEntry entry3_diffUser = new NotificationEntryBuilder() - .setUser(new UserHandle(NOTIF_USER_ID + 1)) - .setPkg(TEST_PKG) - .setId(2) - .build(); - when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry1, entry2, entry3_diffUser)); - - // GIVEN that only entry2 has a standard layout - when(mForegroundServiceController.getStandardLayoutKeys(NOTIF_USER_ID, TEST_PKG)) - .thenReturn(new ArraySet<>(List.of(entry2.getKey()))); - - // WHEN a new app ops code comes in - mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true); - mExecutor.runAllReady(); - - // THEN entry2's app ops are updated, but no one else's are - assertEquals( - new ArraySet<>(), - entry1.mActiveAppOps); - assertEquals( - new ArraySet<>(List.of(47)), - entry2.mActiveAppOps); - assertEquals( - new ArraySet<>(), - entry3_diffUser.mActiveAppOps); - } - - @Test - public void testAppOpsUpdateAppliedToAllNotificationsWithStandardLayouts() { - // GIVEN three notifications with standard layouts - NotificationEntry entry1 = new NotificationEntryBuilder() - .setUser(new UserHandle(NOTIF_USER_ID)) - .setPkg(TEST_PKG) - .setId(1) - .build(); - NotificationEntry entry2 = new NotificationEntryBuilder() - .setUser(new UserHandle(NOTIF_USER_ID)) - .setPkg(TEST_PKG) - .setId(2) - .build(); - NotificationEntry entry3 = new NotificationEntryBuilder() - .setUser(new UserHandle(NOTIF_USER_ID)) - .setPkg(TEST_PKG) - .setId(3) - .build(); - when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry1, entry2, entry3)); - when(mForegroundServiceController.getStandardLayoutKeys(NOTIF_USER_ID, TEST_PKG)) - .thenReturn(new ArraySet<>(List.of(entry1.getKey(), entry2.getKey(), - entry3.getKey()))); - - // WHEN a new app ops code comes in - mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true); - mExecutor.runAllReady(); - - // THEN all entries get updated - assertEquals( - new ArraySet<>(List.of(47)), - entry1.mActiveAppOps); - assertEquals( - new ArraySet<>(List.of(47)), - entry2.mActiveAppOps); - assertEquals( - new ArraySet<>(List.of(47)), - entry3.mActiveAppOps); - } - - @Test - public void testAppOpsAreRemoved() { - // GIVEN One notification which is associated with app ops - NotificationEntry entry = new NotificationEntryBuilder() - .setUser(new UserHandle(NOTIF_USER_ID)) - .setPkg(TEST_PKG) - .setId(2) - .build(); - when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry)); - when(mForegroundServiceController.getStandardLayoutKeys(0, TEST_PKG)) - .thenReturn(new ArraySet<>(List.of(entry.getKey()))); - - // GIVEN that the notification's app ops are already [47, 33] - mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true); - mAppOpsCallback.onActiveStateChanged(33, NOTIF_USER_ID, TEST_PKG, true); - mExecutor.runAllReady(); - assertEquals( - new ArraySet<>(List.of(47, 33)), - entry.mActiveAppOps); - - // WHEN one of the app ops is removed - mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, false); - mExecutor.runAllReady(); - - // THEN the entry's active app ops are updated as well - assertEquals( - new ArraySet<>(List.of(33)), - entry.mActiveAppOps); - } - - @Test - public void testNullAppOps() { - // GIVEN one notification with app ops - NotificationEntry entry = new NotificationEntryBuilder() - .setUser(new UserHandle(NOTIF_USER_ID)) - .setPkg(TEST_PKG) - .setId(2) - .build(); - entry.mActiveAppOps.clear(); - entry.mActiveAppOps.addAll(List.of(47, 33)); - - // WHEN the notification is updated and the foreground service controller returns null for - // this notification - when(mForegroundServiceController.getAppOps(entry.getSbn().getUser().getIdentifier(), - entry.getSbn().getPackageName())).thenReturn(null); - mNotifCollectionListener.onEntryUpdated(entry); - - // THEN the entry's active app ops is updated to empty - assertTrue(entry.mActiveAppOps.isEmpty()); - } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java deleted file mode 100644 index 43d8b50bcf72..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2018 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.notification.row; - -import static android.app.AppOpsManager.OP_CAMERA; -import static android.app.AppOpsManager.OP_RECORD_AUDIO; -import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyBoolean; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Notification; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.graphics.drawable.Drawable; -import android.os.UserHandle; -import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; -import android.testing.AndroidTestingRunner; -import android.testing.UiThreadTest; -import android.util.ArraySet; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import com.android.internal.logging.testing.UiEventLoggerFake; -import com.android.systemui.R; -import com.android.systemui.SysuiTestCase; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.concurrent.CountDownLatch; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -@UiThreadTest -public class AppOpsInfoTest extends SysuiTestCase { - private static final String TEST_PACKAGE_NAME = "test_package"; - private static final int TEST_UID = 1; - - private AppOpsInfo mAppOpsInfo; - private final PackageManager mMockPackageManager = mock(PackageManager.class); - private final NotificationGuts mGutsParent = mock(NotificationGuts.class); - private StatusBarNotification mSbn; - private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake(); - - @Before - public void setUp() throws Exception { - // Inflate the layout - final LayoutInflater layoutInflater = LayoutInflater.from(mContext); - mAppOpsInfo = (AppOpsInfo) layoutInflater.inflate(R.layout.app_ops_info, null); - mAppOpsInfo.setGutsParent(mGutsParent); - - // PackageManager must return a packageInfo and applicationInfo. - final PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = TEST_PACKAGE_NAME; - when(mMockPackageManager.getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt())) - .thenReturn(packageInfo); - final ApplicationInfo applicationInfo = new ApplicationInfo(); - applicationInfo.uid = TEST_UID; // non-zero - when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).thenReturn( - applicationInfo); - - mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0, - new Notification(), UserHandle.CURRENT, null, 0); - } - - @Test - public void testBindNotification_SetsTextApplicationName() { - when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name"); - mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>()); - final TextView textView = mAppOpsInfo.findViewById(R.id.pkgname); - assertTrue(textView.getText().toString().contains("App Name")); - } - - @Test - public void testBindNotification_SetsPackageIcon() { - final Drawable iconDrawable = mock(Drawable.class); - when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class))) - .thenReturn(iconDrawable); - mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>()); - final ImageView iconView = mAppOpsInfo.findViewById(R.id.pkgicon); - assertEquals(iconDrawable, iconView.getDrawable()); - } - - @Test - public void testBindNotification_SetsOnClickListenerForSettings() throws Exception { - ArraySet expectedOps = new ArraySet<>(); - expectedOps.add(OP_CAMERA); - final CountDownLatch latch = new CountDownLatch(1); - mAppOpsInfo.bindGuts(mMockPackageManager, (View v, String pkg, int uid, - ArraySet ops) -> { - assertEquals(TEST_PACKAGE_NAME, pkg); - assertEquals(expectedOps, ops); - assertEquals(TEST_UID, uid); - latch.countDown(); - }, mSbn, mUiEventLogger, expectedOps); - - final View settingsButton = mAppOpsInfo.findViewById(R.id.settings); - settingsButton.performClick(); - // Verify that listener was triggered. - assertEquals(0, latch.getCount()); - } - - @Test - public void testBindNotification_LogsOpen() throws Exception { - mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>()); - assertEquals(1, mUiEventLogger.numLogs()); - assertEquals(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_OPEN.getId(), - mUiEventLogger.eventId(0)); - } - - @Test - public void testOk() { - ArraySet expectedOps = new ArraySet<>(); - expectedOps.add(OP_CAMERA); - final CountDownLatch latch = new CountDownLatch(1); - mAppOpsInfo.bindGuts(mMockPackageManager, (View v, String pkg, int uid, - ArraySet ops) -> { - assertEquals(TEST_PACKAGE_NAME, pkg); - assertEquals(expectedOps, ops); - assertEquals(TEST_UID, uid); - latch.countDown(); - }, mSbn, mUiEventLogger, expectedOps); - - final View okButton = mAppOpsInfo.findViewById(R.id.ok); - okButton.performClick(); - assertEquals(1, latch.getCount()); - verify(mGutsParent, times(1)).closeControls(eq(okButton), anyBoolean()); - } - - @Test - public void testPrompt_camera() { - ArraySet expectedOps = new ArraySet<>(); - expectedOps.add(OP_CAMERA); - mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps); - TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); - assertEquals("This app is using the camera.", prompt.getText()); - } - - @Test - public void testPrompt_mic() { - ArraySet expectedOps = new ArraySet<>(); - expectedOps.add(OP_RECORD_AUDIO); - mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps); - TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); - assertEquals("This app is using the microphone.", prompt.getText()); - } - - @Test - public void testPrompt_overlay() { - ArraySet expectedOps = new ArraySet<>(); - expectedOps.add(OP_SYSTEM_ALERT_WINDOW); - mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps); - TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); - assertEquals("This app is displaying over other apps on your screen.", prompt.getText()); - } - - @Test - public void testPrompt_camera_mic() { - ArraySet expectedOps = new ArraySet<>(); - expectedOps.add(OP_CAMERA); - expectedOps.add(OP_RECORD_AUDIO); - mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps); - TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); - assertEquals("This app is using the microphone and camera.", prompt.getText()); - } - - @Test - public void testPrompt_camera_mic_overlay() { - ArraySet expectedOps = new ArraySet<>(); - expectedOps.add(OP_CAMERA); - expectedOps.add(OP_RECORD_AUDIO); - expectedOps.add(OP_SYSTEM_ALERT_WINDOW); - mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps); - TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); - assertEquals("This app is displaying over other apps on your screen and using" - + " the microphone and camera.", prompt.getText()); - } - - @Test - public void testPrompt_camera_overlay() { - ArraySet expectedOps = new ArraySet<>(); - expectedOps.add(OP_CAMERA); - expectedOps.add(OP_SYSTEM_ALERT_WINDOW); - mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps); - TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); - assertEquals("This app is displaying over other apps on your screen and using" - + " the camera.", prompt.getText()); - } - - @Test - public void testPrompt_mic_overlay() { - ArraySet expectedOps = new ArraySet<>(); - expectedOps.add(OP_RECORD_AUDIO); - expectedOps.add(OP_SYSTEM_ALERT_WINDOW); - mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps); - TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); - assertEquals("This app is displaying over other apps on your screen and using" - + " the microphone.", prompt.getText()); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java index 2684cc29aa93..4758d2318889 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java @@ -35,12 +35,10 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.app.AppOpsManager; import android.app.NotificationChannel; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; -import android.util.ArraySet; import android.view.View; import androidx.test.filters.SmallTest; @@ -212,46 +210,6 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { any(NotificationMenuRowPlugin.MenuItem.class)); } - @Test - public void testShowAppOps_noHeader() { - // public notification is custom layout - no header - mGroupRow.setSensitive(true, true); - mGroupRow.setAppOpsOnClickListener(null); - mGroupRow.showAppOpsIcons(null); - } - - @Test - public void testShowAppOpsIcons_header() { - NotificationContentView publicLayout = mock(NotificationContentView.class); - mGroupRow.setPublicLayout(publicLayout); - NotificationContentView privateLayout = mock(NotificationContentView.class); - mGroupRow.setPrivateLayout(privateLayout); - NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class); - when(mockContainer.getNotificationChildCount()).thenReturn(1); - mGroupRow.setChildrenContainer(mockContainer); - - ArraySet ops = new ArraySet<>(); - ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS); - mGroupRow.showAppOpsIcons(ops); - - verify(mockContainer, times(1)).showAppOpsIcons(ops); - verify(privateLayout, times(1)).showAppOpsIcons(ops); - verify(publicLayout, times(1)).showAppOpsIcons(ops); - - } - - @Test - public void testAppOpsOnClick() { - ExpandableNotificationRow.OnAppOpsClickListener l = mock( - ExpandableNotificationRow.OnAppOpsClickListener.class); - View view = mock(View.class); - - mGroupRow.setAppOpsOnClickListener(l); - - mGroupRow.getAppOpsOnClickListener().onClick(view); - verify(l, times(1)).onClick(any(), anyInt(), anyInt(), any()); - } - @Test public void testHeadsUpAnimatingAwayListener() { mGroupRow.setHeadsUpAnimatingAway(true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java index ed4f8b330e23..b02f2746ce7a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java @@ -74,32 +74,6 @@ public class NotificationContentViewTest extends SysuiTestCase { return view; } - @Test - @UiThreadTest - public void testShowAppOpsIcons() { - View mockContracted = mock(NotificationHeaderView.class); - when(mockContracted.findViewById(com.android.internal.R.id.mic)) - .thenReturn(mockContracted); - View mockExpanded = mock(NotificationHeaderView.class); - when(mockExpanded.findViewById(com.android.internal.R.id.mic)) - .thenReturn(mockExpanded); - View mockHeadsUp = mock(NotificationHeaderView.class); - when(mockHeadsUp.findViewById(com.android.internal.R.id.mic)) - .thenReturn(mockHeadsUp); - - mView.setContractedChild(mockContracted); - mView.setExpandedChild(mockExpanded); - mView.setHeadsUpChild(mockHeadsUp); - - ArraySet ops = new ArraySet<>(); - ops.add(AppOpsManager.OP_RECORD_AUDIO); - mView.showAppOpsIcons(ops); - - verify(mockContracted, times(1)).setVisibility(View.VISIBLE); - verify(mockExpanded, times(1)).setVisibility(View.VISIBLE); - verify(mockHeadsUp, times(1)).setVisibility(View.VISIBLE); - } - @Test @UiThreadTest public void testExpandButtonFocusIsCalled() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index 0c6409b38d21..d2ff2ad8a684 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -421,7 +421,6 @@ public class NotificationTestHelper { mBindStage, mock(OnExpandClickListener.class), mock(NotificationMediaManager.class), - mock(ExpandableNotificationRow.OnAppOpsClickListener.class), mock(FalsingManager.class), mStatusBarStateController, mPeopleNotificationIdentifier); -- GitLab From 5f617413aaf7e129b6f436ad82cb955d66fc374f Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Fri, 14 Aug 2020 11:39:24 -0400 Subject: [PATCH 208/536] Add MODIFY_AUDIO_ROUTING permission to systemui Adds the privileged permission for AppOpsControllerImpl. Test: build and record Fixes: 164213112 Change-Id: Ib23749542bb41eb1df2fb7cfe62db57fba73d0cf --- data/etc/com.android.systemui.xml | 1 + packages/SystemUI/AndroidManifest.xml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml index ada8b000a26b..06f1dae30cd3 100644 --- a/data/etc/com.android.systemui.xml +++ b/data/etc/com.android.systemui.xml @@ -35,6 +35,7 @@ + diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 667433c46e50..7b8aba451e27 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -240,6 +240,8 @@ + + @@ -267,6 +269,7 @@ + -- GitLab From 73d6c7926d2cdc39de617f7213fc85f303501f37 Mon Sep 17 00:00:00 2001 From: Jeff Chang Date: Fri, 7 Aug 2020 16:08:15 +0800 Subject: [PATCH 209/536] [RESTRICT AUTOMERGE] Update the visibility of activities on sleeping display Activity with showWhenLocked flag is visible when screen is off and leads to activity restart called. This CL update the visibility condition for showWhenLocked and dismisskeyguard activities and refer the keyguard visibility to ensure the function works as expected. Bug: 161036653 Test: atest ActivityRecordTests atest CtsWindowManagerDeviceTestCases:KeyguardTests atest CtsWindowManagerDeviceTestCases:KeyguardLockedTests Change-Id: I9d56e40de964e9d11193fec7008f8d880028ac50 --- .../com/android/server/wm/ActivityRecord.java | 15 ++++------ .../server/wm/ActivityRecordTests.java | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 3e9377ed0664..41e48b8ec9db 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -4578,15 +4578,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } - // Check if the activity is on a sleeping display, and if it can turn it ON. - if (getDisplay().isSleeping()) { - final boolean canTurnScreenOn = !mSetToSleep || canTurnScreenOn() - || canShowWhenLocked() || containsDismissKeyguardWindow(); - if (!canTurnScreenOn) { - return false; - } - } - // Now check whether it's really visible depending on Keyguard state, and update // {@link ActivityStack} internal states. // Inform the method if this activity is the top activity of this stack, but exclude the @@ -4597,6 +4588,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this, visibleIgnoringKeyguard, isTop && isTopNotPinnedStack); + // Check if the activity is on a sleeping display, and if it can turn it ON. + // TODO(b/163993448): Do not make activity visible before display awake. + if (visibleIgnoringDisplayStatus && getDisplay().isSleeping()) { + return !mSetToSleep || canTurnScreenOn(); + } + return visibleIgnoringDisplayStatus; } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index c7b45efb2de1..6ab0697206e3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -1099,6 +1099,34 @@ public class ActivityRecordTests extends ActivityTestsBase { verify(topActivity).destroyIfPossible(anyString()); } + /** + * Verify the visibility of a show-when-locked and dismiss keyguard activity on sleeping + * display. + */ + @Test + public void testDisplaySleeping_activityInvisible() { + final KeyguardController keyguardController = + mActivity.mStackSupervisor.getKeyguardController(); + doReturn(true).when(keyguardController).isKeyguardLocked(); + final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build(); + topActivity.mVisibleRequested = true; + topActivity.nowVisible = true; + topActivity.setState(RESUMED, "test" /*reason*/); + doReturn(true).when(topActivity).containsDismissKeyguardWindow(); + doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible( + any() /* starting */, anyInt() /* configChanges */, + anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */); + topActivity.setShowWhenLocked(true); + + // Verify the top activity is occluded keyguard. + assertEquals(topActivity, mStack.topRunningActivity()); + assertTrue(mStack.topActivityOccludesKeyguard()); + + final DisplayContent display = mActivity.mDisplayContent; + doReturn(true).when(display).isSleeping(); + assertFalse(topActivity.shouldBeVisible()); + } + /** * Verify that complete finish request for a show-when-locked activity must ensure the * keyguard occluded state being updated. -- GitLab From a845acf97df0afd7c7ce58fedd81fa81eb7b12e2 Mon Sep 17 00:00:00 2001 From: Sean Pont Date: Wed, 12 Aug 2020 13:42:52 -0700 Subject: [PATCH 210/536] Prevent re-use of dismissed wallet view Rotation is disabled when wallet view is shown, but other interactions (ie with Android Auto) cause ui mode change. Preventing re-use of the wallet view controller after it has been dismissed ensures that the view will not be re-attached to a different parent. Fixes: b/162676641 Test: atest GlobalActionsDialogTest Test: manual - enable rotation when wallet is shown (code change) and rotate. Change-Id: I03591d11cf746f264e71e70585370a5dcdfb67a9 (cherry picked from commit 9294bd646ffdae76b458986fa1a602c516e25fbb) --- .../globalactions/GlobalActionsDialog.java | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index ef51abb1404d..0554dc80cba5 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -148,6 +148,7 @@ import java.util.Set; import java.util.concurrent.Executor; import javax.inject.Inject; +import javax.inject.Provider; /** * Helper to show the global actions dialog. Each item is an {@link Action} that may show depending @@ -401,7 +402,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, if (mDialog != null) { if (!mDialog.isShowingControls() && shouldShowControls()) { mDialog.showControls(mControlsUiControllerOptional.get()); - } else if (shouldShowLockMessage()) { + } else if (shouldShowLockMessage(mDialog)) { mDialog.showLockMessage(); } } @@ -698,19 +699,17 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mPowerAdapter = new MyPowerOptionsAdapter(); mDepthController.setShowingHomeControls(true); - GlobalActionsPanelPlugin.PanelViewController walletViewController = - getWalletViewController(); ControlsUiController uiController = null; if (mControlsUiControllerOptional.isPresent() && shouldShowControls()) { uiController = mControlsUiControllerOptional.get(); } ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, mOverflowAdapter, - walletViewController, mDepthController, mSysuiColorExtractor, + this::getWalletViewController, mDepthController, mSysuiColorExtractor, mStatusBarService, mNotificationShadeWindowController, controlsAvailable(), uiController, mSysUiState, this::onRotate, mKeyguardShowing, mPowerAdapter); - if (shouldShowLockMessage()) { + if (shouldShowLockMessage(dialog)) { dialog.showLockMessage(); } dialog.setCanceledOnTouchOutside(false); // Handled by the custom class. @@ -2124,7 +2123,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private MultiListLayout mGlobalActionsLayout; private Drawable mBackgroundDrawable; private final SysuiColorExtractor mColorExtractor; - private final GlobalActionsPanelPlugin.PanelViewController mWalletViewController; + private final Provider mWalletFactory; + @Nullable private GlobalActionsPanelPlugin.PanelViewController mWalletViewController; private boolean mKeyguardShowing; private boolean mShowing; private float mScrimAlpha; @@ -2144,7 +2144,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private TextView mLockMessage; ActionsDialog(Context context, MyAdapter adapter, MyOverflowAdapter overflowAdapter, - GlobalActionsPanelPlugin.PanelViewController walletViewController, + Provider walletFactory, NotificationShadeDepthController depthController, SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService, NotificationShadeWindowController notificationShadeWindowController, @@ -2165,6 +2165,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mSysUiState = sysuiState; mOnRotateCallback = onRotateCallback; mKeyguardShowing = keyguardShowing; + mWalletFactory = walletFactory; // Window initialization Window window = getWindow(); @@ -2187,7 +2188,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, window.getAttributes().setFitInsetsTypes(0 /* types */); setTitle(R.string.global_actions); - mWalletViewController = walletViewController; initializeLayout(); } @@ -2200,8 +2200,13 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mControlsUiController.show(mControlsView, this::dismissForControlsActivity); } + private boolean isWalletViewAvailable() { + return mWalletViewController != null && mWalletViewController.getPanelContent() != null; + } + private void initializeWalletView() { - if (mWalletViewController == null || mWalletViewController.getPanelContent() == null) { + mWalletViewController = mWalletFactory.get(); + if (!isWalletViewAvailable()) { return; } @@ -2507,6 +2512,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private void dismissWallet() { if (mWalletViewController != null) { mWalletViewController.onDismissed(); + // The wallet controller should not be re-used after being dismissed. + mWalletViewController = null; } } @@ -2648,18 +2655,12 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, && !mControlsServiceInfos.isEmpty(); } - private boolean walletViewAvailable() { - GlobalActionsPanelPlugin.PanelViewController walletViewController = - getWalletViewController(); - return walletViewController != null && walletViewController.getPanelContent() != null; - } - - private boolean shouldShowLockMessage() { + private boolean shouldShowLockMessage(ActionsDialog dialog) { boolean isLockedAfterBoot = mLockPatternUtils.getStrongAuthForUser(getCurrentUser().id) == STRONG_AUTH_REQUIRED_AFTER_BOOT; return !mKeyguardStateController.isUnlocked() && (!mShowLockScreenCardsAndControls || isLockedAfterBoot) - && (controlsAvailable() || walletViewAvailable()); + && (controlsAvailable() || dialog.isWalletViewAvailable()); } private void onPowerMenuLockScreenSettingsChanged() { -- GitLab From b18a2fccc359c5deba515c6c4aa5d0e51719e51a Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Thu, 13 Aug 2020 20:19:53 -0700 Subject: [PATCH 211/536] Rename game driver to updatable driver. Game driver is considered a production name. We should use the term updatable driver instead of the production name. Bug: b/164449016 Test: build Change-Id: I787f97b4801dcc7b5ec2acd569a7ce284c9a1f18 --- core/java/android/os/GraphicsEnvironment.java | 103 ++++++++++-------- core/java/android/provider/Settings.java | 46 ++++---- core/proto/android/app/settings_enums.proto | 4 +- .../android/providers/settings/global.proto | 39 +++---- .../settings/SettingsProtoDumpUtil.java | 32 +++--- .../android/provider/SettingsBackupTest.java | 16 +-- .../server/am/CoreSettingsObserver.java | 21 ++-- .../com/android/server/gpu/GpuService.java | 51 +++++---- 8 files changed, 168 insertions(+), 144 deletions(-) diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index a6b869d19867..1eb3fc11df7b 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -64,10 +64,11 @@ public class GraphicsEnvironment { private static final String SYSTEM_DRIVER_NAME = "system"; private static final String SYSTEM_DRIVER_VERSION_NAME = ""; private static final long SYSTEM_DRIVER_VERSION_CODE = 0; - private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0"; + private static final String PROPERTY_GFX_DRIVER_PRODUCTION = "ro.gfx.driver.0"; private static final String PROPERTY_GFX_DRIVER_PRERELEASE = "ro.gfx.driver.1"; private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time"; - private static final String METADATA_DRIVER_BUILD_TIME = "com.android.gamedriver.build_time"; + private static final String METADATA_DRIVER_BUILD_TIME = + "com.android.graphics.updatabledriver.build_time"; private static final String METADATA_DEVELOPER_DRIVER_ENABLE = "com.android.graphics.developerdriver.enable"; private static final String METADATA_INJECT_LAYERS_ENABLE = @@ -78,20 +79,20 @@ public class GraphicsEnvironment { private static final String ACTION_ANGLE_FOR_ANDROID_TOAST_MESSAGE = "android.app.action.ANGLE_FOR_ANDROID_TOAST_MESSAGE"; private static final String INTENT_KEY_A4A_TOAST_MESSAGE = "A4A Toast Message"; - private static final String GAME_DRIVER_ALLOWLIST_ALL = "*"; - private static final String GAME_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt"; + private static final String UPDATABLE_DRIVER_ALLOWLIST_ALL = "*"; + private static final String UPDATABLE_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt"; private static final int VULKAN_1_0 = 0x00400000; private static final int VULKAN_1_1 = 0x00401000; - // GAME_DRIVER_ALL_APPS + // UPDATABLE_DRIVER_ALL_APPS // 0: Default (Invalid values fallback to default as well) - // 1: All apps use Game Driver - // 2: All apps use Prerelease Driver + // 1: All apps use updatable production driver + // 2: All apps use updatable prerelease driver // 3: All apps use system graphics driver - private static final int GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT = 0; - private static final int GAME_DRIVER_GLOBAL_OPT_IN_GAME_DRIVER = 1; - private static final int GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2; - private static final int GAME_DRIVER_GLOBAL_OPT_IN_OFF = 3; + private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_DEFAULT = 0; + private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRODUCTION_DRIVER = 1; + private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2; + private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_OFF = 3; private ClassLoader mClassLoader; private String mLibrarySearchPaths; @@ -722,14 +723,17 @@ public class GraphicsEnvironment { * Return the driver package name to use. Return null for system driver. */ private static String chooseDriverInternal(Bundle coreSettings, ApplicationInfo ai) { - final String gameDriver = SystemProperties.get(PROPERTY_GFX_DRIVER); - final boolean hasGameDriver = gameDriver != null && !gameDriver.isEmpty(); + final String productionDriver = SystemProperties.get(PROPERTY_GFX_DRIVER_PRODUCTION); + final boolean hasProductionDriver = productionDriver != null && !productionDriver.isEmpty(); final String prereleaseDriver = SystemProperties.get(PROPERTY_GFX_DRIVER_PRERELEASE); final boolean hasPrereleaseDriver = prereleaseDriver != null && !prereleaseDriver.isEmpty(); - if (!hasGameDriver && !hasPrereleaseDriver) { - if (DEBUG) Log.v(TAG, "Neither Game Driver nor prerelease driver is supported."); + if (!hasProductionDriver && !hasPrereleaseDriver) { + if (DEBUG) { + Log.v(TAG, + "Neither updatable production driver nor prerelease driver is supported."); + } return null; } @@ -745,56 +749,59 @@ public class GraphicsEnvironment { (ai.metaData != null && ai.metaData.getBoolean(METADATA_DEVELOPER_DRIVER_ENABLE)) || isDebuggable(); - // Priority for Game Driver settings global on confliction (Higher priority comes first): - // 1. GAME_DRIVER_ALL_APPS - // 2. GAME_DRIVER_OPT_OUT_APPS - // 3. GAME_DRIVER_PRERELEASE_OPT_IN_APPS - // 4. GAME_DRIVER_OPT_IN_APPS - // 5. GAME_DRIVER_DENYLIST - // 6. GAME_DRIVER_ALLOWLIST - switch (coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0)) { - case GAME_DRIVER_GLOBAL_OPT_IN_OFF: - if (DEBUG) Log.v(TAG, "Game Driver is turned off on this device."); + // Priority of updatable driver settings on confliction (Higher priority comes first): + // 1. UPDATABLE_DRIVER_ALL_APPS + // 2. UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS + // 3. UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS + // 4. UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS + // 5. UPDATABLE_DRIVER_PRODUCTION_DENYLIST + // 6. UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST + switch (coreSettings.getInt(Settings.Global.UPDATABLE_DRIVER_ALL_APPS, 0)) { + case UPDATABLE_DRIVER_GLOBAL_OPT_IN_OFF: + if (DEBUG) Log.v(TAG, "updatable driver is turned off on this device."); return null; - case GAME_DRIVER_GLOBAL_OPT_IN_GAME_DRIVER: - if (DEBUG) Log.v(TAG, "All apps opt in to use Game Driver."); - return hasGameDriver ? gameDriver : null; - case GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER: - if (DEBUG) Log.v(TAG, "All apps opt in to use prerelease driver."); + case UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRODUCTION_DRIVER: + if (DEBUG) Log.v(TAG, "All apps opt in to use updatable production driver."); + return hasProductionDriver ? productionDriver : null; + case UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER: + if (DEBUG) Log.v(TAG, "All apps opt in to use updatable prerelease driver."); return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null; - case GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT: + case UPDATABLE_DRIVER_GLOBAL_OPT_IN_DEFAULT: default: break; } final String appPackageName = ai.packageName; - if (getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_OPT_OUT_APPS) + if (getGlobalSettingsString(null, coreSettings, + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS) .contains(appPackageName)) { - if (DEBUG) Log.v(TAG, "App opts out for Game Driver."); + if (DEBUG) Log.v(TAG, "App opts out for updatable production driver."); return null; } if (getGlobalSettingsString( - null, coreSettings, Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS) + null, coreSettings, Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS) .contains(appPackageName)) { - if (DEBUG) Log.v(TAG, "App opts in for prerelease Game Driver."); + if (DEBUG) Log.v(TAG, "App opts in for updatable prerelease driver."); return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null; } - // Early return here since the rest logic is only for Game Driver. - if (!hasGameDriver) { - if (DEBUG) Log.v(TAG, "Game Driver is not supported on the device."); + // Early return here since the rest logic is only for updatable production Driver. + if (!hasProductionDriver) { + if (DEBUG) Log.v(TAG, "Updatable production driver is not supported on the device."); return null; } final boolean isOptIn = - getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_OPT_IN_APPS) + getGlobalSettingsString(null, coreSettings, + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS) .contains(appPackageName); final List allowlist = - getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_ALLOWLIST); - if (!isOptIn && allowlist.indexOf(GAME_DRIVER_ALLOWLIST_ALL) != 0 + getGlobalSettingsString(null, coreSettings, + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST); + if (!isOptIn && allowlist.indexOf(UPDATABLE_DRIVER_ALLOWLIST_ALL) != 0 && !allowlist.contains(appPackageName)) { - if (DEBUG) Log.v(TAG, "App is not on the allowlist for Game Driver."); + if (DEBUG) Log.v(TAG, "App is not on the allowlist for updatable production driver."); return null; } @@ -802,13 +809,13 @@ public class GraphicsEnvironment { // terminate early if it's on the denylist and fallback to system driver. if (!isOptIn && getGlobalSettingsString( - null, coreSettings, Settings.Global.GAME_DRIVER_DENYLIST) + null, coreSettings, Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST) .contains(appPackageName)) { - if (DEBUG) Log.v(TAG, "App is on the denylist for Game Driver."); + if (DEBUG) Log.v(TAG, "App is on the denylist for updatable production driver."); return null; } - return gameDriver; + return productionDriver; } /** @@ -873,7 +880,7 @@ public class GraphicsEnvironment { final String driverBuildTime = driverAppInfo.metaData.getString(METADATA_DRIVER_BUILD_TIME); if (driverBuildTime == null || driverBuildTime.isEmpty()) { - throw new IllegalArgumentException("com.android.gamedriver.build_time is not set"); + Log.v(TAG, "com.android.graphics.updatabledriver.build_time is not set"); } // driver_build_time in the meta-data is in "L" format. e.g. L123456. // Long.parseLong will throw if the meta-data "driver_build_time" is not set properly. @@ -901,7 +908,7 @@ public class GraphicsEnvironment { final Context driverContext = context.createPackageContext(driverPackageName, Context.CONTEXT_RESTRICTED); final BufferedReader reader = new BufferedReader(new InputStreamReader( - driverContext.getAssets().open(GAME_DRIVER_SPHAL_LIBRARIES_FILENAME))); + driverContext.getAssets().open(UPDATABLE_DRIVER_SPHAL_LIBRARIES_FILENAME))); final ArrayList assetStrings = new ArrayList<>(); for (String assetString; (assetString = reader.readLine()) != null;) { assetStrings.add(assetString); @@ -913,7 +920,7 @@ public class GraphicsEnvironment { } } catch (IOException e) { if (DEBUG) { - Log.w(TAG, "Failed to load '" + GAME_DRIVER_SPHAL_LIBRARIES_FILENAME + "'"); + Log.w(TAG, "Failed to load '" + UPDATABLE_DRIVER_SPHAL_LIBRARIES_FILENAME + "'"); } } return ""; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index dda5c5ede53f..a760dc677437 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -12291,63 +12291,71 @@ public final class Settings { "show_angle_in_use_dialog_box"; /** - * Game Driver global preference for all Apps. + * Updatable driver global preference for all Apps. * 0 = Default - * 1 = All Apps use Game Driver - * 2 = All Apps use system graphics driver + * 1 = All Apps use updatable production driver + * 2 = All apps use updatable prerelease driver + * 3 = All Apps use system graphics driver * @hide */ - public static final String GAME_DRIVER_ALL_APPS = "game_driver_all_apps"; + public static final String UPDATABLE_DRIVER_ALL_APPS = "updatable_driver_all_apps"; /** - * List of Apps selected to use Game Driver. + * List of Apps selected to use updatable production driver. * i.e. ,,..., * @hide */ - public static final String GAME_DRIVER_OPT_IN_APPS = "game_driver_opt_in_apps"; + public static final String UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS = + "updatable_driver_production_opt_in_apps"; /** - * List of Apps selected to use prerelease Game Driver. + * List of Apps selected to use updatable prerelease driver. * i.e. ,,..., * @hide */ - public static final String GAME_DRIVER_PRERELEASE_OPT_IN_APPS = - "game_driver_prerelease_opt_in_apps"; + public static final String UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS = + "updatable_driver_prerelease_opt_in_apps"; /** - * List of Apps selected not to use Game Driver. + * List of Apps selected not to use updatable production driver. * i.e. ,,..., * @hide */ - public static final String GAME_DRIVER_OPT_OUT_APPS = "game_driver_opt_out_apps"; + public static final String UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS = + "updatable_driver_production_opt_out_apps"; /** - * Apps on the denylist that are forbidden to use Game Driver. + * Apps on the denylist that are forbidden to use updatable production driver. * @hide */ - public static final String GAME_DRIVER_DENYLIST = "game_driver_denylist"; + public static final String UPDATABLE_DRIVER_PRODUCTION_DENYLIST = + "updatable_driver_production_denylist"; /** - * List of denylists, each denylist is a denylist for a specific version of Game Driver. + * List of denylists, each denylist is a denylist for a specific version of + * updatable production driver. * @hide */ - public static final String GAME_DRIVER_DENYLISTS = "game_driver_denylists"; + public static final String UPDATABLE_DRIVER_PRODUCTION_DENYLISTS = + "updatable_driver_production_denylists"; /** - * Apps on the allowlist that are allowed to use Game Driver. + * Apps on the allowlist that are allowed to use updatable production driver. * The string is a list of application package names, seperated by comma. * i.e. ,,..., * @hide */ - public static final String GAME_DRIVER_ALLOWLIST = "game_driver_allowlist"; + public static final String UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST = + "updatable_driver_production_allowlist"; /** - * List of libraries in sphal accessible by Game Driver + * List of libraries in sphal accessible by updatable driver * The string is a list of library names, separated by colon. * i.e. ::...: * @hide */ - public static final String GAME_DRIVER_SPHAL_LIBRARIES = "game_driver_sphal_libraries"; + public static final String UPDATABLE_DRIVER_SPHAL_LIBRARIES = + "updatable_driver_sphal_libraries"; /** * Ordered GPU debug layer list for Vulkan diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto index 69b32c264d3d..b3b464de9437 100644 --- a/core/proto/android/app/settings_enums.proto +++ b/core/proto/android/app/settings_enums.proto @@ -2310,10 +2310,10 @@ enum PageId { // OS: Q ZEN_CUSTOM_SETTINGS_DIALOG = 1612; - // OPEN: Settings > Developer Options > Game Driver Preferences + // OPEN: Settings > Developer Options > Graphics Driver Preferences // CATEGORY: SETTINGS // OS: Q - SETTINGS_GAME_DRIVER_DASHBOARD = 1613; + SETTINGS_GRAPHICS_DRIVER_DASHBOARD = 1613; // OPEN: Settings > Accessibility > Vibration > Ring vibration // CATEGORY: SETTINGS diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index a80bb4013854..171a14bfe301 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -433,35 +433,36 @@ message GlobalSettingsProto { // Ordered GPU debug layer list for GLES // i.e. ::...: optional SettingProto debug_layers_gles = 7; - // Game Driver - global preference for all Apps + // Updatable Driver - global preference for all Apps // 0 = Default - // 1 = All Apps use Game Driver - // 2 = All Apps use system graphics driver - optional SettingProto game_driver_all_apps = 8; - // Game Driver - List of Apps selected to use Game Driver + // 1 = All Apps use updatable production driver + // 2 = All apps use updatable prerelease driver + // 3 = All Apps use system graphics driver + optional SettingProto updatable_driver_all_apps = 8; + // Updatable Driver - List of Apps selected to use updatable production driver // i.e. ,,..., - optional SettingProto game_driver_opt_in_apps = 9; - // Game Driver - List of Apps selected not to use Game Driver + optional SettingProto updatable_driver_production_opt_in_apps = 9; + // Updatable Driver - List of Apps selected not to use updatable production driver // i.e. ,,..., - optional SettingProto game_driver_opt_out_apps = 10; - // Game Driver - List of Apps that are forbidden to use Game Driver - optional SettingProto game_driver_denylist = 11; - // Game Driver - List of Apps that are allowed to use Game Driver - optional SettingProto game_driver_allowlist = 12; + optional SettingProto updatable_driver_production_opt_out_apps = 10; + // Updatable Driver - List of Apps that are forbidden to use updatable production driver + optional SettingProto updatable_driver_production_denylist = 11; + // Updatable Driver - List of Apps that are allowed to use updatable production driver + optional SettingProto updatable_driver_production_allowlist = 12; // ANGLE - List of Apps that can check ANGLE rules optional SettingProto angle_allowlist = 13; - // Game Driver - List of denylists, each denylist is a denylist for - // a specific Game Driver version - optional SettingProto game_driver_denylists = 14; + // Updatable Driver - List of denylists, each denylist is a denylist for + // a specific updatable production driver version + optional SettingProto updatable_driver_production_denylists = 14; // ANGLE - Show a dialog box when ANGLE is selected for the currently running PKG optional SettingProto show_angle_in_use_dialog = 15; - // Game Driver - List of libraries in sphal accessible by Game Driver - optional SettingProto game_driver_sphal_libraries = 16; + // Updatable Driver - List of libraries in sphal accessible by updatable driver + optional SettingProto updatable_driver_sphal_libraries = 16; // ANGLE - External package containing ANGLE libraries optional SettingProto angle_debug_package = 17; - // Game Driver - List of Apps selected to use prerelease Game Driver + // Updatable Driver - List of Apps selected to use updatable prerelease driver // i.e. ,,..., - optional SettingProto game_driver_prerelease_opt_in_apps = 18; + optional SettingProto updatable_driver_prerelease_opt_in_apps = 18; } optional Gpu gpu = 59; diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index 7c198c88d5b6..779293fb2f61 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -773,29 +773,29 @@ class SettingsProtoDumpUtil { Settings.Global.GPU_DEBUG_LAYERS_GLES, GlobalSettingsProto.Gpu.DEBUG_LAYERS_GLES); dumpSetting(s, p, - Settings.Global.GAME_DRIVER_ALL_APPS, - GlobalSettingsProto.Gpu.GAME_DRIVER_ALL_APPS); + Settings.Global.UPDATABLE_DRIVER_ALL_APPS, + GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_ALL_APPS); dumpSetting(s, p, - Settings.Global.GAME_DRIVER_OPT_IN_APPS, - GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_IN_APPS); + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS, + GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS); dumpSetting(s, p, - Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS, - GlobalSettingsProto.Gpu.GAME_DRIVER_PRERELEASE_OPT_IN_APPS); + Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS, + GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS); dumpSetting(s, p, - Settings.Global.GAME_DRIVER_OPT_OUT_APPS, - GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_OUT_APPS); + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS, + GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS); dumpSetting(s, p, - Settings.Global.GAME_DRIVER_DENYLIST, - GlobalSettingsProto.Gpu.GAME_DRIVER_DENYLIST); + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST, + GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRODUCTION_DENYLIST); dumpSetting(s, p, - Settings.Global.GAME_DRIVER_ALLOWLIST, - GlobalSettingsProto.Gpu.GAME_DRIVER_ALLOWLIST); + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST, + GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST); dumpSetting(s, p, - Settings.Global.GAME_DRIVER_DENYLISTS, - GlobalSettingsProto.Gpu.GAME_DRIVER_DENYLISTS); + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS, + GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS); dumpSetting(s, p, - Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, - GlobalSettingsProto.Gpu.GAME_DRIVER_SPHAL_LIBRARIES); + Settings.Global.UPDATABLE_DRIVER_SPHAL_LIBRARIES, + GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_SPHAL_LIBRARIES); p.end(gpuToken); final long hdmiToken = p.start(GlobalSettingsProto.HDMI); diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index d20e14e62f52..1d07734ec1fc 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -504,14 +504,14 @@ public class SettingsBackupTest { Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES, Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST, - Settings.Global.GAME_DRIVER_ALL_APPS, - Settings.Global.GAME_DRIVER_OPT_IN_APPS, - Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS, - Settings.Global.GAME_DRIVER_OPT_OUT_APPS, - Settings.Global.GAME_DRIVER_DENYLISTS, - Settings.Global.GAME_DRIVER_DENYLIST, - Settings.Global.GAME_DRIVER_ALLOWLIST, - Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, + Settings.Global.UPDATABLE_DRIVER_ALL_APPS, + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS, + Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS, + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS, + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS, + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST, + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST, + Settings.Global.UPDATABLE_DRIVER_SPHAL_LIBRARIES, Settings.Global.GLOBAL_SETTINGS_SHOW_ANGLE_IN_USE_DIALOG_BOX, Settings.Global.GPU_DEBUG_LAYER_APP, Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING, diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java index 2661dd62ce21..4e938abb7d0d 100644 --- a/services/core/java/com/android/server/am/CoreSettingsObserver.java +++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java @@ -100,15 +100,20 @@ final class CoreSettingsObserver extends ContentObserver { sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYERS, String.class); sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYERS_GLES, String.class); sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYER_APP, String.class); - sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_ALL_APPS, int.class); - sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_IN_APPS, String.class); + sGlobalSettingToTypeMap.put(Settings.Global.UPDATABLE_DRIVER_ALL_APPS, int.class); sGlobalSettingToTypeMap.put( - Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS, String.class); - sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_OUT_APPS, String.class); - sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_DENYLIST, String.class); - sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_ALLOWLIST, String.class); - sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_DENYLISTS, String.class); - sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, String.class); + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS, String.class); + sGlobalSettingToTypeMap.put( + Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS, String.class); + sGlobalSettingToTypeMap.put( + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS, String.class); + sGlobalSettingToTypeMap.put( + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST, String.class); + sGlobalSettingToTypeMap.put( + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST, String.class); + sGlobalSettingToTypeMap.put( + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS, String.class); + sGlobalSettingToTypeMap.put(Settings.Global.UPDATABLE_DRIVER_SPHAL_LIBRARIES, String.class); // add other global settings here... sDeviceConfigEntries.add(new DeviceConfigEntry( diff --git a/services/core/java/com/android/server/gpu/GpuService.java b/services/core/java/com/android/server/gpu/GpuService.java index c0617ca95f9f..54794fecbf5b 100644 --- a/services/core/java/com/android/server/gpu/GpuService.java +++ b/services/core/java/com/android/server/gpu/GpuService.java @@ -65,7 +65,7 @@ public class GpuService extends SystemService { private static final String PROD_DRIVER_PROPERTY = "ro.gfx.driver.0"; private static final String DEV_DRIVER_PROPERTY = "ro.gfx.driver.1"; - private static final String GAME_DRIVER_ALLOWLIST_FILENAME = "allowlist.txt"; + private static final String UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST_FILENAME = "allowlist.txt"; private static final int BASE64_FLAGS = Base64.NO_PADDING | Base64.NO_WRAP; private final Context mContext; @@ -77,7 +77,7 @@ public class GpuService extends SystemService { private final boolean mHasProdDriver; private final boolean mHasDevDriver; private ContentResolver mContentResolver; - private long mGameDriverVersionCode; + private long mProdDriverVersionCode; private SettingsObserver mSettingsObserver; private DeviceConfigListener mDeviceConfigListener; @GuardedBy("mLock") @@ -88,7 +88,7 @@ public class GpuService extends SystemService { mContext = context; mProdDriverPackageName = SystemProperties.get(PROD_DRIVER_PROPERTY); - mGameDriverVersionCode = -1; + mProdDriverVersionCode = -1; mDevDriverPackageName = SystemProperties.get(DEV_DRIVER_PROPERTY); mPackageManager = context.getPackageManager(); mHasProdDriver = !TextUtils.isEmpty(mProdDriverPackageName); @@ -117,20 +117,20 @@ public class GpuService extends SystemService { } mSettingsObserver = new SettingsObserver(); mDeviceConfigListener = new DeviceConfigListener(); - fetchGameDriverPackageProperties(); + fetchProductionDriverPackageProperties(); processDenylists(); setDenylist(); - fetchDeveloperDriverPackageProperties(); + fetchPrereleaseDriverPackageProperties(); } } private final class SettingsObserver extends ContentObserver { - private final Uri mGameDriverDenylistsUri = - Settings.Global.getUriFor(Settings.Global.GAME_DRIVER_DENYLISTS); + private final Uri mProdDriverDenylistsUri = + Settings.Global.getUriFor(Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS); SettingsObserver() { super(new Handler()); - mContentResolver.registerContentObserver(mGameDriverDenylistsUri, false, this, + mContentResolver.registerContentObserver(mProdDriverDenylistsUri, false, this, UserHandle.USER_ALL); } @@ -140,7 +140,7 @@ public class GpuService extends SystemService { return; } - if (mGameDriverDenylistsUri.equals(uri)) { + if (mProdDriverDenylistsUri.equals(uri)) { processDenylists(); setDenylist(); } @@ -157,9 +157,11 @@ public class GpuService extends SystemService { @Override public void onPropertiesChanged(Properties properties) { synchronized (mDeviceConfigLock) { - if (properties.getKeyset().contains(Settings.Global.GAME_DRIVER_DENYLISTS)) { + if (properties.getKeyset().contains( + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS)) { parseDenylists( - properties.getString(Settings.Global.GAME_DRIVER_DENYLISTS, "")); + properties.getString( + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS, "")); setDenylist(); } } @@ -186,10 +188,10 @@ public class GpuService extends SystemService { case ACTION_PACKAGE_CHANGED: case ACTION_PACKAGE_REMOVED: if (isProdDriver) { - fetchGameDriverPackageProperties(); + fetchProductionDriverPackageProperties(); setDenylist(); } else if (isDevDriver) { - fetchDeveloperDriverPackageProperties(); + fetchPrereleaseDriverPackageProperties(); } break; default: @@ -218,7 +220,7 @@ public class GpuService extends SystemService { } } - private void fetchGameDriverPackageProperties() { + private void fetchProductionDriverPackageProperties() { final ApplicationInfo driverInfo; try { driverInfo = mPackageManager.getApplicationInfo(mProdDriverPackageName, @@ -241,15 +243,16 @@ public class GpuService extends SystemService { // Reset the allowlist. Settings.Global.putString(mContentResolver, - Settings.Global.GAME_DRIVER_ALLOWLIST, ""); - mGameDriverVersionCode = driverInfo.longVersionCode; + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST, ""); + mProdDriverVersionCode = driverInfo.longVersionCode; try { final Context driverContext = mContext.createPackageContext(mProdDriverPackageName, Context.CONTEXT_RESTRICTED); - assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_ALLOWLIST_FILENAME, - Settings.Global.GAME_DRIVER_ALLOWLIST, ","); + assetToSettingsGlobal(mContext, driverContext, + UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST_FILENAME, + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST, ","); } catch (PackageManager.NameNotFoundException e) { if (DEBUG) { Slog.w(TAG, "driver package '" + mProdDriverPackageName + "' not installed"); @@ -259,11 +262,11 @@ public class GpuService extends SystemService { private void processDenylists() { String base64String = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_GAME_DRIVER, - Settings.Global.GAME_DRIVER_DENYLISTS); + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS); if (base64String == null) { base64String = Settings.Global.getString(mContentResolver, - Settings.Global.GAME_DRIVER_DENYLISTS); + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS); } parseDenylists(base64String != null ? base64String : ""); } @@ -288,16 +291,16 @@ public class GpuService extends SystemService { private void setDenylist() { Settings.Global.putString(mContentResolver, - Settings.Global.GAME_DRIVER_DENYLIST, ""); + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST, ""); synchronized (mLock) { if (mDenylists == null) { return; } List denylists = mDenylists.getDenylistsList(); for (Denylist denylist : denylists) { - if (denylist.getVersionCode() == mGameDriverVersionCode) { + if (denylist.getVersionCode() == mProdDriverVersionCode) { Settings.Global.putString(mContentResolver, - Settings.Global.GAME_DRIVER_DENYLIST, + Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST, String.join(",", denylist.getPackageNamesList())); return; } @@ -305,7 +308,7 @@ public class GpuService extends SystemService { } } - private void fetchDeveloperDriverPackageProperties() { + private void fetchPrereleaseDriverPackageProperties() { final ApplicationInfo driverInfo; try { driverInfo = mPackageManager.getApplicationInfo(mDevDriverPackageName, -- GitLab From cbc302a86e702ba15d446dc38793db838fd0b109 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Thu, 16 Jul 2020 10:08:25 -0700 Subject: [PATCH 212/536] VIS : SoundTriggerService: fix fake AudioRecord creation Make sure exceptions that can occur when creating the fake AudioRecord instance in SoundTriggerService.createAudioRecordForEvent() are caught. Bug: 161375011 Test: Manual sound trigger regression with OK Google and Now Playing Squashed commit of: a82281f6e7643ba08276de8181d44df11ecf8ae7 1a6689766af6831f0ba6b6a01d245caf4ef438c6 Change-Id: Ib973e22a5f1bd43facca1ed8c282fe444a739249 Merged-In: Ie367b9dda6f9e4f3079f5afe2ac92fc98cf8bced --- .../soundtrigger/SoundTriggerService.java | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java index 6c13cd799bc2..20e0cfe41791 100644 --- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java +++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java @@ -1284,32 +1284,25 @@ public class SoundTriggerService extends SystemService { * @return The initialized AudioRecord */ private @NonNull AudioRecord createAudioRecordForEvent( - @NonNull SoundTrigger.GenericRecognitionEvent event) { + @NonNull SoundTrigger.GenericRecognitionEvent event) + throws IllegalArgumentException, UnsupportedOperationException { AudioAttributes.Builder attributesBuilder = new AudioAttributes.Builder(); attributesBuilder.setInternalCapturePreset(MediaRecorder.AudioSource.HOTWORD); AudioAttributes attributes = attributesBuilder.build(); - // Use same AudioFormat processing as in RecognitionEvent.fromParcel AudioFormat originalFormat = event.getCaptureFormat(); - AudioFormat captureFormat = (new AudioFormat.Builder()) - .setChannelMask(originalFormat.getChannelMask()) - .setEncoding(originalFormat.getEncoding()) - .setSampleRate(originalFormat.getSampleRate()) - .build(); - - int bufferSize = AudioRecord.getMinBufferSize( - captureFormat.getSampleRate() == AudioFormat.SAMPLE_RATE_UNSPECIFIED - ? AudioFormat.SAMPLE_RATE_HZ_MAX - : captureFormat.getSampleRate(), - captureFormat.getChannelCount() == 2 - ? AudioFormat.CHANNEL_IN_STEREO - : AudioFormat.CHANNEL_IN_MONO, - captureFormat.getEncoding()); sEventLogger.log(new SoundTriggerLogger.StringEvent("createAudioRecordForEvent")); - return new AudioRecord(attributes, captureFormat, bufferSize, - event.getCaptureSession()); + return (new AudioRecord.Builder()) + .setAudioAttributes(attributes) + .setAudioFormat((new AudioFormat.Builder()) + .setChannelMask(originalFormat.getChannelMask()) + .setEncoding(originalFormat.getEncoding()) + .setSampleRate(originalFormat.getSampleRate()) + .build()) + .setSessionId(event.getCaptureSession()) + .build(); } @Override @@ -1335,12 +1328,16 @@ public class SoundTriggerService extends SystemService { // execute if throttled: () -> { if (event.isCaptureAvailable()) { - AudioRecord capturedData = createAudioRecordForEvent(event); - - // Currently we need to start and release the audio record to reset - // the DSP even if we don't want to process the event - capturedData.startRecording(); - capturedData.release(); + try { + // Currently we need to start and release the audio record to reset + // the DSP even if we don't want to process the eve + AudioRecord capturedData = createAudioRecordForEvent(event); + capturedData.startRecording(); + capturedData.release(); + } catch (IllegalArgumentException | UnsupportedOperationException e) { + Slog.w(TAG, mPuuid + ": createAudioRecordForEvent(" + event + + "), failed to create AudioRecord"); + } } })); } -- GitLab From 39bcfc7c83f39e6e7c0d8f7496864f989907f259 Mon Sep 17 00:00:00 2001 From: Agatha Man Date: Tue, 4 Aug 2020 16:25:48 -0700 Subject: [PATCH 213/536] Remove car permissions from common shell package Removing car permissions that were added into common shell so that they can be re-evaulated to include into CarShell. Adding car permissions to shell should be reviewed by car frameworks team to determine what can be allowed to the end-user and in terms of car safety. Bug: 160339243 Test: make then check permission for shell user with adb shell pm dump com.android.shell Change-Id: I5a3b2086f605ba31f4231ec425cb2cb7c51ea7e6 (cherry picked from commit 89e5cfe9d8f9eb179ba3c3e2d4a3260ba3f0c470) Merged-In: I5a3b2086f605ba31f4231ec425cb2cb7c51ea7e6 --- data/etc/privapp-permissions-platform.xml | 12 ------------ packages/Shell/AndroidManifest.xml | 13 ------------- 2 files changed, 25 deletions(-) diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 4325ef4bd2df..e08e42aec391 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -431,18 +431,6 @@ applications that come with the platform - - - - - - - - - - - - diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index b142cfb7413c..570c2ab3efd1 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -317,19 +317,6 @@ - - - - - - - - - - - - - Date: Fri, 14 Aug 2020 15:05:33 -0400 Subject: [PATCH 214/536] Use theme color for screenshot UI icons Bug: 162377061 Fix: 162377061 Test: manual (tested in light/dark modes, ensured that smart screenshot actions are not tinted) Change-Id: I00b2cb91af1df057501d35394f1c6ab63990f8d5 --- .../SystemUI/res/layout/global_screenshot_action_chip.xml | 1 + .../android/systemui/screenshot/ScreenshotActionChip.java | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml index 46396e3e62b4..4b3534b1cbc8 100644 --- a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml +++ b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml @@ -32,6 +32,7 @@ android:gravity="center"> Date: Fri, 14 Aug 2020 20:57:48 +0000 Subject: [PATCH 215/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I91b9b0733774de4695ba160caa3e02b863441ab0 --- core/res/res/values-as/strings.xml | 8 ++++---- core/res/res/values-bn/strings.xml | 8 ++++---- core/res/res/values-gu/strings.xml | 2 +- core/res/res/values-kn/strings.xml | 8 ++++---- core/res/res/values-ml/strings.xml | 8 ++++---- core/res/res/values-mr/strings.xml | 8 ++++---- core/res/res/values-or/strings.xml | 8 ++++---- core/res/res/values-sq/strings.xml | 2 +- core/res/res/values-te/strings.xml | 8 ++++---- core/res/res/values-vi/strings.xml | 8 ++++---- 10 files changed, 34 insertions(+), 34 deletions(-) diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index cbafe4f1ee1f..4ff2a6a062ec 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -980,9 +980,9 @@ "স্পেচ" "লিখক" "মচক" - "অনুসন্ধান কৰক" + "Search" "অনুসন্ধান কৰক…" - "অনুসন্ধান কৰক" + "Search" "প্ৰশ্নৰ সন্ধান কৰক" "প্ৰশ্ন মচক" "প্ৰশ্ন দাখিল কৰক" @@ -1398,7 +1398,7 @@ "জুম নিয়ন্ত্ৰণ কৰিবলৈ দুবাৰ টিপক" "ৱিজেট যোগ কৰিব পৰা নগ\'ল।" "যাওক" - "অনুসন্ধান কৰক" + "Search" "পঠিয়াওক" "পৰৱৰ্তী" "সম্পন্ন হ’ল" @@ -1881,7 +1881,7 @@ "প্ৰস্তাৱিত" "সকলো ভাষা" "সকলো অঞ্চল" - "অনুসন্ধান কৰক" + "Search" "এপটো নাই" "এই মুহূৰ্তত %1$s উপলব্ধ নহয়। ইয়াক %2$sএ পৰিচালনা কৰে।" "অধিক জানক" diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 09b69db879e7..1b75ac21ed01 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -980,9 +980,9 @@ "স্পেস" "enter" "মুছুন" - "খুঁজুন" + "সার্চ" "সার্চ করুন..." - "খুঁজুন" + "সার্চ" "সার্চ ক্যোয়ারী" "ক্যোয়ারী সাফ করুন" "ক্যোয়ারী জমা দিন" @@ -1398,7 +1398,7 @@ "জুম নিয়ন্ত্রণের জন্য দুবার ট্যাপ করুন" "উইজেট যোগ করা যায়নি৷" "যান" - "খুঁজুন" + "সার্চ" "পাঠান" "পরবর্তী" "সম্পন্ন হয়েছে" @@ -1881,7 +1881,7 @@ "প্রস্তাবিত" "সকল ভাষা" "সমস্ত অঞ্চল" - "খুঁজুন" + "সার্চ" "অ্যাপটি উপলভ্য নয়" "%1$s এখন উপলভ্য নয়। এই অ্যাপটিকে %2$s অ্যাপ ম্যানেজ করে।" "আরও জানুন" diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 6ef746dfd105..5ba54d3ab9e2 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -982,7 +982,7 @@ "ડિલીટ કરો" "શોધો" "શોધો…" - "શોધ" + "શોધો" "શોધ ક્વેરી" "ક્વેરી સાફ કરો" "ક્વેરી સબમિટ કરો" diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index fc60da764c42..4386a3d8da6f 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -980,9 +980,9 @@ "space" "enter" "ಅಳಿಸಿ" - "ಹುಡುಕಿ" + "Search" "ಹುಡುಕಿ…" - "ಹುಡುಕಿ" + "Search" "ಪ್ರಶ್ನೆಯನ್ನು ಹುಡುಕಿ" "ಪ್ರಶ್ನೆಯನ್ನು ತೆರವುಗೊಳಿಸು" "ಪ್ರಶ್ನೆಯನ್ನು ಸಲ್ಲಿಸು" @@ -1398,7 +1398,7 @@ "ಝೂಮ್‌ ನಿಯಂತ್ರಿಸಲು ಎರಡು ಬಾರಿ ಟ್ಯಾಪ್ ಮಾಡಿ" "ವಿಜೆಟ್ ಸೇರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ." "ಹೋಗು" - "ಹುಡುಕಿ" + "Search" "ಕಳುಹಿಸು" "ಮುಂದೆ" "ಮುಗಿದಿದೆ" @@ -1881,7 +1881,7 @@ "ಸೂಚಿತ ಭಾಷೆ" "ಎಲ್ಲಾ ಭಾಷೆಗಳು" "ಎಲ್ಲಾ ಪ್ರದೇಶಗಳು" - "ಹುಡುಕಿ" + "Search" "ಅಪ್ಲಿಕೇಶನ್ ಲಭ್ಯವಿಲ್ಲ" "%1$s ಅಪ್ಲಿಕೇಶನ್‌ ಸದ್ಯಕ್ಕೆ ಲಭ್ಯವಿಲ್ಲ. ಇದನ್ನು %2$s ನಲ್ಲಿ ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ." "ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ" diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 3ccd9ecef552..94ac5ca66e34 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -980,9 +980,9 @@ "space" "enter" "delete" - "തിരയൽ" + "Search" "തിരയുക…" - "തിരയൽ" + "Search" "തിരയൽ അന്വേഷണം" "അന്വേഷണം മായ്‌ക്കുക" "ചോദ്യം സമർപ്പിക്കുക" @@ -1398,7 +1398,7 @@ "സൂം നിയന്ത്രണം ലഭിക്കാൻ രണ്ടുതവണ ടാപ്പുചെയ്യുക" "വിജറ്റ് ചേർക്കാനായില്ല." "പോവുക" - "തിരയൽ" + "Search" "അയയ്‌ക്കുക" "അടുത്തത്" "പൂർത്തിയായി" @@ -1881,7 +1881,7 @@ "നിര്‍‌ദ്ദേശിച്ചത്" "എല്ലാ ഭാഷകളും" "എല്ലാ പ്രദേശങ്ങളും" - "തിരയുക" + "Search" "ആപ്പ് ലഭ്യമല്ല" "%1$s ഇപ്പോൾ ലഭ്യമല്ല. %2$s ആണ് ഇത് മാനേജ് ചെയ്യുന്നത്." "കൂടുതലറിയുക" diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 621f2b5d5101..b443f7e52934 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -980,9 +980,9 @@ "स्पेस" "एंटर" "हटवा" - "शोध" + "Search" "शोधा…" - "शोध" + "Search" "शोध क्वेरी" "क्‍वेरी साफ करा" "क्वेरी सबमिट करा" @@ -1398,7 +1398,7 @@ "झूम नियंत्रणासाठी दोनदा टॅप करा" "विजेट जोडू शकलो नाही." "जा" - "शोधा" + "Search" "पाठवा" "पुढे" "पूर्ण झाले" @@ -1881,7 +1881,7 @@ "सुचवलेल्या भाषा" "सर्व भाषा" "सर्व प्रदेश" - "शोध" + "Search" "अ‍ॅप उपलब्ध नाही" "%1$s आत्ता उपलब्ध नाही. हे %2$s कडून व्यवस्थापित केले जाते." "अधिक जाणून घ्या" diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index ccfc4ae483ec..72fbc1d31781 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -980,9 +980,9 @@ "ସ୍ପେସ୍‍" "ଏଣ୍ଟର୍" "ଡିଲିଟ୍‍" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "ସର୍ଚ୍ଚ…" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "କ୍ୱେରୀ ସର୍ଚ୍ଚ କରନ୍ତୁ" "କ୍ୱେରୀ ଖାଲି କରନ୍ତୁ" "କ୍ୱେରୀ ଦାଖଲ କରନ୍ତୁ" @@ -1398,7 +1398,7 @@ "ଜୁମ୍ ନିୟନ୍ତ୍ରଣ ପାଇଁ ଦୁଇଥର ଟାପ୍‌ କରନ୍ତୁ" "ୱିଜେଟ୍‍ ଯୋଡ଼ିପାରିବ ନାହିଁ।" "ଯାଆନ୍ତୁ" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "ପଠାନ୍ତୁ" "ପରବର୍ତ୍ତୀ" "ହୋଇଗଲା" @@ -1881,7 +1881,7 @@ "ପ୍ରସ୍ତାବିତ" "ସମସ୍ତ ଭାଷା" "ସମସ୍ତ ଅଞ୍ଚଳ" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "ଆପ୍‌ ଉପଲବ୍ଧ ନାହିଁ" "ବର୍ତ୍ତମାନ %1$s ଉପଲବ୍ଧ ନାହିଁ। ଏହା %2$s ଦ୍ଵାରା ପରିଚାଳିତ ହେଉଛି।" "ଅଧିକ ଜାଣନ୍ତୁ" diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 8bc3682a4fca..d84b019c97b7 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -751,7 +751,7 @@ "Faks shtëpie" "Biper" "Tjetër" - "Ri-telefono" + "Kthim telefonate" "Numri i telefonit të makinës" "Numri kryesor i telefonit të kompanisë" "ISDN" diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index b9cedebddebb..d9475d92b947 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -980,9 +980,9 @@ "space" "enter" "delete" - "వెతుకు" + "సెర్చ్" "వెతుకు..." - "శోధించండి" + "సెర్చ్" "ప్రశ్నను శోధించండి" "ప్రశ్నను క్లియర్ చేయి" "ప్రశ్నని సమర్పించండి" @@ -1398,7 +1398,7 @@ "జూమ్ నియంత్రణ కోసం రెండుసార్లు నొక్కండి" "విడ్జెట్‌ను జోడించడం సాధ్యపడలేదు." "వెళ్లు" - "వెతుకు" + "సెర్చ్" "పంపు" "తర్వాత" "పూర్తయింది" @@ -1881,7 +1881,7 @@ "సూచించినవి" "అన్ని భాషలు" "అన్ని ప్రాంతాలు" - "వెతుకు" + "సెర్చ్" "యాప్ అందుబాటులో లేదు" "%1$s ప్రస్తుతం అందుబాటులో లేదు. ఇది %2$s ద్వారా నిర్వహించబడుతుంది." "మరింత తెలుసుకోండి" diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 50c29a631bfb..bf7fbca64581 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1128,10 +1128,10 @@ "Mở bằng" "Mở bằng %1$s" "Mở" - "Mở đường dẫn liên kết %1$s bằng" - "Mở đường dẫn liên kết bằng" - "Mở đường dẫn liên kết bằng %1$s" - "Mở đường dẫn liên kết %1$s bằng %2$s" + "Mở đường liên kết %1$s bằng" + "Mở đường liên kết bằng" + "Mở đường liên kết bằng %1$s" + "Mở đường liên kết %1$s bằng %2$s" "Cấp quyền truy cập" "Chỉnh sửa bằng" "Chỉnh sửa bằng %1$s" -- GitLab From 5fec07e052145973789473bfae804c7096450b83 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 14 Aug 2020 21:47:41 -0700 Subject: [PATCH 216/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I03057fd866fc5d48e876ac1ca0233db868d7c1a3 --- core/res/res/values-as/strings.xml | 8 ++++---- core/res/res/values-bn/strings.xml | 8 ++++---- core/res/res/values-gu/strings.xml | 2 +- core/res/res/values-kn/strings.xml | 8 ++++---- core/res/res/values-ml/strings.xml | 8 ++++---- core/res/res/values-mr/strings.xml | 8 ++++---- core/res/res/values-or/strings.xml | 8 ++++---- core/res/res/values-sq/strings.xml | 2 +- core/res/res/values-te/strings.xml | 8 ++++---- core/res/res/values-vi/strings.xml | 8 ++++---- 10 files changed, 34 insertions(+), 34 deletions(-) diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 5e87287185f3..1ecda856e574 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -980,9 +980,9 @@ "স্পেচ" "লিখক" "মচক" - "অনুসন্ধান কৰক" + "Search" "অনুসন্ধান কৰক…" - "অনুসন্ধান কৰক" + "Search" "প্ৰশ্নৰ সন্ধান কৰক" "প্ৰশ্ন মচক" "প্ৰশ্ন দাখিল কৰক" @@ -1398,7 +1398,7 @@ "জুম নিয়ন্ত্ৰণ কৰিবলৈ দুবাৰ টিপক" "ৱিজেট যোগ কৰিব পৰা নগ\'ল।" "যাওক" - "অনুসন্ধান কৰক" + "Search" "পঠিয়াওক" "পৰৱৰ্তী" "সম্পন্ন হ’ল" @@ -1881,7 +1881,7 @@ "প্ৰস্তাৱিত" "সকলো ভাষা" "সকলো অঞ্চল" - "অনুসন্ধান কৰক" + "Search" "এপটো নাই" "এই মুহূৰ্তত %1$s উপলব্ধ নহয়। ইয়াক %2$sএ পৰিচালনা কৰে।" "অধিক জানক" diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index c212b6c55d04..0533adc0c1aa 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -980,9 +980,9 @@ "স্পেস" "enter" "মুছুন" - "খুঁজুন" + "সার্চ" "সার্চ করুন..." - "খুঁজুন" + "সার্চ" "সার্চ ক্যোয়ারী" "ক্যোয়ারী সাফ করুন" "ক্যোয়ারী জমা দিন" @@ -1398,7 +1398,7 @@ "জুম নিয়ন্ত্রণের জন্য দুবার ট্যাপ করুন" "উইজেট যোগ করা যায়নি৷" "যান" - "খুঁজুন" + "সার্চ" "পাঠান" "পরবর্তী" "সম্পন্ন হয়েছে" @@ -1881,7 +1881,7 @@ "প্রস্তাবিত" "সকল ভাষা" "সমস্ত অঞ্চল" - "খুঁজুন" + "সার্চ" "অ্যাপটি উপলভ্য নয়" "%1$s এখন উপলভ্য নয়। এই অ্যাপটিকে %2$s অ্যাপ ম্যানেজ করে।" "আরও জানুন" diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 911a846d7afa..747a75e3f88b 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -982,7 +982,7 @@ "ડિલીટ કરો" "શોધો" "શોધો…" - "શોધ" + "શોધો" "શોધ ક્વેરી" "ક્વેરી સાફ કરો" "ક્વેરી સબમિટ કરો" diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 56311965cc50..4671f708bd39 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -980,9 +980,9 @@ "space" "enter" "ಅಳಿಸಿ" - "ಹುಡುಕಿ" + "Search" "ಹುಡುಕಿ…" - "ಹುಡುಕಿ" + "Search" "ಪ್ರಶ್ನೆಯನ್ನು ಹುಡುಕಿ" "ಪ್ರಶ್ನೆಯನ್ನು ತೆರವುಗೊಳಿಸು" "ಪ್ರಶ್ನೆಯನ್ನು ಸಲ್ಲಿಸು" @@ -1398,7 +1398,7 @@ "ಝೂಮ್‌ ನಿಯಂತ್ರಿಸಲು ಎರಡು ಬಾರಿ ಟ್ಯಾಪ್ ಮಾಡಿ" "ವಿಜೆಟ್ ಸೇರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ." "ಹೋಗು" - "ಹುಡುಕಿ" + "Search" "ಕಳುಹಿಸು" "ಮುಂದೆ" "ಮುಗಿದಿದೆ" @@ -1881,7 +1881,7 @@ "ಸೂಚಿತ ಭಾಷೆ" "ಎಲ್ಲಾ ಭಾಷೆಗಳು" "ಎಲ್ಲಾ ಪ್ರದೇಶಗಳು" - "ಹುಡುಕಿ" + "Search" "ಅಪ್ಲಿಕೇಶನ್ ಲಭ್ಯವಿಲ್ಲ" "%1$s ಅಪ್ಲಿಕೇಶನ್‌ ಸದ್ಯಕ್ಕೆ ಲಭ್ಯವಿಲ್ಲ. ಇದನ್ನು %2$s ನಲ್ಲಿ ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ." "ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ" diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 60a06c84504a..ce7624244a17 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -980,9 +980,9 @@ "space" "enter" "delete" - "തിരയൽ" + "Search" "തിരയുക…" - "തിരയൽ" + "Search" "തിരയൽ അന്വേഷണം" "അന്വേഷണം മായ്‌ക്കുക" "ചോദ്യം സമർപ്പിക്കുക" @@ -1398,7 +1398,7 @@ "സൂം നിയന്ത്രണം ലഭിക്കാൻ രണ്ടുതവണ ടാപ്പുചെയ്യുക" "വിജറ്റ് ചേർക്കാനായില്ല." "പോവുക" - "തിരയൽ" + "Search" "അയയ്‌ക്കുക" "അടുത്തത്" "പൂർത്തിയായി" @@ -1881,7 +1881,7 @@ "നിര്‍‌ദ്ദേശിച്ചത്" "എല്ലാ ഭാഷകളും" "എല്ലാ പ്രദേശങ്ങളും" - "തിരയുക" + "Search" "ആപ്പ് ലഭ്യമല്ല" "%1$s ഇപ്പോൾ ലഭ്യമല്ല. %2$s ആണ് ഇത് മാനേജ് ചെയ്യുന്നത്." "കൂടുതലറിയുക" diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 9c3202e1b1ef..e53d1da18721 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -980,9 +980,9 @@ "स्पेस" "एंटर" "हटवा" - "शोध" + "Search" "शोधा…" - "शोध" + "Search" "शोध क्वेरी" "क्‍वेरी साफ करा" "क्वेरी सबमिट करा" @@ -1398,7 +1398,7 @@ "झूम नियंत्रणासाठी दोनदा टॅप करा" "विजेट जोडू शकलो नाही." "जा" - "शोधा" + "Search" "पाठवा" "पुढे" "पूर्ण झाले" @@ -1881,7 +1881,7 @@ "सुचवलेल्या भाषा" "सर्व भाषा" "सर्व प्रदेश" - "शोध" + "Search" "अ‍ॅप उपलब्ध नाही" "%1$s आत्ता उपलब्ध नाही. हे %2$s कडून व्यवस्थापित केले जाते." "अधिक जाणून घ्या" diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index def4a412ddfa..4baab0eb34ee 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -980,9 +980,9 @@ "ସ୍ପେସ୍‍" "ଏଣ୍ଟର୍" "ଡିଲିଟ୍‍" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "ସର୍ଚ୍ଚ…" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "କ୍ୱେରୀ ସର୍ଚ୍ଚ କରନ୍ତୁ" "କ୍ୱେରୀ ଖାଲି କରନ୍ତୁ" "କ୍ୱେରୀ ଦାଖଲ କରନ୍ତୁ" @@ -1398,7 +1398,7 @@ "ଜୁମ୍ ନିୟନ୍ତ୍ରଣ ପାଇଁ ଦୁଇଥର ଟାପ୍‌ କରନ୍ତୁ" "ୱିଜେଟ୍‍ ଯୋଡ଼ିପାରିବ ନାହିଁ।" "ଯାଆନ୍ତୁ" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "ପଠାନ୍ତୁ" "ପରବର୍ତ୍ତୀ" "ହୋଇଗଲା" @@ -1881,7 +1881,7 @@ "ପ୍ରସ୍ତାବିତ" "ସମସ୍ତ ଭାଷା" "ସମସ୍ତ ଅଞ୍ଚଳ" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "ଆପ୍‌ ଉପଲବ୍ଧ ନାହିଁ" "ବର୍ତ୍ତମାନ %1$s ଉପଲବ୍ଧ ନାହିଁ। ଏହା %2$s ଦ୍ଵାରା ପରିଚାଳିତ ହେଉଛି।" "ଅଧିକ ଜାଣନ୍ତୁ" diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index cc8b9876f247..000ec504cfee 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -751,7 +751,7 @@ "Faks shtëpie" "Biper" "Tjetër" - "Ri-telefono" + "Kthim telefonate" "Numri i telefonit të makinës" "Numri kryesor i telefonit të kompanisë" "ISDN" diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index b0886570c613..348e5e1fe1b2 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -980,9 +980,9 @@ "space" "enter" "delete" - "వెతుకు" + "సెర్చ్" "వెతుకు..." - "శోధించండి" + "సెర్చ్" "ప్రశ్నను శోధించండి" "ప్రశ్నను క్లియర్ చేయి" "ప్రశ్నని సమర్పించండి" @@ -1398,7 +1398,7 @@ "జూమ్ నియంత్రణ కోసం రెండుసార్లు నొక్కండి" "విడ్జెట్‌ను జోడించడం సాధ్యపడలేదు." "వెళ్లు" - "వెతుకు" + "సెర్చ్" "పంపు" "తర్వాత" "పూర్తయింది" @@ -1881,7 +1881,7 @@ "సూచించినవి" "అన్ని భాషలు" "అన్ని ప్రాంతాలు" - "వెతుకు" + "సెర్చ్" "యాప్ అందుబాటులో లేదు" "%1$s ప్రస్తుతం అందుబాటులో లేదు. ఇది %2$s ద్వారా నిర్వహించబడుతుంది." "మరింత తెలుసుకోండి" diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 2d205ea856cb..c2caedda82ed 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1128,10 +1128,10 @@ "Mở bằng" "Mở bằng %1$s" "Mở" - "Mở đường dẫn liên kết %1$s bằng" - "Mở đường dẫn liên kết bằng" - "Mở đường dẫn liên kết bằng %1$s" - "Mở đường dẫn liên kết %1$s bằng %2$s" + "Mở đường liên kết %1$s bằng" + "Mở đường liên kết bằng" + "Mở đường liên kết bằng %1$s" + "Mở đường liên kết %1$s bằng %2$s" "Cấp quyền truy cập" "Chỉnh sửa bằng" "Chỉnh sửa bằng %1$s" -- GitLab From 0e74a934eebb0a1656eeeee23b78fe5d085866bc Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 15 Aug 2020 10:05:31 +0000 Subject: [PATCH 217/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I8396b73e9c5e8c8f843e3be1066f935170087736 --- packages/SystemUI/res/values-af/strings.xml | 2 +- packages/SystemUI/res/values-am/strings.xml | 4 ++-- packages/SystemUI/res/values-ar/strings.xml | 2 +- packages/SystemUI/res/values-as/strings.xml | 6 +++--- packages/SystemUI/res/values-az/strings.xml | 2 +- packages/SystemUI/res/values-b+sr+Latn/strings.xml | 2 +- packages/SystemUI/res/values-be/strings.xml | 2 +- packages/SystemUI/res/values-bg/strings.xml | 2 +- packages/SystemUI/res/values-bn/strings.xml | 6 +++--- packages/SystemUI/res/values-bs/strings.xml | 2 +- packages/SystemUI/res/values-ca/strings.xml | 2 +- packages/SystemUI/res/values-cs/strings.xml | 2 +- packages/SystemUI/res/values-da/strings.xml | 2 +- packages/SystemUI/res/values-de/strings.xml | 2 +- packages/SystemUI/res/values-el/strings.xml | 2 +- packages/SystemUI/res/values-en-rAU/strings.xml | 2 +- packages/SystemUI/res/values-en-rCA/strings.xml | 2 +- packages/SystemUI/res/values-en-rGB/strings.xml | 2 +- packages/SystemUI/res/values-en-rIN/strings.xml | 2 +- packages/SystemUI/res/values-en-rXC/strings.xml | 2 +- packages/SystemUI/res/values-es-rUS/strings.xml | 2 +- packages/SystemUI/res/values-es/strings.xml | 2 +- packages/SystemUI/res/values-et/strings.xml | 2 +- packages/SystemUI/res/values-eu/strings.xml | 2 +- packages/SystemUI/res/values-fa/strings.xml | 2 +- packages/SystemUI/res/values-fi/strings.xml | 2 +- packages/SystemUI/res/values-fr-rCA/strings.xml | 2 +- packages/SystemUI/res/values-fr/strings.xml | 2 +- packages/SystemUI/res/values-gl/strings.xml | 2 +- packages/SystemUI/res/values-gu/strings.xml | 4 ++-- packages/SystemUI/res/values-hi/strings.xml | 2 +- packages/SystemUI/res/values-hr/strings.xml | 2 +- packages/SystemUI/res/values-hu/strings.xml | 2 +- packages/SystemUI/res/values-hy/strings.xml | 2 +- packages/SystemUI/res/values-in/strings.xml | 2 +- packages/SystemUI/res/values-is/strings.xml | 2 +- packages/SystemUI/res/values-it/strings.xml | 2 +- packages/SystemUI/res/values-iw/strings.xml | 2 +- packages/SystemUI/res/values-ja/strings.xml | 2 +- packages/SystemUI/res/values-ka/strings.xml | 2 +- packages/SystemUI/res/values-kk/strings.xml | 2 +- packages/SystemUI/res/values-km/strings.xml | 2 +- packages/SystemUI/res/values-kn/strings.xml | 6 +++--- packages/SystemUI/res/values-ko/strings.xml | 6 +++--- packages/SystemUI/res/values-ky/strings.xml | 2 +- packages/SystemUI/res/values-lo/strings.xml | 2 +- packages/SystemUI/res/values-lt/strings.xml | 2 +- packages/SystemUI/res/values-lv/strings.xml | 2 +- packages/SystemUI/res/values-mk/strings.xml | 2 +- packages/SystemUI/res/values-ml/strings.xml | 6 +++--- packages/SystemUI/res/values-mn/strings.xml | 2 +- packages/SystemUI/res/values-mr/strings.xml | 6 +++--- packages/SystemUI/res/values-ms/strings.xml | 2 +- packages/SystemUI/res/values-my/strings.xml | 2 +- packages/SystemUI/res/values-nb/strings.xml | 2 +- packages/SystemUI/res/values-ne/strings.xml | 2 +- packages/SystemUI/res/values-nl/strings.xml | 2 +- packages/SystemUI/res/values-or/strings.xml | 6 +++--- packages/SystemUI/res/values-pa/strings.xml | 2 +- packages/SystemUI/res/values-pl/strings.xml | 2 +- packages/SystemUI/res/values-pt-rBR/strings.xml | 2 +- packages/SystemUI/res/values-pt-rPT/strings.xml | 2 +- packages/SystemUI/res/values-pt/strings.xml | 2 +- packages/SystemUI/res/values-ro/strings.xml | 2 +- packages/SystemUI/res/values-ru/strings.xml | 2 +- packages/SystemUI/res/values-si/strings.xml | 2 +- packages/SystemUI/res/values-sk/strings.xml | 2 +- packages/SystemUI/res/values-sl/strings.xml | 2 +- packages/SystemUI/res/values-sq/strings.xml | 2 +- packages/SystemUI/res/values-sr/strings.xml | 2 +- packages/SystemUI/res/values-sv/strings.xml | 2 +- packages/SystemUI/res/values-sw/strings.xml | 2 +- packages/SystemUI/res/values-ta/strings.xml | 2 +- packages/SystemUI/res/values-te/strings.xml | 6 +++--- packages/SystemUI/res/values-th/strings.xml | 2 +- packages/SystemUI/res/values-tl/strings.xml | 2 +- packages/SystemUI/res/values-tr/strings.xml | 2 +- packages/SystemUI/res/values-uk/strings.xml | 2 +- packages/SystemUI/res/values-ur/strings.xml | 2 +- packages/SystemUI/res/values-uz/strings.xml | 2 +- packages/SystemUI/res/values-vi/strings.xml | 2 +- packages/SystemUI/res/values-zh-rCN/strings.xml | 2 +- packages/SystemUI/res/values-zh-rHK/strings.xml | 2 +- packages/SystemUI/res/values-zh-rTW/strings.xml | 2 +- packages/SystemUI/res/values-zu/strings.xml | 2 +- 85 files changed, 103 insertions(+), 103 deletions(-) diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index a2a0e64db30e..4fc65dcb4951 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -1075,7 +1075,7 @@ "Laai tans aanbevelings" "Media" "Versteek die huidige sessie." - "Versteek" + "Maak toe" "Hervat" "Instellings" "Onaktief, gaan program na" diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index a28dd54c94b1..67d37739d43e 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -73,7 +73,7 @@ "መሣሪያዎን ከፈሳሽ ወይም ፍርስራሽ ለመጠበቅ ሲባል የዩኤስቢ ወደቡ ተሰናክሏል፣ እና ማናቸውም ተቀጥላዎችን አያገኝም።\n\nየዩኤስቢ ወደቡን እንደገና መጠቀም ችግር በማይኖረው ጊዜ ማሳወቂያ ይደርሰዎታል።" "ኃይል መሙያዎችን እና ተጨማሪ መሣሪያዎችን ፈልጎ ለማግኘት የነቃ የዩኤስቢ ወደብ" "ዩኤስቢ አንቃ" - "የበለጠ መረዳት" + "የበለጠ ለመረዳት" "ማያ እንዲሞላ አጉላ" "ማያ ለመሙለት ሳብ" "ቅጽበታዊ ገጽ እይታ" @@ -1075,7 +1075,7 @@ "ምክሮችን በመጫን ላይ" "ሚዲያ" "የአሁኑን ክፍለ-ጊዜ ደብቅ።" - "ደብቅ" + "አሰናብት" "ከቆመበት ቀጥል" "ቅንብሮች" "ንቁ ያልኾነ፣ መተግበሪያን ይፈትሹ" diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index de368b32e124..f4adeddafcec 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -1099,7 +1099,7 @@ "جارٍ تحميل الاقتراحات" "الوسائط" "إخفاء الجلسة الحالية" - "إخفاء" + "إغلاق" "استئناف التشغيل" "الإعدادات" "غير نشط، تحقّق من التطبيق." diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 89f986f07fe2..8fd20dfc4a8d 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -125,7 +125,7 @@ "দিব্যাংগসকলৰ বাবে থকা সুবিধাসমূহ" "স্ক্ৰীণ ঘূৰাওক" "অৱলোকন" - "সন্ধান কৰক" + "Search" "কেমেৰা" "ফ\'ন" "কণ্ঠধ্বনিৰে সহায়" @@ -441,7 +441,7 @@ "বেটাৰিৰ চ্চাৰ্জ সম্পূর্ণ হ\'বলৈ %s বাকী" "চ্চার্জ কৰি থকা নাই" "নেটৱৰ্ক \nনিৰীক্ষণ কৰা হ\'ব পাৰে" - "অনুসন্ধান কৰক" + "Search" "%sৰ বাবে ওপৰলৈ শ্লাইড কৰক।" "%sৰ বাবে বাওঁফাললৈ শ্লাইড কৰক।" "আপুনি নিৰ্দিষ্ট কৰা এলাৰ্ম, ৰিমাইণ্ডাৰ, ইভেন্ট আৰু কল কৰোঁতাৰ বাহিৰে আন কোনো শব্দৰ পৰা আপুনি অসুবিধা নাপাব। কিন্তু, সংগীত, ভিডিঅ\' আৰু খেলসমূহকে ধৰি আপুনি প্লে কৰিব খোজা যিকোনো বস্তু তথাপি শুনিব পাৰিব।" @@ -1075,7 +1075,7 @@ "চুপাৰিছসমূহ ল’ড কৰি থকা হৈছে" "মিডিয়া" "বৰ্তমানৰ ছেশ্বনটো লুকুৱাওক।" - "লুকুৱাওক" + "অগ্ৰাহ্য কৰক" "পুনৰ আৰম্ভ কৰক" "ছেটিংসমূহ" "সক্ৰিয় নহয়, এপ্‌টো পৰীক্ষা কৰক" diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index c6a7f14eb7d2..f45fe634b5a9 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -1075,7 +1075,7 @@ "Tövsiyələr yüklənir" "Media" "Cari sessiyanı gizlədin." - "Gizlədin" + "İmtina edin" "Davam edin" "Ayarlar" "Aktiv deyil, tətbiqi yoxlayın" diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index efb3e58c65e9..daac5028f4ca 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -1081,7 +1081,7 @@ "Učitavaju se preporuke" "Mediji" "Sakrijte aktuelnu sesiju." - "Sakrij" + "Odbaci" "Nastavi" "Podešavanja" "Neaktivno. Vidite aplikaciju" diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 799a9c22e1ba..50227525fa07 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -1087,7 +1087,7 @@ "Загружаюцца рэкамендацыі" "Мультымедыя" "Схаваць цяперашні сеанс." - "Схаваць" + "Адхіліць" "Узнавіць" "Налады" "Неактыўна, праверце праграму" diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 1241d06454e0..599cd6007b16 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -1075,7 +1075,7 @@ "Препоръките се зареждат" "Мултимедия" "Скриване на текущата сесия." - "Скриване" + "Отхвърляне" "Възобновяване" "Настройки" "Неактивно, проверете прилож." diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 46004599d499..657022b6a4ae 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -125,7 +125,7 @@ "অ্যাক্সেসযোগ্যতা" "স্ক্রিন ঘোরান" "এক নজরে" - "খুঁজুন" + "সার্চ" "ক্যামেরা" "ফোন" "ভয়েস সহায়তা" @@ -441,7 +441,7 @@ "পূর্ণ হতে %s সময় লাগবে" "চার্জ হচ্ছে না" "নেটওয়ার্ক নিরীক্ষণ\nকরা হতে পারে" - "খুঁজুন" + "সার্চ" "%s এর জন্য উপরের দিকে স্লাইড করুন৷" "%s এর জন্য বাঁ দিকে স্লাইড করুন৷" "অ্যালার্ম, রিমাইন্ডার, ইভেন্ট, এবং আপনার নির্দিষ্ট করে দেওয়া ব্যক্তিদের কল ছাড়া অন্য কোনও আওয়াজ বা ভাইব্রেশন হবে না। তবে সঙ্গীত, ভিডিও, এবং গেম সহ আপনি যা কিছু চালাবেন তার আওয়াজ শুনতে পাবেন।" @@ -1075,7 +1075,7 @@ "সাজেশন লোড করা হচ্ছে" "মিডিয়া" "বর্তমান সেশন লুকান।" - "লুকান" + "খারিজ করুন" "আবার চালু করুন" "সেটিংস" "বন্ধ আছে, অ্যাপ চেক করুন" diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index b974b924f35c..a51e79a42da7 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -1081,7 +1081,7 @@ "Učitavanje preporuka" "Mediji" "Sakrijte trenutnu sesiju." - "Sakrij" + "Odbaci" "Nastavi" "Postavke" "Neaktivno, vidite aplikaciju" diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index b261a455a788..5a70913c4fe3 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -1075,7 +1075,7 @@ "Carregant les recomanacions" "Multimèdia" "Amaga la sessió actual." - "Amaga" + "Ignora" "Reprèn" "Configuració" "Inactiu; comprova l\'aplicació" diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 1c239713743a..a4e831a256c3 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -1087,7 +1087,7 @@ "Načítání doporučení" "Média" "Skrýt aktuální relaci." - "Skrýt" + "Zavřít" "Pokračovat" "Nastavení" "Neaktivní, zkontrolujte aplikaci" diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index d439771b7c1d..c8a61a7051c8 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -1075,7 +1075,7 @@ "Indlæser anbefalinger" "Medie" "Skjul den aktuelle session." - "Skjul" + "Luk" "Genoptag" "Indstillinger" "Inaktiv. Tjek appen" diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 6cb86d980fef..787f927d85f0 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -1075,7 +1075,7 @@ "Empfehlungen werden geladen" "Medien" "Du kannst die aktuelle Sitzung ausblenden." - "Ausblenden" + "Ablehnen" "Fortsetzen" "Einstellungen" "Inaktiv – sieh in der App nach" diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index c2210169092f..a2865b182c31 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -1075,7 +1075,7 @@ "Φόρτωση προτάσεων" "Μέσα" "Απόκρυψη της τρέχουσας περιόδου λειτουργίας." - "Απόκρυψη" + "Παράβλεψη" "Συνέχιση" "Ρυθμίσεις" "Ανενεργό, έλεγχος εφαρμογής" diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 89bc37308289..a96f3ef83a32 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -1075,7 +1075,7 @@ "Loading recommendations" "Media" "Hide the current session." - "Hide" + "Dismiss" "Resume" "Settings" "Inactive, check app" diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index e70e74db84ab..931df88f4cd2 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -1075,7 +1075,7 @@ "Loading recommendations" "Media" "Hide the current session." - "Hide" + "Dismiss" "Resume" "Settings" "Inactive, check app" diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 89bc37308289..a96f3ef83a32 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -1075,7 +1075,7 @@ "Loading recommendations" "Media" "Hide the current session." - "Hide" + "Dismiss" "Resume" "Settings" "Inactive, check app" diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 89bc37308289..a96f3ef83a32 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -1075,7 +1075,7 @@ "Loading recommendations" "Media" "Hide the current session." - "Hide" + "Dismiss" "Resume" "Settings" "Inactive, check app" diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 38dd7557018f..dbb6eb7ef76b 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -1075,7 +1075,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎Loading recommendations‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎Media‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‎Hide the current session.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎Hide‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎Dismiss‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎Resume‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎Settings‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎Inactive, check app‎‏‎‎‏‎" diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index c95cb4f6833a..de86271dca0e 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -1075,7 +1075,7 @@ "Cargando recomendaciones" "Contenido multimedia" "Oculta la sesión actual." - "Ocultar" + "Descartar" "Reanudar" "Configuración" "Inactivo. Verifica la app" diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 45a058871cc9..ef4e7522002d 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -1075,7 +1075,7 @@ "Cargando recomendaciones" "Multimedia" "Ocultar la sesión." - "Ocultar" + "Cerrar" "Reanudar" "Ajustes" "Inactivo, comprobar aplicación" diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index ea9266e2811b..9a12f54608b1 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -1075,7 +1075,7 @@ "Soovituste laadimine" "Meedia" "Peidetakse praegune seanss." - "Peida" + "Loobu" "Jätka" "Seaded" "Passiivne, vaadake rakendust" diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 338acbe7440b..d0bf329fa46e 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -1075,7 +1075,7 @@ "Gomendioak kargatzen" "Multimedia-edukia" "Ezkutatu uneko saioa." - "Ezkutatu" + "Baztertu" "Berrekin" "Ezarpenak" "Inaktibo; egiaztatu aplikazioa" diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 02809ae04297..52ba23e17a32 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -1075,7 +1075,7 @@ "درحال بار کردن توصیه‌ها" "رسانه" "جلسه فعلی پنهان شود." - "پنهان کردن" + "رد کردن" "ازسرگیری" "تنظیمات" "غیرفعال، برنامه را بررسی کنید" diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 97a1b44a119e..332c512b1772 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -1075,7 +1075,7 @@ "Ladataan suosituksia" "Media" "Piilota nykyinen käyttökerta." - "Piilota" + "Ohita" "Jatka" "Asetukset" "Epäaktiivinen, tarkista sovellus" diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 03afe10c5e4e..e1942a4ed98b 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -1075,7 +1075,7 @@ "Chargement des recommandations…" "Commandes multimédias" "Masquer la session en cours." - "Masquer" + "Fermer" "Reprendre" "Paramètres" "Délai expiré, vérifiez l\'appli" diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 50e8d379e6da..7fb9e968ec33 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -1075,7 +1075,7 @@ "Chargement des recommandations" "Multimédia" "Masquer la session en cours." - "Masquer" + "Fermer" "Reprendre" "Paramètres" "Délai expiré, vérifier l\'appli" diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index dcb95386f935..29be995a6cca 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -1075,7 +1075,7 @@ "Cargando recomendacións" "Contido multimedia" "Oculta a sesión actual." - "Ocultar" + "Ignorar" "Retomar" "Configuración" "Inactivo. Comproba a app" diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 4164a55d8e2d..bafa026ce4ce 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -125,7 +125,7 @@ "ઍક્સેસિબિલિટી" "સ્ક્રીન ફેરવો" "ઝલક" - "શોધો" + "શોધ" "કૅમેરો" "ફોન" "વૉઇસ સહાય" @@ -1075,7 +1075,7 @@ "સુઝાવ લોડ કરી રહ્યાં છીએ" "મીડિયા" "હાલનું સત્ર છુપાવો." - "છુપાવો" + "છોડી દો" "ફરી શરૂ કરો" "સેટિંગ" "નિષ્ક્રિય, ઍપને ચેક કરો" diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 85635e919e30..be2cd0bd2218 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -1077,7 +1077,7 @@ "सुझाव लोड हो रहे हैं" "मीडिया" "इस मीडिया सेशन को छिपाएं." - "छिपाएं" + "खारिज करें" "फिर से शुरू करें" "सेटिंग" "काम नहीं कर रहा, ऐप जांचें" diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index aa3dd64b778a..96880773f19e 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -1081,7 +1081,7 @@ "Učitavanje preporuka" "Mediji" "Sakrij trenutačnu sesiju." - "Sakrij" + "Odbaci" "Nastavi" "Postavke" "Neaktivno, provjerite aplik." diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 0c6166c81c79..607c05a13468 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -1075,7 +1075,7 @@ "Javaslatok betöltése…" "Média" "Jelenlegi munkamenet elrejtése." - "Elrejtés" + "Elvetés" "Folytatás" "Beállítások" "Inaktív, ellenőrizze az appot" diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 24fcc19ce49e..56b8d32a1324 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -1075,7 +1075,7 @@ "Բեռնման խորհուրդներ" "Մեդիա" "Թաքցրեք ընթացիկ աշխատաշրջանը" - "Թաքցնել" + "Փակել" "Շարունակել" "Կարգավորումներ" "Ակտիվ չէ, ստուգեք հավելվածը" diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 3c2dbfc6dd10..9417d483bb62 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -1075,7 +1075,7 @@ "Memuat rekomendasi" "Media" "Menyembunyikan sesi saat ini." - "Sembunyikan" + "Tutup" "Lanjutkan" "Setelan" "Nonaktif, periksa aplikasi" diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index dc3a10dc7400..379666906f11 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -1075,7 +1075,7 @@ "Hleður tillögum" "Margmiðlunarefni" "Fela núverandi lotu." - "Fela" + "Hunsa" "Halda áfram" "Stillingar" "Óvirkt, athugaðu forrit" diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index bc13f9941b93..7d7785caa866 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -1075,7 +1075,7 @@ "Caricamento dei consigli" "Contenuti multimediali" "Nascondi la sessione attuale." - "Nascondi" + "Ignora" "Riprendi" "Impostazioni" "Inattivo, controlla l\'app" diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 4854a07a7dcd..778ab9bbb873 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -1087,7 +1087,7 @@ "בטעינת המלצות" "מדיה" "הסתרת הסשן הנוכחי." - "הסתרה" + "סגירה" "המשך" "הגדרות" "לא פעיל, יש לבדוק את האפליקציה" diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index c3cf58b3349a..ef80212874d8 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -1075,7 +1075,7 @@ "候補を読み込んでいます" "メディア" "現在のセッションを非表示にします。" - "非表示" + "閉じる" "再開" "設定" "無効: アプリをご確認ください" diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index ff055fcf6073..c2888117ca6b 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -1075,7 +1075,7 @@ "მიმდინარეობს რეკომენდაციების ჩატვირთვა" "მედია" "დაიმალოს მიმდინარე სესია" - "დამალვა" + "დახურვა" "გაგრძელება" "პარამეტრები" "არააქტიურია, გადაამოწმეთ აპი" diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index bac8b24e00ab..501e92e2de0b 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -1075,7 +1075,7 @@ "Жүктеуге қатысты ұсыныстар" "Мультимедиа" "Ағымдағы сеансты жасыру" - "Жасыру" + "Жабу" "Жалғастыру" "Параметрлер" "Өшірулі. Қолданба тексеріңіз." diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 43c3ad31abea..1ddca55e9aa8 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -1075,7 +1075,7 @@ "កំពុងផ្ទុក​ការណែនាំ" "មេឌៀ" "លាក់វគ្គ​បច្ចុប្បន្ន។" - "លាក់" + "ច្រាន​ចោល" "បន្ត" "ការកំណត់" "អសកម្ម ពិនិត្យមើល​កម្មវិធី" diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 7baa634efdca..c726e00ce131 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -125,7 +125,7 @@ "ಪ್ರವೇಶಿಸುವಿಕೆ" "ಪರದೆಯನ್ನು ತಿರುಗಿಸಿ" "ಸಮಗ್ರ ನೋಟ" - "ಹುಡುಕಿ" + "Search" "ಕ್ಯಾಮರಾ" "ಫೋನ್" "ಧ್ವನಿ ಸಹಾಯಕ" @@ -441,7 +441,7 @@ "%s ಪೂರ್ಣಗೊಳ್ಳುವವರೆಗೆ" "ಚಾರ್ಜ್‌ ಆಗುತ್ತಿಲ್ಲ" "ನೆಟ್‌ವರ್ಕ್\n ವೀಕ್ಷಿಸಬಹುದಾಗಿರುತ್ತದೆ" - "ಹುಡುಕಿ" + "Search" "%s ಗಾಗಿ ಮೇಲಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ." "%s ಗಾಗಿ ಎಡಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ." "ಅಲಾರಾಂಗಳು, ಜ್ಞಾಪನೆಗಳು, ಈವೆಂಟ್‌ಗಳು ಹಾಗೂ ನೀವು ಸೂಚಿಸಿರುವ ಕರೆದಾರರನ್ನು ಹೊರತುಪಡಿಸಿ ಬೇರಾವುದೇ ಸದ್ದುಗಳು ಅಥವಾ ವೈಬ್ರೇಶನ್‌ಗಳು ನಿಮಗೆ ತೊಂದರೆ ನೀಡುವುದಿಲ್ಲ. ಹಾಗಿದ್ದರೂ, ನೀವು ಪ್ಲೇ ಮಾಡುವ ಸಂಗೀತ, ವೀಡಿಯೊಗಳು ಮತ್ತು ಆಟಗಳ ಆಡಿಯೊವನ್ನು ನೀವು ಕೇಳಿಸಿಕೊಳ್ಳುತ್ತೀರಿ." @@ -1075,7 +1075,7 @@ "ಶಿಫಾರಸುಗಳು ಲೋಡ್ ಆಗುತ್ತಿವೆ" "ಮಾಧ್ಯಮ" "ಪ್ರಸ್ತುತ ಸೆಶನ್ ಅನ್ನು ಮರೆಮಾಡಿ." - "ಮರೆಮಾಡಿ" + "ವಜಾಗೊಳಿಸಿ" "ಪುನರಾರಂಭಿಸಿ" "ಸೆಟ್ಟಿಂಗ್‌ಗಳು" "ನಿಷ್ಕ್ರಿಯ, ಆ್ಯಪ್ ಪರಿಶೀಲಿಸಿ" diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index ff61691758fd..9f8aafdf911f 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -502,10 +502,10 @@ "절전 모드 사용 중" "성능 및 백그라운드 데이터를 줄입니다." "절전 모드 사용 중지" - "%s이(가) 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다." + "%s이 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다." "이 기능을 제공하는 서비스는 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다." "녹화 또는 전송을 시작하시겠습니까?" - "%s(으)로 녹화 또는 전송을 시작하시겠습니까?" + "%s으로 녹화 또는 전송을 시작하시겠습니까?" "다시 표시 안함" "모두 지우기" "관리" @@ -1075,7 +1075,7 @@ "추천 제어 기능 로드 중" "미디어" "현재 세션을 숨깁니다." - "숨기기" + "닫기" "다시 시작" "설정" "비활성. 앱을 확인하세요." diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index e4ad9ef577dc..134d04d3f702 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -1075,7 +1075,7 @@ "Сунуштар жүктөлүүдө" "Медиа" "Учурдагы сеансты жашыруу." - "Жашыруу" + "Жабуу" "Улантуу" "Жөндөөлөр" "Жигерсиз. Колдонмону текшериңиз" diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 8e7fba0c4e38..862e1458937d 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -1075,7 +1075,7 @@ "ກຳລັງໂຫຼດຄຳແນະນຳ" "ມີເດຍ" "ເຊື່ອງເຊດຊັນປັດຈຸບັນ." - "ເຊື່ອງ" + "ປິດໄວ້" "ສືບຕໍ່" "ການຕັ້ງຄ່າ" "ບໍ່ເຮັດວຽກ, ກະລຸນາກວດສອບແອັບ" diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 39776fda02e6..e50ceaf023c3 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -1087,7 +1087,7 @@ "Įkeliamos rekomendacijos" "Medija" "Slėpti dabartinį seansą." - "Slėpti" + "Atsisakyti" "Tęsti" "Nustatymai" "Neaktyvu, patikrinkite progr." diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index ccbe7bf874d7..d05fa08f1bbe 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -1081,7 +1081,7 @@ "Notiek ieteikumu ielāde" "Multivide" "Paslēpiet pašreizējo sesiju." - "Paslēpt" + "Nerādīt" "Atsākt" "Iestatījumi" "Neaktīva, pārbaudiet lietotni" diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 4764618d9bba..9c78de6219fd 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -1075,7 +1075,7 @@ "Се вчитуваат препораки" "Аудиовизуелни содржини" "Сокриј ја тековнава сесија." - "Сокриј" + "Отфрли" "Продолжи" "Поставки" "Неактивна, провери апликација" diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 69f13e9395c1..9624be9430a2 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -125,7 +125,7 @@ "ഉപയോഗസഹായി" "സ്‌ക്രീൻ തിരിക്കുക" "അവലോകനം" - "തിരയൽ" + "Search" "ക്യാമറ" "ഫോണ്‍" "വോയ്‌സ് സഹായം" @@ -441,7 +441,7 @@ "ഫുൾ ചാർജാകാൻ, %s" "ചാർജ്ജുചെയ്യുന്നില്ല" "നെറ്റ്‌വർക്ക്\nനിരീക്ഷിക്കപ്പെടാം" - "തിരയൽ" + "Search" "%s എന്നതിനായി മുകളിലേയ്‌ക്ക് സ്ലൈഡുചെയ്യുക." "%s എന്നതിനായി ഇടത്തേയ്‌ക്ക് സ്ലൈഡുചെയ്യുക." "നിങ്ങൾ സജ്ജീകരിച്ച അലാറങ്ങൾ, റിമൈൻഡറുകൾ, ഇവന്റുകൾ, കോളർമാർ എന്നിവയിൽ നിന്നുള്ള ശബ്‌ദങ്ങളും വൈബ്രേഷനുകളുമൊഴികെ മറ്റൊന്നും നിങ്ങളെ ശല്യപ്പെടുത്തുകയില്ല. സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയുൾപ്പെടെ പ്ലേ ചെയ്യുന്നതെന്തും നിങ്ങൾക്ക് ‌തുടർന്നും കേൾക്കാൻ കഴിയും." @@ -1075,7 +1075,7 @@ "നിർദ്ദേശങ്ങൾ ലോഡ് ചെയ്യുന്നു" "മീഡിയ" "നിലവിലെ സെഷൻ മറയ്‌ക്കുക." - "മറയ്‌ക്കുക" + "ഡിസ്‌മിസ് ചെയ്യുക" "പുനരാരംഭിക്കുക" "ക്രമീകരണം" "നിഷ്‌ക്രിയം, ആപ്പ് പരിശോധിക്കൂ" diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 74af0fd7703c..59305949d529 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -1075,7 +1075,7 @@ "Зөвлөмжүүдийг ачаалж байна" "Медиа" "Одоогийн харилцан үйлдлийг нуугаарай." - "Нуух" + "Хаах" "Үргэлжлүүлэх" "Тохиргоо" "Идэвхгүй байна, аппыг шалгана уу" diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index b1d98915bac7..3c87b3136ee8 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -125,7 +125,7 @@ "अ‍ॅक्सेसिबिलिटी" "स्क्रीन फिरवा" "अवलोकन" - "शोधा" + "Search" "कॅमेरा" "फोन" "व्हॉइस सहाय्य" @@ -441,7 +441,7 @@ "%s पूर्ण होईपर्यंत" "चार्ज होत नाही" "नेटवर्कचे परीक्षण\nकेले जाऊ शकते" - "शोध" + "Search" "%s साठी वर स्लाइड करा." "%s साठी डावीकडे स्लाइड करा." "अलार्म, रिमाइंडर, इव्‍हेंट आणि तुम्ही निश्चित केलेल्या कॉलर व्यतिरिक्त तुम्हाला कोणत्याही आवाज आणि कंपनांचा व्यत्त्यय आणला जाणार नाही. तरीही तुम्ही प्ले करायचे ठरवलेले कोणतेही संगीत, व्हिडिओ आणि गेमचे आवाज ऐकू शकतात." @@ -1075,7 +1075,7 @@ "शिफारशी लोड करत आहे" "मीडिया" "सध्याचे सेशन लपवा." - "लपवा" + "डिसमिस करा" "पुन्हा सुरू करा" "सेटिंग्ज" "निष्क्रिय, ॲप तपासा" diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index dcaded56062a..f72e3ef75607 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -1075,7 +1075,7 @@ "Memuatkan cadangan" "Media" "Sembunyikan sesi semasa." - "Sembunyikan" + "Tolak" "Sambung semula" "Tetapan" "Tidak aktif, semak apl" diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 1bf289bd2450..8f5b47e9fbcf 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -1075,7 +1075,7 @@ "အကြံပြုချက်များ ဖွင့်နေသည်" "မီဒီယာ" "လက်ရှိ စက်ရှင်ကို ဖျောက်ထားမည်။" - "ဖျောက်ထားမည်" + "ပယ်ရန်" "ဆက်လုပ်ရန်" "ဆက်တင်များ" "ရပ်နေသည်၊ အက်ပ်ကို စစ်ဆေးပါ" diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index bfd5dab673ec..56851e421dc7 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -1075,7 +1075,7 @@ "Laster inn anbefalinger" "Medier" "Skjul den nåværende økten." - "Skjul" + "Lukk" "Gjenoppta" "Innstillinger" "Inaktiv. Sjekk appen" diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 7edeea4ff561..61e500afeb4a 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -1075,7 +1075,7 @@ "सिफारिसहरू लोड गर्दै" "मिडिया" "हालको सत्र लुकाउनुहोस्।" - "लुकाउनुहोस्" + "हटाउनुहोस्" "सुचारु गर्नुहोस्" "सेटिङ" "निष्क्रिय छ, एप जाँच गर्नु…" diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 3145568ad60c..d5c831cebb23 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -1075,7 +1075,7 @@ "Aanbevelingen laden" "Media" "De huidige sessie verbergen." - "Verbergen" + "Sluiten" "Hervatten" "Instellingen" "Inactief, check de app" diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index b9db632c9d25..6ab0791ad9c8 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -125,7 +125,7 @@ "ଆକ୍ସେସିବିଲିଟୀ" "ସ୍କ୍ରୀନ୍‌କୁ ଘୁରାନ୍ତୁ" "ଓଭରଭିଉ" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "କ୍ୟାମେରା" "ଫୋନ୍‍" "ଭଏସ୍‌ ସହାୟକ" @@ -441,7 +441,7 @@ "ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବାକୁ ଆଉ %s ଅଛି" "ଚାର୍ଜ ହେଉନାହିଁ" "ନେଟ୍‍ୱର୍କ\nମନିଟର୍‍ କରାଯାଇପାରେ" - "ସର୍ଚ୍ଚ" + "Search" "%s ପାଇଁ ଉପରକୁ ସ୍ଲାଇଡ୍‍ କରନ୍ତୁ।" "%s ପାଇଁ ବାମକୁ ସ୍ଲାଇଡ୍ କରନ୍ତୁ" "ଆଲାର୍ମ, ରିମାଇଣ୍ଡର୍‌, ଇଭେଣ୍ଟ ଏବଂ ଆପଣ ନିର୍ଦ୍ଦିଷ୍ଟ କରିଥିବା କଲର୍‌ଙ୍କ ବ୍ୟତୀତ ଆପଣଙ୍କ ଧ୍ୟାନ ଅନ୍ୟ କୌଣସି ଧ୍ୱନୀ ଏବଂ ଭାଇବ୍ରେଶନ୍‌ରେ ଆକର୍ଷଣ କରାଯିବନାହିଁ। ମ୍ୟୁଜିକ୍‍, ଭିଡିଓ ଏବଂ ଗେମ୍‌ ସମେତ ନିଜେ ଚଲାଇବାକୁ ବାଛିଥିବା ଅନ୍ୟ ସବୁକିଛି ଆପଣ ଶୁଣିପାରିବେ।" @@ -1075,7 +1075,7 @@ "ସୁପାରିଶଗୁଡ଼ିକ ଲୋଡ୍ କରାଯାଉଛି" "ମିଡିଆ" "ବର୍ତ୍ତମାନର ସେସନ୍ ଲୁଚାନ୍ତୁ।" - "ଲୁଚାନ୍ତୁ" + "ଖାରଜ କରନ୍ତୁ" "ପୁଣି ଆରମ୍ଭ କରନ୍ତୁ" "ସେଟିଂସ୍" "ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ" diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 7a2effc264a6..2e481f53963b 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -1075,7 +1075,7 @@ "ਸਿਫ਼ਾਰਸ਼ਾਂ ਲੋਡ ਹੋ ਰਹੀਆਂ ਹਨ" "ਮੀਡੀਆ" "ਮੌਜੂਦਾ ਸੈਸ਼ਨ ਨੂੰ ਲੁਕਾਓ।" - "ਲੁਕਾਓ" + "ਖਾਰਜ ਕਰੋ" "ਮੁੜ-ਚਾਲੂ ਕਰੋ" "ਸੈਟਿੰਗਾਂ" "ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ" diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index ae5f3d282db6..d946f9a4fbb4 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -1087,7 +1087,7 @@ "Wczytuję rekomendacje" "Multimedia" "Ukryj bieżącą sesję." - "Ukryj" + "Odrzuć" "Wznów" "Ustawienia" "Nieaktywny, sprawdź aplikację" diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index f5339d3e1d99..9c0db7a4e71d 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -1075,7 +1075,7 @@ "Carregando recomendações" "Mídia" "Ocultar a sessão atual." - "Ocultar" + "Dispensar" "Retomar" "Configurações" "Inativo, verifique o app" diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 982dbcf1d624..478d8fdd644c 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -1075,7 +1075,7 @@ "A carregar recomendações…" "Multimédia" "Oculte a sessão atual." - "Ocultar" + "Ignorar" "Retomar" "Definições" "Inativa. Consulte a app." diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index f5339d3e1d99..9c0db7a4e71d 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -1075,7 +1075,7 @@ "Carregando recomendações" "Mídia" "Ocultar a sessão atual." - "Ocultar" + "Dispensar" "Retomar" "Configurações" "Inativo, verifique o app" diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 1b9f34b9f7e3..54d6d5583bc0 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -1081,7 +1081,7 @@ "Se încarcă recomandările" "Media" "Ascunde sesiunea actuală." - "Ascunde" + "Închideți" "Reia" "Setări" "Inactiv, verificați aplicația" diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 6bf24f58071e..a9bb44b79a97 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -1087,7 +1087,7 @@ "Загрузка рекомендаций…" "Медиа" "Скрыть текущий сеанс?" - "Скрыть" + "Скрыть" "Возобновить" "Настройки" "Нет ответа. Проверьте приложение." diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 347ad69d5cfc..fe3457b5f45a 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -1075,7 +1075,7 @@ "නිර්දේශ පූරණය කරමින්" "මාධ්‍ය" "වත්මන් සැසිය සඟවන්න." - "සඟවන්න" + "ඉවත ලන්න" "නැවත පටන් ගන්න" "සැකසීම්" "අක්‍රියයි, යෙදුම පරීක්ෂා කරන්න" diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 986fec63e844..ae6154d8ef9a 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -1087,7 +1087,7 @@ "Načítavajú sa odporúčania" "Médiá" "Skryť aktuálnu reláciu." - "Skryť" + "Zavrieť" "Pokračovať" "Nastavenia" "Neaktívne, preverte aplikáciu" diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index c44535fd8182..8e9544edf7b1 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -1087,7 +1087,7 @@ "Nalaganje priporočil" "Predstavnost" "Skrije trenutno sejo." - "Skrij" + "Opusti" "Nadaljuj" "Nastavitve" "Neaktivno, poglejte aplikacijo" diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 056e5b424b46..a78c31381ad8 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -1075,7 +1075,7 @@ "Po ngarkon rekomandimet" "Media" "Fshih sesionin aktual." - "Fshih" + "Hiq" "Vazhdo" "Cilësimet" "Joaktive, kontrollo aplikacionin" diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 5fccdd04fff2..cfb33e89856f 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -1081,7 +1081,7 @@ "Учитавају се препоруке" "Медији" "Сакријте актуелну сесију." - "Сакриј" + "Одбаци" "Настави" "Подешавања" "Неактивно. Видите апликацију" diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 5674c04636fa..baa69b491a07 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -1075,7 +1075,7 @@ "Rekommendationer läses in" "Media" "Dölj den aktuella sessionen." - "Dölj" + "Stäng" "Återuppta" "Inställningar" "Inaktiv, kolla appen" diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 72ef2c45ec10..09c42e771156 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -1075,7 +1075,7 @@ "Inapakia mapendekezo" "Maudhui" "Ficha kipindi cha sasa." - "Ficha" + "Ondoa" "Endelea" "Mipangilio" "Haitumiki, angalia programu" diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 12d4bc0fc1f4..134fc2dcaa7d 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -1075,7 +1075,7 @@ "பரிந்துரைகளை ஏற்றுகிறது" "மீடியா" "இந்த அமர்வை மறையுங்கள்." - "மறை" + "மூடுக" "தொடர்க" "அமைப்புகள்" "செயலில் இல்லை , சரிபார்க்கவும்" diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 830a3aefed5b..a50399069ca3 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -125,7 +125,7 @@ "యాక్సెస్ సామర్థ్యం" "స్క్రీన్‌ను తిప్పండి" "ఓవర్‌వ్యూ" - "వెతుకు" + "సెర్చ్" "కెమెరా" "ఫోన్" "వాయిస్ అసిస్టెంట్" @@ -441,7 +441,7 @@ "పూర్తిగా నిండటానికి %s" "ఛార్జ్ కావడం లేదు" "నెట్‌వర్క్\nపర్యవేక్షించబడవచ్చు" - "శోధించండి" + "సెర్చ్" "%s కోసం పైకి స్లైడ్ చేయండి." "%s కోసం ఎడమవైపుకు స్లైడ్ చేయండి." "మీరు పేర్కొనే అలారాలు, రిమైండర్‌లు, ఈవెంట్‌లు మరియు కాలర్‌ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్‌లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు." @@ -1075,7 +1075,7 @@ "సిఫార్సులు లోడ్ అవుతున్నాయి" "మీడియా" "ప్రస్తుత సెషన్‌ను దాచు." - "దాచు" + "విస్మరించు" "కొనసాగించండి" "సెట్టింగ్‌లు" "ఇన్‌యాక్టివ్, యాప్ చెక్ చేయండి" diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 178accd66824..52d99171d654 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -1075,7 +1075,7 @@ "กำลังโหลดคำแนะนำ" "สื่อ" "ซ่อนเซสชันปัจจุบัน" - "ซ่อน" + "ปิด" "เล่นต่อ" "การตั้งค่า" "ไม่มีการใช้งาน โปรดตรวจสอบแอป" diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 7d1f45f72d07..b7eca6399b7b 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -1075,7 +1075,7 @@ "Nilo-load ang rekomendasyon" "Media" "Itago ang kasalukuyang session." - "Itago" + "I-dismiss" "Ituloy" "Mga Setting" "Hindi aktibo, tingnan ang app" diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index d26c8d8eeeed..e5cd3f6b8204 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -1075,7 +1075,7 @@ "Öneriler yükleniyor" "Medya" "Mevcut oturumu gizle." - "Gizle" + "Kapat" "Devam ettir" "Ayarlar" "Devre dışı, uygulamaya bakın" diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 77347d4d30ea..412e5133fdac 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -1087,7 +1087,7 @@ "Завантаження рекомендацій" "Медіа" "Приховати поточний сеанс." - "Приховати" + "Закрити" "Відновити" "Налаштування" "Неактивно, перейдіть у додаток" diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 7b9ac7122320..ab096baeebae 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -1075,7 +1075,7 @@ "تجاویز لوڈ ہو رہی ہیں" "میڈیا" "موجودہ سیشن چھپائیں۔" - "چھپائیں" + "برخاست کریں" "دوبارہ شروع کریں" "ترتیبات" "غیر فعال، ایپ چیک کریں" diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 96e0ef34c601..123e9460a85b 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -1075,7 +1075,7 @@ "Tavsiyalar yuklanmoqda" "Media" "Joriy seans berkitilsin." - "Berkitish" + "Yopish" "Davom etish" "Sozlamalar" "Nofaol. Ilovani tekshiring" diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 9136807d077a..41033e5fc6eb 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -1075,7 +1075,7 @@ "Đang tải các đề xuất" "Nội dung nghe nhìn" "Ẩn phiên hiện tại." - "Ẩn" + "Đóng" "Tiếp tục" "Cài đặt" "Không hoạt động, hãy kiểm tra ứng dụng" diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 9f694296c3ca..9b3c55ddf943 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -1075,7 +1075,7 @@ "正在加载推荐内容" "媒体" "隐藏当前会话。" - "隐藏" + "关闭" "继续播放" "设置" "无效,请检查应用" diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index b4431c480954..e061aebcafdd 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -1075,7 +1075,7 @@ "正在載入建議" "媒體" "隱藏目前的工作階段。" - "隱藏" + "關閉" "繼續播放" "設定" "已停用,請檢查應用程式" diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index e4a4513f2922..a340e37fa2e1 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -1075,7 +1075,7 @@ "正在載入建議控制項" "媒體" "隱藏目前的工作階段。" - "隱藏" + "關閉" "繼續播放" "設定" "無效,請查看應用程式" diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index cb6df335c8b2..679659587d6e 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -1075,7 +1075,7 @@ "Ilayisha izincomo" "Imidiya" "Fihla iseshini yamanje." - "Fihla" + "Cashisa" "Qalisa kabusha" "Izilungiselelo" "Akusebenzi, hlola uhlelo lokusebenza" -- GitLab From 412a546b28b73450de4f2beee7571c0800b40290 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 15 Aug 2020 05:07:45 -0700 Subject: [PATCH 218/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I2cc57c01f4701fd4be2f9754ca0fbe9ff53c2b6e --- packages/PrintSpooler/res/values-as/strings.xml | 2 +- packages/PrintSpooler/res/values-bn/strings.xml | 2 +- packages/PrintSpooler/res/values-kn/strings.xml | 2 +- packages/PrintSpooler/res/values-ml/strings.xml | 2 +- packages/PrintSpooler/res/values-mr/strings.xml | 2 +- packages/PrintSpooler/res/values-or/strings.xml | 2 +- packages/PrintSpooler/res/values-te/strings.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/PrintSpooler/res/values-as/strings.xml b/packages/PrintSpooler/res/values-as/strings.xml index a93fceb87959..b6b287ff66aa 100644 --- a/packages/PrintSpooler/res/values-as/strings.xml +++ b/packages/PrintSpooler/res/values-as/strings.xml @@ -47,7 +47,7 @@ "PDFৰ জৰিয়তে ছেভ কৰক" "প্ৰিণ্ট বিকল্পসমূহ বিস্তাৰ কৰা হ’ল" "প্ৰিণ্ট বিকল্পসমূহ সংকুচিত কৰা হ’ল" - "সন্ধান কৰক" + "Search" "সকলো প্ৰিণ্টাৰ" "সেৱা যোগ কৰক" "সন্ধান বাকচটো দেখুওৱা হ’ল" diff --git a/packages/PrintSpooler/res/values-bn/strings.xml b/packages/PrintSpooler/res/values-bn/strings.xml index 637becbe23f0..b2e1eed85f0c 100644 --- a/packages/PrintSpooler/res/values-bn/strings.xml +++ b/packages/PrintSpooler/res/values-bn/strings.xml @@ -47,7 +47,7 @@ "পিডিএফ হিসাবে সেভ করুন" "প্রিন্ট বিকল্প প্রসারিত হয়েছে" "প্রিন্ট বিকল্প সংকুচিত হয়েছে" - "খুঁজুন" + "সার্চ" "সমস্ত প্রিন্টার" "পরিষেবা যোগ করুন" "সার্চ বাক্স দেখানো হচ্ছে" diff --git a/packages/PrintSpooler/res/values-kn/strings.xml b/packages/PrintSpooler/res/values-kn/strings.xml index 150ede4f8e62..261fe4b0de9a 100644 --- a/packages/PrintSpooler/res/values-kn/strings.xml +++ b/packages/PrintSpooler/res/values-kn/strings.xml @@ -47,7 +47,7 @@ "PDF ಗೆ ಉಳಿಸು" "ಪ್ರಿಂಟ್ ಆಯ್ಕೆಗಳನ್ನು ವಿಸ್ತರಿಸಲಾಗಿದೆ" "ಪ್ರಿಂಟ್ ಆಯ್ಕೆಗಳನ್ನು ಮುಚ್ಚಲಾಗಿದೆ" - "ಹುಡುಕಿ" + "Search" "ಎಲ್ಲಾ ಪ್ರಿಂಟರ್‌ಗಳು" "ಸೇವೆಯನ್ನು ಸೇರಿಸು" "ಹುಡುಕಾಟ ಪೆಟ್ಟಿಗೆಯನ್ನು ತೋರಿಸಲಾಗಿದೆ" diff --git a/packages/PrintSpooler/res/values-ml/strings.xml b/packages/PrintSpooler/res/values-ml/strings.xml index dbcd34b1360d..73af95d2e117 100644 --- a/packages/PrintSpooler/res/values-ml/strings.xml +++ b/packages/PrintSpooler/res/values-ml/strings.xml @@ -47,7 +47,7 @@ "PDF-ൽ സംരക്ഷിക്കുക" "പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്‌ഷനുകൾ വിപുലീകരിച്ചു" "പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്‌ഷനുകൾ ചുരുക്കി" - "തിരയൽ" + "Search" "എല്ലാ പ്രിന്ററുകളും" "സേവനം ചേർക്കുക" "തിരയൽ ബോക്‌സ് ദൃശ്യമാക്കിയിരിക്കുന്നു" diff --git a/packages/PrintSpooler/res/values-mr/strings.xml b/packages/PrintSpooler/res/values-mr/strings.xml index 44456b4cae05..4d7e919ad125 100644 --- a/packages/PrintSpooler/res/values-mr/strings.xml +++ b/packages/PrintSpooler/res/values-mr/strings.xml @@ -47,7 +47,7 @@ "पीडीएफ वर सेव्ह करा" "प्रिंट पर्याय विस्तृत झाले" "प्रिंट पर्याय संक्षिप्त झाले" - "शोध" + "Search" "सर्व प्रिंटर" "सेवा जोडा" "शोध बॉक्स दर्शविला" diff --git a/packages/PrintSpooler/res/values-or/strings.xml b/packages/PrintSpooler/res/values-or/strings.xml index a1675fa7ca76..7000b95b35d6 100644 --- a/packages/PrintSpooler/res/values-or/strings.xml +++ b/packages/PrintSpooler/res/values-or/strings.xml @@ -47,7 +47,7 @@ "PDFରେ ସେଭ୍‍ କରନ୍ତୁ" "ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ବଡ଼ କରାଯାଇଛି" "ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ଛୋଟ କରାଯାଇଛି" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "ସମସ୍ତ ପ୍ରିଣ୍ଟର୍‌" "ସେବା ଯୋଗ କରନ୍ତୁ" "ସର୍ଚ୍ଚ ବକ୍ସ ଦେଖାଯାଇଛି" diff --git a/packages/PrintSpooler/res/values-te/strings.xml b/packages/PrintSpooler/res/values-te/strings.xml index b01b50a60f6b..79944bb9994c 100644 --- a/packages/PrintSpooler/res/values-te/strings.xml +++ b/packages/PrintSpooler/res/values-te/strings.xml @@ -47,7 +47,7 @@ "PDF వలె సేవ్ చేయి" "ముద్రణ ఎంపికలు విస్తరించబడ్డాయి" "ముద్రణ ఎంపికలు కుదించబడ్డాయి" - "వెతుకు" + "సెర్చ్" "అన్ని ప్రింటర్‌లు" "సేవను జోడించు" "శోధన పెట్టె చూపబడింది" -- GitLab From 12a31d14ce77e5eded459029c8b0fd29c2e6af9e Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 15 Aug 2020 06:02:49 -0700 Subject: [PATCH 219/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I9c94741491c64ea81b8c70c4347751db76cdaae3 --- packages/SoundPicker/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SoundPicker/res/values-ar/strings.xml b/packages/SoundPicker/res/values-ar/strings.xml index a91795545269..f8844e94815f 100644 --- a/packages/SoundPicker/res/values-ar/strings.xml +++ b/packages/SoundPicker/res/values-ar/strings.xml @@ -25,5 +25,5 @@ "حذف" "يتعذر إضافة نغمة رنين مخصصة" "يتعذر حذف نغمة الرنين المخصصة" - "Sounds" + "الأصوات" -- GitLab From d6d30963d7bc7299892f2add44ba5b72a374f342 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 15 Aug 2020 06:58:20 -0700 Subject: [PATCH 220/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I3e2c0634be1101928170606dfc9a9900eba722ee --- packages/SystemUI/res/values-am/strings.xml | 2 +- packages/SystemUI/res/values-as/strings.xml | 4 ++-- packages/SystemUI/res/values-bn/strings.xml | 4 ++-- packages/SystemUI/res/values-gu/strings.xml | 2 +- packages/SystemUI/res/values-kn/strings.xml | 4 ++-- packages/SystemUI/res/values-ko/strings.xml | 4 ++-- packages/SystemUI/res/values-ml/strings.xml | 4 ++-- packages/SystemUI/res/values-mr/strings.xml | 4 ++-- packages/SystemUI/res/values-or/strings.xml | 4 ++-- packages/SystemUI/res/values-te/strings.xml | 4 ++-- packages/SystemUI/res/values-uz/strings.xml | 2 +- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 8710cb805a0b..30a09d3d4e5b 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -73,7 +73,7 @@ "መሣሪያዎን ከፈሳሽ ወይም ፍርስራሽ ለመጠበቅ ሲባል የዩኤስቢ ወደቡ ተሰናክሏል፣ እና ማናቸውም ተቀጥላዎችን አያገኝም።\n\nየዩኤስቢ ወደቡን እንደገና መጠቀም ችግር በማይኖረው ጊዜ ማሳወቂያ ይደርሰዎታል።" "ኃይል መሙያዎችን እና ተጨማሪ መሣሪያዎችን ፈልጎ ለማግኘት የነቃ የዩኤስቢ ወደብ" "ዩኤስቢ አንቃ" - "የበለጠ መረዳት" + "የበለጠ ለመረዳት" "ማያ እንዲሞላ አጉላ" "ማያ ለመሙለት ሳብ" "ቅጽበታዊ ገጽ እይታ" diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 5b54f77dd043..43bfa890d434 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -125,7 +125,7 @@ "দিব্যাংগসকলৰ বাবে থকা সুবিধাসমূহ" "স্ক্ৰীণ ঘূৰাওক" "অৱলোকন" - "সন্ধান কৰক" + "Search" "কেমেৰা" "ফ\'ন" "কণ্ঠধ্বনিৰে সহায়" @@ -441,7 +441,7 @@ "বেটাৰিৰ চ্চাৰ্জ সম্পূর্ণ হ\'বলৈ %s বাকী" "চ্চার্জ কৰি থকা নাই" "নেটৱৰ্ক \nনিৰীক্ষণ কৰা হ\'ব পাৰে" - "অনুসন্ধান কৰক" + "Search" "%sৰ বাবে ওপৰলৈ শ্লাইড কৰক।" "%sৰ বাবে বাওঁফাললৈ শ্লাইড কৰক।" "আপুনি নিৰ্দিষ্ট কৰা এলাৰ্ম, ৰিমাইণ্ডাৰ, ইভেন্ট আৰু কল কৰোঁতাৰ বাহিৰে আন কোনো শব্দৰ পৰা আপুনি অসুবিধা নাপাব। কিন্তু, সংগীত, ভিডিঅ\' আৰু খেলসমূহকে ধৰি আপুনি প্লে কৰিব খোজা যিকোনো বস্তু তথাপি শুনিব পাৰিব।" diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 08cf5d19d315..f9627ab4db19 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -125,7 +125,7 @@ "অ্যাক্সেসযোগ্যতা" "স্ক্রিন ঘোরান" "এক নজরে" - "খুঁজুন" + "সার্চ" "ক্যামেরা" "ফোন" "ভয়েস সহায়তা" @@ -441,7 +441,7 @@ "পূর্ণ হতে %s সময় লাগবে" "চার্জ হচ্ছে না" "নেটওয়ার্ক নিরীক্ষণ\nকরা হতে পারে" - "খুঁজুন" + "সার্চ" "%s এর জন্য উপরের দিকে স্লাইড করুন৷" "%s এর জন্য বাঁ দিকে স্লাইড করুন৷" "অ্যালার্ম, রিমাইন্ডার, ইভেন্ট, এবং আপনার নির্দিষ্ট করে দেওয়া ব্যক্তিদের কল ছাড়া অন্য কোনও আওয়াজ বা ভাইব্রেশন হবে না। তবে সঙ্গীত, ভিডিও, এবং গেম সহ আপনি যা কিছু চালাবেন তার আওয়াজ শুনতে পাবেন।" diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 53e0fc9f5e45..b495bb357774 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -125,7 +125,7 @@ "ઍક્સેસિબિલિટી" "સ્ક્રીન ફેરવો" "ઝલક" - "શોધો" + "શોધ" "કૅમેરો" "ફોન" "વૉઇસ સહાય" diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index c41e8bb2396a..0aa53759a36c 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -125,7 +125,7 @@ "ಪ್ರವೇಶಿಸುವಿಕೆ" "ಪರದೆಯನ್ನು ತಿರುಗಿಸಿ" "ಸಮಗ್ರ ನೋಟ" - "ಹುಡುಕಿ" + "Search" "ಕ್ಯಾಮರಾ" "ಫೋನ್" "ಧ್ವನಿ ಸಹಾಯಕ" @@ -441,7 +441,7 @@ "%s ಪೂರ್ಣಗೊಳ್ಳುವವರೆಗೆ" "ಚಾರ್ಜ್‌ ಆಗುತ್ತಿಲ್ಲ" "ನೆಟ್‌ವರ್ಕ್\n ವೀಕ್ಷಿಸಬಹುದಾಗಿರುತ್ತದೆ" - "ಹುಡುಕಿ" + "Search" "%s ಗಾಗಿ ಮೇಲಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ." "%s ಗಾಗಿ ಎಡಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ." "ಅಲಾರಾಂಗಳು, ಜ್ಞಾಪನೆಗಳು, ಈವೆಂಟ್‌ಗಳು ಹಾಗೂ ನೀವು ಸೂಚಿಸಿರುವ ಕರೆದಾರರನ್ನು ಹೊರತುಪಡಿಸಿ ಬೇರಾವುದೇ ಸದ್ದುಗಳು ಅಥವಾ ವೈಬ್ರೇಶನ್‌ಗಳು ನಿಮಗೆ ತೊಂದರೆ ನೀಡುವುದಿಲ್ಲ. ಹಾಗಿದ್ದರೂ, ನೀವು ಪ್ಲೇ ಮಾಡುವ ಸಂಗೀತ, ವೀಡಿಯೊಗಳು ಮತ್ತು ಆಟಗಳ ಆಡಿಯೊವನ್ನು ನೀವು ಕೇಳಿಸಿಕೊಳ್ಳುತ್ತೀರಿ." diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index a858576bc4d2..490ce15986e2 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -502,10 +502,10 @@ "절전 모드 사용 중" "성능 및 백그라운드 데이터를 줄입니다." "절전 모드 사용 중지" - "%s이(가) 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다." + "%s이 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다." "이 기능을 제공하는 서비스는 녹화 또는 전송 중에 화면에 표시되거나 기기에서 재생되는 모든 정보에 액세스할 수 있습니다. 여기에는 비밀번호, 결제 세부정보, 사진, 메시지, 재생하는 오디오 같은 정보가 포함됩니다." "녹화 또는 전송을 시작하시겠습니까?" - "%s(으)로 녹화 또는 전송을 시작하시겠습니까?" + "%s으로 녹화 또는 전송을 시작하시겠습니까?" "다시 표시 안함" "모두 지우기" "관리" diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 4c89859ca36b..070364d14cc6 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -125,7 +125,7 @@ "ഉപയോഗസഹായി" "സ്‌ക്രീൻ തിരിക്കുക" "അവലോകനം" - "തിരയൽ" + "Search" "ക്യാമറ" "ഫോണ്‍" "വോയ്‌സ് സഹായം" @@ -441,7 +441,7 @@ "ഫുൾ ചാർജാകാൻ, %s" "ചാർജ്ജുചെയ്യുന്നില്ല" "നെറ്റ്‌വർക്ക്\nനിരീക്ഷിക്കപ്പെടാം" - "തിരയൽ" + "Search" "%s എന്നതിനായി മുകളിലേയ്‌ക്ക് സ്ലൈഡുചെയ്യുക." "%s എന്നതിനായി ഇടത്തേയ്‌ക്ക് സ്ലൈഡുചെയ്യുക." "നിങ്ങൾ സജ്ജീകരിച്ച അലാറങ്ങൾ, റിമൈൻഡറുകൾ, ഇവന്റുകൾ, കോളർമാർ എന്നിവയിൽ നിന്നുള്ള ശബ്‌ദങ്ങളും വൈബ്രേഷനുകളുമൊഴികെ മറ്റൊന്നും നിങ്ങളെ ശല്യപ്പെടുത്തുകയില്ല. സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയുൾപ്പെടെ പ്ലേ ചെയ്യുന്നതെന്തും നിങ്ങൾക്ക് ‌തുടർന്നും കേൾക്കാൻ കഴിയും." diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 2620689076a5..fc17d1e0bde8 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -125,7 +125,7 @@ "अ‍ॅक्सेसिबिलिटी" "स्क्रीन फिरवा" "अवलोकन" - "शोधा" + "Search" "कॅमेरा" "फोन" "व्हॉइस सहाय्य" @@ -441,7 +441,7 @@ "%s पूर्ण होईपर्यंत" "चार्ज होत नाही" "नेटवर्कचे परीक्षण\nकेले जाऊ शकते" - "शोध" + "Search" "%s साठी वर स्लाइड करा." "%s साठी डावीकडे स्लाइड करा." "अलार्म, रिमाइंडर, इव्‍हेंट आणि तुम्ही निश्चित केलेल्या कॉलर व्यतिरिक्त तुम्हाला कोणत्याही आवाज आणि कंपनांचा व्यत्त्यय आणला जाणार नाही. तरीही तुम्ही प्ले करायचे ठरवलेले कोणतेही संगीत, व्हिडिओ आणि गेमचे आवाज ऐकू शकतात." diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index c35b22a8c175..c269c6b5af73 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -125,7 +125,7 @@ "ଆକ୍ସେସିବିଲିଟୀ" "ସ୍କ୍ରୀନ୍‌କୁ ଘୁରାନ୍ତୁ" "ଓଭରଭିଉ" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "କ୍ୟାମେରା" "ଫୋନ୍‍" "ଭଏସ୍‌ ସହାୟକ" @@ -441,7 +441,7 @@ "ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବାକୁ ଆଉ %s ଅଛି" "ଚାର୍ଜ ହେଉନାହିଁ" "ନେଟ୍‍ୱର୍କ\nମନିଟର୍‍ କରାଯାଇପାରେ" - "ସର୍ଚ୍ଚ" + "Search" "%s ପାଇଁ ଉପରକୁ ସ୍ଲାଇଡ୍‍ କରନ୍ତୁ।" "%s ପାଇଁ ବାମକୁ ସ୍ଲାଇଡ୍ କରନ୍ତୁ" "ଆଲାର୍ମ, ରିମାଇଣ୍ଡର୍‌, ଇଭେଣ୍ଟ ଏବଂ ଆପଣ ନିର୍ଦ୍ଦିଷ୍ଟ କରିଥିବା କଲର୍‌ଙ୍କ ବ୍ୟତୀତ ଆପଣଙ୍କ ଧ୍ୟାନ ଅନ୍ୟ କୌଣସି ଧ୍ୱନୀ ଏବଂ ଭାଇବ୍ରେଶନ୍‌ରେ ଆକର୍ଷଣ କରାଯିବନାହିଁ। ମ୍ୟୁଜିକ୍‍, ଭିଡିଓ ଏବଂ ଗେମ୍‌ ସମେତ ନିଜେ ଚଲାଇବାକୁ ବାଛିଥିବା ଅନ୍ୟ ସବୁକିଛି ଆପଣ ଶୁଣିପାରିବେ।" diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index addc1b432e86..490c9de8cec6 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -125,7 +125,7 @@ "యాక్సెస్ సామర్థ్యం" "స్క్రీన్‌ను తిప్పండి" "ఓవర్‌వ్యూ" - "వెతుకు" + "సెర్చ్" "కెమెరా" "ఫోన్" "వాయిస్ అసిస్టెంట్" @@ -441,7 +441,7 @@ "పూర్తిగా నిండటానికి %s" "ఛార్జ్ కావడం లేదు" "నెట్‌వర్క్\nపర్యవేక్షించబడవచ్చు" - "శోధించండి" + "సెర్చ్" "%s కోసం పైకి స్లైడ్ చేయండి." "%s కోసం ఎడమవైపుకు స్లైడ్ చేయండి." "మీరు పేర్కొనే అలారాలు, రిమైండర్‌లు, ఈవెంట్‌లు మరియు కాలర్‌ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్‌లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు." diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 7c355c7315c2..d48d95b4edf2 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -227,7 +227,7 @@ "Rouming" "EDGE" "Wi-Fi" - "SIM karta solinmagan." + "SIM kartasiz." "Mobil internet" "Mobil internet yoniq" "Mobil internet yoqilmagan" -- GitLab From 68391260368b1ae444441db172ce72f75ce13852 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Mon, 17 Aug 2020 10:48:53 +0800 Subject: [PATCH 221/536] Update process info while making activity visible The top fullscreen activity converted to translucent while running exit transition, which resulted in the activity below being visible. Since the the process state of the activity below remained as background, some operations required to be done as a foreground (opening camera) was being rejected. Bug: 162216572 Test: back to camera from filmstrip Change-Id: Ib746f5a2c5409f142819f7eba89c7948c756c23e --- .../core/java/com/android/server/wm/ActivityRecord.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 3e9377ed0664..7daea6992943 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -4735,6 +4735,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A Slog.v(TAG_VISIBILITY, "Start visible activity, " + this); } setState(STARTED, "makeActiveIfNeeded"); + + // Update process info while making an activity from invisible to visible, to make + // sure the process state is updated to foreground. + if (app != null) { + app.updateProcessInfo(false /* updateServiceConnectionActivities */, + true /* activityChange */, true /* updateOomAdj */, + true /* addPendingTopUid */); + } + try { mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken, StartActivityItem.obtain()); -- GitLab From 87c7f4116d35f94d62697cd6e16498d8baf60a06 Mon Sep 17 00:00:00 2001 From: Kyunglyul Hyun Date: Thu, 13 Aug 2020 23:42:51 +0900 Subject: [PATCH 222/536] MediaRouter: Create BluetoothRouteProvider for each user The bluetooth service manages the active device for each user and sent broadcast for each user. BluetoothRouteProvider was singleton and listened broadcast from the owner (uid=0) only , which failed to catch correct events when the foreground user is not the owner. This CL fixes that by creating BluetoothRouteProvider per user and listening to the events of each user. Bug: 162541640 Test: manually open the output switcher and check bluetooth state with switching users and run cts Change-Id: Iabab6f7830ce0224b7f73a7c5cfb863aebf5562b (cherry picked from commit 715b6488aeaa99b9949532d8a4608c3576f853f4) --- .../server/media/BluetoothRouteProvider.java | 25 +++++++++++-------- .../server/media/MediaRouter2ServiceImpl.java | 3 ++- .../media/SystemMediaRoute2Provider.java | 10 +++++--- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java index 3a4dfaf9bfcd..0b3cdae9231e 100644 --- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java +++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java @@ -34,6 +34,7 @@ import android.content.IntentFilter; import android.media.AudioManager; import android.media.AudioSystem; import android.media.MediaRoute2Info; +import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.util.Slog; @@ -55,7 +56,6 @@ class BluetoothRouteProvider { private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final String HEARING_AID_ROUTE_ID_PREFIX = "HEARING_AID_"; - private static BluetoothRouteProvider sInstance; @SuppressWarnings("WeakerAccess") /* synthetic access */ // Maps hardware address to BluetoothRouteInfo @@ -79,19 +79,21 @@ class BluetoothRouteProvider { private final BroadcastReceiver mBroadcastReceiver = new BluetoothBroadcastReceiver(); private final BluetoothProfileListener mProfileListener = new BluetoothProfileListener(); - static synchronized BluetoothRouteProvider getInstance(@NonNull Context context, + /** + * Create an instance of {@link BluetoothRouteProvider}. + * It may return {@code null} if Bluetooth is not supported on this hardware platform. + */ + @Nullable + static BluetoothRouteProvider createInstance(@NonNull Context context, @NonNull BluetoothRoutesUpdatedListener listener) { Objects.requireNonNull(context); Objects.requireNonNull(listener); - if (sInstance == null) { - BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); - if (btAdapter == null) { - return null; - } - sInstance = new BluetoothRouteProvider(context, btAdapter, listener); + BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); + if (btAdapter == null) { + return null; } - return sInstance; + return new BluetoothRouteProvider(context, btAdapter, listener); } private BluetoothRouteProvider(Context context, BluetoothAdapter btAdapter, @@ -103,7 +105,7 @@ class BluetoothRouteProvider { buildBluetoothRoutes(); } - public void start() { + public void start(UserHandle user) { mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP); mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEARING_AID); @@ -118,7 +120,8 @@ class BluetoothRouteProvider { addEventReceiver(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED, deviceStateChangedReceiver); - mContext.registerReceiver(mBroadcastReceiver, mIntentFilter, null, null); + mContext.registerReceiverAsUser(mBroadcastReceiver, user, + mIntentFilter, null, null); } /** diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index 875bfdffafcd..1114fe0d9bf8 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -1176,7 +1176,8 @@ class MediaRouter2ServiceImpl { super(Looper.getMainLooper(), null, true); mServiceRef = new WeakReference<>(service); mUserRecord = userRecord; - mSystemProvider = new SystemMediaRoute2Provider(service.mContext); + mSystemProvider = new SystemMediaRoute2Provider(service.mContext, + UserHandle.of(userRecord.mUserId)); mRouteProviders.add(mSystemProvider); mWatcher = new MediaRoute2ProviderWatcher(service.mContext, this, this, mUserRecord.mUserId); diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java index 2c089ca8300e..4f7af9469668 100644 --- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java @@ -45,6 +45,7 @@ import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.util.Slog; @@ -99,7 +100,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } }; - SystemMediaRoute2Provider(Context context) { + SystemMediaRoute2Provider(Context context, UserHandle user) { super(sComponentName); mIsSystemRouteProvider = true; @@ -117,7 +118,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { updateDeviceRoute(newAudioRoutes); // .getInstance returns null if there is no bt adapter available - mBtRouteProvider = BluetoothRouteProvider.getInstance(context, (routes) -> { + mBtRouteProvider = BluetoothRouteProvider.createInstance(context, (routes) -> { publishProviderState(); boolean sessionInfoChanged; @@ -130,11 +131,12 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { IntentFilter intentFilter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION); intentFilter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION); - mContext.registerReceiver(new AudioManagerBroadcastReceiver(), intentFilter); + mContext.registerReceiverAsUser(new AudioManagerBroadcastReceiver(), user, + intentFilter, null, null); if (mBtRouteProvider != null) { mHandler.post(() -> { - mBtRouteProvider.start(); + mBtRouteProvider.start(user); notifyProviderState(); }); } -- GitLab From d83e3a350d1a2a6fd317b19ad22ee5647781870e Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 13 Aug 2020 01:45:09 +0000 Subject: [PATCH 223/536] DO NOT MERGE Don't allow non-instant permissions for instant apps. Bug: 140256621 Test: atest EphemeralTest Change-Id: Id07342c0347c0b4d2ccb3f58a4af9fda7a20d6ef --- .../server/pm/PackageManagerService.java | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 63c721a5da7b..7a38a4533572 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4198,13 +4198,9 @@ public class PackageManagerService extends IPackageManager.Stub Iterator iter = matches.iterator(); while (iter.hasNext()) { final ResolveInfo rInfo = iter.next(); - final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName); - if (ps != null) { - final PermissionsState permissionsState = ps.getPermissionsState(); - if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0) - || Build.IS_ENG) { - continue; - } + if (checkPermission(Manifest.permission.INSTALL_PACKAGES, + rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || Build.IS_ENG) { + continue; } iter.remove(); } @@ -4380,8 +4376,24 @@ public class PackageManagerService extends IPackageManager.Stub final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); // Compute granted permissions only if package has requested permissions - final Set permissions = ArrayUtils.isEmpty(p.getRequestedPermissions()) + Set permissions = ArrayUtils.isEmpty(p.getRequestedPermissions()) ? Collections.emptySet() : permissionsState.getPermissions(userId); + if (state.instantApp) { + permissions = new ArraySet<>(permissions); + permissions.removeIf(permissionName -> { + BasePermission permission = mPermissionManager.getPermissionTEMP( + permissionName); + if (permission == null) { + return true; + } + if (!permission.isInstant()) { + EventLog.writeEvent(0x534e4554, "140256621", UserHandle.getUid(userId, + ps.appId), permissionName); + return true; + } + return false; + }); + } PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags, ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId, ps); @@ -8579,10 +8591,9 @@ public class PackageManagerService extends IPackageManager.Stub private void addPackageHoldingPermissions(ArrayList list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId) { int numMatch = 0; - final PermissionsState permissionsState = ps.getPermissionsState(); for (int i=0; i Date: Thu, 13 Aug 2020 01:45:09 +0000 Subject: [PATCH 224/536] DO NOT MERGE Don't allow non-instant permissions for instant apps. Bug: 140256621 Test: atest EphemeralTest Change-Id: Id07342c0347c0b4d2ccb3f58a4af9fda7a20d6ef --- .../server/pm/PackageManagerService.java | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index ad39760200e0..cfc49392967e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3902,13 +3902,9 @@ public class PackageManagerService extends IPackageManager.Stub Iterator iter = matches.iterator(); while (iter.hasNext()) { final ResolveInfo rInfo = iter.next(); - final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName); - if (ps != null) { - final PermissionsState permissionsState = ps.getPermissionsState(); - if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0) - || Build.IS_ENG) { - continue; - } + if (checkPermission(Manifest.permission.INSTALL_PACKAGES, + rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || Build.IS_ENG) { + continue; } iter.remove(); } @@ -4084,8 +4080,24 @@ public class PackageManagerService extends IPackageManager.Stub final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); // Compute granted permissions only if package has requested permissions - final Set permissions = ArrayUtils.isEmpty(p.requestedPermissions) + Set permissions = ArrayUtils.isEmpty(p.requestedPermissions) ? Collections.emptySet() : permissionsState.getPermissions(userId); + if (state.instantApp) { + permissions = new ArraySet<>(permissions); + permissions.removeIf(permissionName -> { + BasePermission permission = mPermissionManager.getPermissionTEMP( + permissionName); + if (permission == null) { + return true; + } + if (!permission.isInstant()) { + EventLog.writeEvent(0x534e4554, "140256621", UserHandle.getUid(userId, + ps.appId), permissionName); + return true; + } + return false; + }); + } PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags, ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); @@ -8569,10 +8581,9 @@ public class PackageManagerService extends IPackageManager.Stub private void addPackageHoldingPermissions(ArrayList list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId) { int numMatch = 0; - final PermissionsState permissionsState = ps.getPermissionsState(); for (int i=0; i Date: Thu, 13 Aug 2020 01:45:09 +0000 Subject: [PATCH 225/536] DO NOT MERGE Don't allow non-instant permissions for instant apps. Bug: 140256621 Test: atest EphemeralTest Change-Id: Id07342c0347c0b4d2ccb3f58a4af9fda7a20d6ef --- .../server/pm/PackageManagerService.java | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 43f6fd6c3374..0446d8ea726d 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3721,13 +3721,9 @@ public class PackageManagerService extends IPackageManager.Stub Iterator iter = matches.iterator(); while (iter.hasNext()) { final ResolveInfo rInfo = iter.next(); - final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName); - if (ps != null) { - final PermissionsState permissionsState = ps.getPermissionsState(); - if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0) - || Build.IS_ENG) { - continue; - } + if (checkPermission(Manifest.permission.INSTALL_PACKAGES, + rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || Build.IS_ENG) { + continue; } iter.remove(); } @@ -3970,8 +3966,24 @@ public class PackageManagerService extends IPackageManager.Stub final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); // Compute granted permissions only if package has requested permissions - final Set permissions = ArrayUtils.isEmpty(p.requestedPermissions) + Set permissions = ArrayUtils.isEmpty(p.requestedPermissions) ? Collections.emptySet() : permissionsState.getPermissions(userId); + if (state.instantApp) { + permissions = new ArraySet<>(permissions); + permissions.removeIf(permissionName -> { + BasePermission permission = mPermissionManager.getPermissionTEMP( + permissionName); + if (permission == null) { + return true; + } + if (!permission.isInstant()) { + EventLog.writeEvent(0x534e4554, "140256621", UserHandle.getUid(userId, + ps.appId), permissionName); + return true; + } + return false; + }); + } PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags, ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); @@ -7969,10 +7981,9 @@ public class PackageManagerService extends IPackageManager.Stub private void addPackageHoldingPermissions(ArrayList list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId) { int numMatch = 0; - final PermissionsState permissionsState = ps.getPermissionsState(); for (int i=0; i Date: Thu, 13 Aug 2020 01:45:09 +0000 Subject: [PATCH 226/536] DO NOT MERGE Don't allow non-instant permissions for instant apps. Bug: 140256621 Test: atest EphemeralTest Change-Id: Id07342c0347c0b4d2ccb3f58a4af9fda7a20d6ef --- .../server/pm/PackageManagerService.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index cd6f8b7c6043..b4f521893377 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3343,12 +3343,9 @@ public class PackageManagerService extends IPackageManager.Stub Iterator iter = matches.iterator(); while (iter.hasNext()) { final ResolveInfo rInfo = iter.next(); - final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName); - if (ps != null) { - final PermissionsState permissionsState = ps.getPermissionsState(); - if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) { - continue; - } + if (checkPermission(Manifest.permission.INSTALL_PACKAGES, + rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED) { + continue; } iter.remove(); } @@ -3599,9 +3596,24 @@ public class PackageManagerService extends IPackageManager.Stub final int[] gids = (flags & PackageManager.GET_GIDS) == 0 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); // Compute granted permissions only if package has requested permissions - final Set permissions = ArrayUtils.isEmpty(p.requestedPermissions) + Set permissions = ArrayUtils.isEmpty(p.requestedPermissions) ? Collections.emptySet() : permissionsState.getPermissions(userId); final PackageUserState state = ps.readUserState(userId); + if (state.instantApp) { + permissions = new ArraySet<>(permissions); + permissions.removeIf(permissionName -> { + BasePermission permission = mSettings.mPermissions.get(permissionName); + if (permission == null) { + return true; + } + if (!permission.isInstant()) { + EventLog.writeEvent(0x534e4554, "140256621", UserHandle.getUid(userId, + ps.appId), permissionName); + return true; + } + return false; + }); + } if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && ps.isSystem()) { @@ -8299,10 +8311,9 @@ public class PackageManagerService extends IPackageManager.Stub private void addPackageHoldingPermissions(ArrayList list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId) { int numMatch = 0; - final PermissionsState permissionsState = ps.getPermissionsState(); for (int i=0; i Date: Fri, 7 Aug 2020 11:40:27 -0400 Subject: [PATCH 227/536] Allow user to block individual apps from resuming This adds a setting which stores a list of packages that will be prevented from persisting in QS as resumable media controls, even when resumption is enabled. If the user adds a new package to this list when it already has a resume control, that control will be removed. Bug: 161813143 Test: manual, atest Change-Id: I8c85bc937aeaf366954f2669eba8f6954640fe4c Merged-In: I8c85bc937aeaf366954f2669eba8f6954640fe4c --- core/java/android/provider/Settings.java | 8 +++ .../settings/backup/SecureSettings.java | 1 + .../validators/SecureSettingsValidators.java | 2 + .../systemui/media/MediaDataManager.kt | 24 ++++++++- .../systemui/media/MediaResumeListener.kt | 18 +++++-- .../systemui/tuner/TunerServiceImpl.java | 3 +- .../src/com/android/systemui/util/Utils.java | 20 +++++++ .../systemui/media/MediaDataManagerTest.kt | 52 +++++++++++++++++++ 8 files changed, 123 insertions(+), 5 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index f395569877f5..b5d0b78dcc76 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -8928,6 +8928,14 @@ public final class Settings { */ public static final String MEDIA_CONTROLS_RESUME = "qs_media_resumption"; + /** + * Controls which packages are blocked from persisting in media controls when resumption is + * enabled. The list of packages is set by the user in the Settings app. + * @see Settings.Secure#MEDIA_CONTROLS_RESUME + * @hide + */ + public static final String MEDIA_CONTROLS_RESUME_BLOCKED = "qs_media_resumption_blocked"; + /** * Controls if window magnification is enabled. * @hide diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index d05e6e16bc1a..0977799a6976 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -165,6 +165,7 @@ public class SecureSettings { Settings.Secure.AWARE_TAP_PAUSE_TOUCH_COUNT, Settings.Secure.PEOPLE_STRIP, Settings.Secure.MEDIA_CONTROLS_RESUME, + Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED, Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS }; diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index fa810bdf3a4e..c62fdc6a2780 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -244,6 +244,8 @@ public class SecureSettingsValidators { VALIDATORS.put(Secure.TAP_GESTURE, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.PEOPLE_STRIP, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.MEDIA_CONTROLS_RESUME, BOOLEAN_VALIDATOR); + VALIDATORS.put(Secure.MEDIA_CONTROLS_RESUME_BLOCKED, + COLON_SEPARATED_PACKAGE_LIST_VALIDATOR); VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_MODE, new InclusiveIntegerRangeValidator( Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 64ba5f7cc483..33475aca0bfb 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -55,6 +55,8 @@ import java.io.PrintWriter import java.util.concurrent.Executor import javax.inject.Inject import javax.inject.Singleton +import kotlin.collections.ArrayList +import kotlin.collections.LinkedHashMap // URI fields to try loading album art from private val ART_URIS = arrayOf( @@ -102,6 +104,17 @@ class MediaDataManager( private val listeners: MutableSet = mutableSetOf() private val mediaEntries: LinkedHashMap = LinkedHashMap() + internal var appsBlockedFromResume: MutableSet = Utils.getBlockedMediaApps(context) + set(value) { + // Update list + appsBlockedFromResume.clear() + appsBlockedFromResume.addAll(value) + + // Remove any existing resume players that are now blocked + appsBlockedFromResume.forEach { + removeAllForPackage(it) + } + } @Inject constructor( @@ -523,7 +536,8 @@ class MediaDataManager( fun onNotificationRemoved(key: String) { Assert.isMainThread() val removed = mediaEntries.remove(key) - if (useMediaResumption && removed?.resumeAction != null) { + if (useMediaResumption && removed?.resumeAction != null && + !isBlockedFromResume(removed?.packageName)) { Log.d(TAG, "Not removing $key because resumable") // Move to resume key (aka package name) if that key doesn't already exist. val resumeAction = getResumeMediaAction(removed.resumeAction!!) @@ -560,6 +574,13 @@ class MediaDataManager( } } + private fun isBlockedFromResume(packageName: String?): Boolean { + if (packageName == null) { + return true + } + return appsBlockedFromResume.contains(packageName) + } + fun setMediaResumptionEnabled(isEnabled: Boolean) { if (useMediaResumption == isEnabled) { return @@ -602,6 +623,7 @@ class MediaDataManager( println("listeners: $listeners") println("mediaEntries: $mediaEntries") println("useMediaResumption: $useMediaResumption") + println("appsBlockedFromResume: $appsBlockedFromResume") } } } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt index 4ec746fcb153..c41712c4cf10 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt @@ -52,6 +52,7 @@ class MediaResumeListener @Inject constructor( private var useMediaResumption: Boolean = Utils.useMediaResumption(context) private val resumeComponents: ConcurrentLinkedQueue = ConcurrentLinkedQueue() + private var blockedApps: MutableSet = Utils.getBlockedMediaApps(context) private lateinit var mediaDataManager: MediaDataManager @@ -114,6 +115,14 @@ class MediaResumeListener @Inject constructor( mediaDataManager.setMediaResumptionEnabled(useMediaResumption) } }, Settings.Secure.MEDIA_CONTROLS_RESUME) + + // Listen to changes in which apps are allowed to persist + tunerService.addTunable(object : TunerService.Tunable { + override fun onTuningChanged(key: String?, newValue: String?) { + blockedApps = Utils.getBlockedMediaApps(context) + mediaDataManager.appsBlockedFromResume = blockedApps + } + }, Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED) } fun isResumptionEnabled() = useMediaResumption @@ -144,8 +153,10 @@ class MediaResumeListener @Inject constructor( } resumeComponents.forEach { - val browser = ResumeMediaBrowser(context, mediaBrowserCallback, it) - browser.findRecentMedia() + if (!blockedApps.contains(it.packageName)) { + val browser = ResumeMediaBrowser(context, mediaBrowserCallback, it) + browser.findRecentMedia() + } } } @@ -154,7 +165,8 @@ class MediaResumeListener @Inject constructor( // If this had been started from a resume state, disconnect now that it's live mediaBrowser?.disconnect() // If we don't have a resume action, check if we haven't already - if (data.resumeAction == null && !data.hasCheckedForResume) { + if (data.resumeAction == null && !data.hasCheckedForResume && + !blockedApps.contains(data.packageName)) { // TODO also check for a media button receiver intended for restarting (b/154127084) Log.d(TAG, "Checking for service component for " + data.packageName) val pm = context.packageManager diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java index 9ad2aa257aa0..2512257fdc19 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java @@ -63,7 +63,8 @@ public class TunerServiceImpl extends TunerService { private static final String[] RESET_BLACKLIST = new String[] { QSTileHost.TILES_SETTING, Settings.Secure.DOZE_ALWAYS_ON, - Settings.Secure.MEDIA_CONTROLS_RESUME + Settings.Secure.MEDIA_CONTROLS_RESUME, + Secure.MEDIA_CONTROLS_RESUME_BLOCKED }; private final Observer mObserver = new Observer(); diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java index 9e3fcc401ffa..21f7a85b3277 100644 --- a/packages/SystemUI/src/com/android/systemui/util/Utils.java +++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java @@ -21,12 +21,15 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.provider.Settings; +import android.text.TextUtils; import android.view.View; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.CommandQueue; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.function.Consumer; public class Utils { @@ -141,4 +144,21 @@ public class Utils { Settings.Secure.MEDIA_CONTROLS_RESUME, 1); return useQsMediaPlayer(context) && flag > 0; } + + /** + * Get the set of apps for which the user has manually disabled resumption. + */ + public static Set getBlockedMediaApps(Context context) { + String list = Settings.Secure.getString(context.getContentResolver(), + Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED); + if (TextUtils.isEmpty(list)) { + return new HashSet<>(); + } + String[] names = list.split(":"); + Set apps = new HashSet<>(names.length); + for (String s : names) { + apps.add(s); + } + return apps; + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt index 3789e6ef1f65..568dd6aafc3d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt @@ -196,6 +196,58 @@ class MediaDataManagerTest : SysuiTestCase() { assertThat(listener.removedKey!!).isEqualTo(KEY_2) } + @Test + fun testAppBlockedFromResumption() { + // GIVEN that the manager has a notification with a resume action + val listener = TestListener() + mediaDataManager.addListener(listener) + whenever(controller.metadata).thenReturn(metadataBuilder.build()) + mediaDataManager.onNotificationAdded(KEY, mediaNotification) + assertThat(backgroundExecutor.runAllReady()).isEqualTo(1) + assertThat(foregroundExecutor.runAllReady()).isEqualTo(1) + val data = listener.data!! + assertThat(data.resumption).isFalse() + mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {})) + + // and the manager should block the package from creating resume controls + val blocked = mutableSetOf(PACKAGE_NAME, "com.example.app") + mediaDataManager.appsBlockedFromResume = blocked + + // WHEN the notification is removed + mediaDataManager.onNotificationRemoved(KEY) + + // THEN the media data is removed + assertThat(listener.removedKey!!).isEqualTo(KEY) + } + + @Test + fun testAppUnblockedFromResumption() { + // GIVEN that an app was blocked from resuming + val blocked = mutableSetOf(PACKAGE_NAME, "com.example.app") + mediaDataManager.appsBlockedFromResume = blocked + + // and GIVEN that the manager has a notification from that app with a resume action + val listener = TestListener() + mediaDataManager.addListener(listener) + whenever(controller.metadata).thenReturn(metadataBuilder.build()) + mediaDataManager.onNotificationAdded(KEY, mediaNotification) + assertThat(backgroundExecutor.runAllReady()).isEqualTo(1) + assertThat(foregroundExecutor.runAllReady()).isEqualTo(1) + val data = listener.data!! + assertThat(data.resumption).isFalse() + mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {})) + + // WHEN the app is unblocked + mediaDataManager.appsBlockedFromResume = mutableSetOf("com.example.app") + + // and the notification is removed + mediaDataManager.onNotificationRemoved(KEY) + + // THEN the entry will stay as a resume control + assertThat(listener.key!!).isEqualTo(PACKAGE_NAME) + assertThat(listener.oldKey!!).isEqualTo(KEY) + } + @Test fun testAddResumptionControls() { val listener = TestListener() -- GitLab From 9bb99247d82d58d5ca98f654ee581ca7f43bf2a6 Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Wed, 29 Jul 2020 13:20:24 -0700 Subject: [PATCH 228/536] Reduce WTFs in SyncManager We sometimes get these WTFs due to a race condition. To improve system health, let's remove excessive WTFs. Fix: 158724292 Test: manual code inspection Change-Id: Id808aedcf2f26973773ae3b3e519baf9ac80a235 --- .../com/android/server/content/SyncManager.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 041bedc3c575..ec12a971e445 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -210,6 +210,7 @@ public class SyncManager { private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm"; private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock"; + private static final boolean USE_WTF_FOR_ACCOUNT_ERROR = false; private static final int SYNC_OP_STATE_VALID = 0; // "1" used to include errors 3, 4 and 5 but now it's split up. @@ -3446,7 +3447,7 @@ public class SyncManager { if (isLoggable) { Slog.v(TAG, " Dropping sync operation: account doesn't exist."); } - Slog.wtf(TAG, "SYNC_OP_STATE_INVALID: account doesn't exist."); + logAccountError("SYNC_OP_STATE_INVALID: account doesn't exist."); return SYNC_OP_STATE_INVALID_NO_ACCOUNT; } // Drop this sync request if it isn't syncable. @@ -3456,14 +3457,14 @@ public class SyncManager { Slog.v(TAG, " Dropping sync operation: " + "isSyncable == SYNCABLE_NO_ACCOUNT_ACCESS"); } - Slog.wtf(TAG, "SYNC_OP_STATE_INVALID_NO_ACCOUNT_ACCESS"); + logAccountError("SYNC_OP_STATE_INVALID_NO_ACCOUNT_ACCESS"); return SYNC_OP_STATE_INVALID_NO_ACCOUNT_ACCESS; } if (state == AuthorityInfo.NOT_SYNCABLE) { if (isLoggable) { Slog.v(TAG, " Dropping sync operation: isSyncable == NOT_SYNCABLE"); } - Slog.wtf(TAG, "SYNC_OP_STATE_INVALID: NOT_SYNCABLE"); + logAccountError("SYNC_OP_STATE_INVALID: NOT_SYNCABLE"); return SYNC_OP_STATE_INVALID_NOT_SYNCABLE; } @@ -3482,12 +3483,20 @@ public class SyncManager { if (isLoggable) { Slog.v(TAG, " Dropping sync operation: disallowed by settings/network."); } - Slog.wtf(TAG, "SYNC_OP_STATE_INVALID: disallowed by settings/network"); + logAccountError("SYNC_OP_STATE_INVALID: disallowed by settings/network"); return SYNC_OP_STATE_INVALID_SYNC_DISABLED; } return SYNC_OP_STATE_VALID; } + private void logAccountError(String message) { + if (USE_WTF_FOR_ACCOUNT_ERROR) { + Slog.wtf(TAG, message); + } else { + Slog.e(TAG, message); + } + } + private boolean dispatchSyncOperation(SyncOperation op) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Slog.v(TAG, "dispatchSyncOperation: we are going to sync " + op); -- GitLab From ca5b04dffae3cadad2505b21a4ded519965c826e Mon Sep 17 00:00:00 2001 From: Sarah Chin Date: Wed, 12 Aug 2020 19:51:45 -0700 Subject: [PATCH 229/536] Update NR TAC limit to 3 bytes TAC was updated to 3 bytes, so the limit is now 0xffffff instead of the previous 0xffff. Update to meet 3GPP requirements in 24.501 9.11.3.8. Test: build Bug: 144433329 Change-Id: Ie007c29671da709f23684ff27d30ef1c377aadc6 Merged-In: Ie007c29671da709f23684ff27d30ef1c377aadc6 --- telephony/java/android/telephony/CellIdentityNr.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java index e34bbfcde492..1794ac5b723a 100644 --- a/telephony/java/android/telephony/CellIdentityNr.java +++ b/telephony/java/android/telephony/CellIdentityNr.java @@ -37,7 +37,7 @@ public final class CellIdentityNr extends CellIdentity { private static final String TAG = "CellIdentityNr"; private static final int MAX_PCI = 1007; - private static final int MAX_TAC = 65535; + private static final int MAX_TAC = 16777215; // 0xffffff private static final int MAX_NRARFCN = 3279165; private static final long MAX_NCI = 68719476735L; @@ -53,7 +53,7 @@ public final class CellIdentityNr extends CellIdentity { /** * * @param pci Physical Cell Id in range [0, 1007]. - * @param tac 16-bit Tracking Area Code. + * @param tac 24-bit Tracking Area Code. * @param nrArfcn NR Absolute Radio Frequency Channel Number, in range [0, 3279165]. * @param bands Bands used by the cell. Band number defined in 3GPP TS 38.101-1 and TS 38.101-2. * @param mccStr 3-digit Mobile Country Code in string format. @@ -199,7 +199,7 @@ public final class CellIdentityNr extends CellIdentity { /** * Get the tracking area code. - * @return a 16 bit integer or {@link CellInfo#UNAVAILABLE} if unknown. + * @return a 24 bit integer or {@link CellInfo#UNAVAILABLE} if unknown. */ @IntRange(from = 0, to = 65535) public int getTac() { -- GitLab From cbb1ec8a4ab8bd71a5794c9ad963411519add263 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Mon, 17 Aug 2020 16:03:07 -0400 Subject: [PATCH 230/536] Fix padding in management activities Remove the inherent margin of the controls tiles and exclusively use the item decorator. As we are only assigning margin to the top (to prevent extra margin at the bottom) of each group, we double the top margin. Fixes: 164171322 Test: manual Change-Id: Id337471f3ac81855940da598b4396257ed829311 --- packages/SystemUI/res/values/dimens.xml | 2 +- .../systemui/controls/management/ControlAdapter.kt | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 5984d8d3322e..0d40a9fa26d4 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1371,7 +1371,7 @@ 2dp 32dp - 2dp + @dimen/control_base_item_margin 15 32dp diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt index c683a87d6282..31830b94e8e4 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt @@ -72,8 +72,13 @@ class ControlAdapter( TYPE_CONTROL -> { ControlHolder( layoutInflater.inflate(R.layout.controls_base_item, parent, false).apply { - layoutParams.apply { + (layoutParams as ViewGroup.MarginLayoutParams).apply { width = ViewGroup.LayoutParams.MATCH_PARENT + // Reset margins as they will be set through the decoration + topMargin = 0 + bottomMargin = 0 + leftMargin = 0 + rightMargin = 0 } elevation = this@ControlAdapter.elevation background = parent.context.getDrawable( @@ -386,7 +391,7 @@ class MarginItemDecorator( val type = parent.adapter?.getItemViewType(position) if (type == ControlAdapter.TYPE_CONTROL) { outRect.apply { - top = topMargin + top = topMargin * 2 // Use double margin, as we are not setting bottom left = sideMargins right = sideMargins bottom = 0 -- GitLab From c07be0dfcff85391249778a49a3b6ccfc5b62500 Mon Sep 17 00:00:00 2001 From: "jorgegil@google.com" Date: Fri, 14 Aug 2020 17:33:28 -0700 Subject: [PATCH 231/536] Invalidate resized bounds on aspect ratio changes When the aspect ratio is changed on the pinned window, the previously saved user-resize bounds are used as the restore bounds when unexpanding, which have the previous aspect ratio still. This change invalidates the user resized bounds on aspect ratio changes, which then forces it to be re-set to the new normal bounds. Bug: 163420655 Test: PIP portrait Youtube video, touch to expand menu, click 'next' icon to switch to a landscape video. The landscape video should restore to its unexpanded bounds with the correct aspect ratio. Change-Id: I808993a921e3dc3858fad2c131e6a86bf45955e0 Merged-In: I808993a921e3dc3858fad2c131e6a86bf45955e0 (cherry picked from commit 9b9c7d019b55a00c50964307a037620de225bbce) --- .../com/android/systemui/pip/phone/PipManager.java | 5 ++++- .../systemui/pip/phone/PipResizeGestureHandler.java | 4 ++++ .../android/systemui/pip/phone/PipTouchHandler.java | 13 +++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java index b16b71b3e558..9d9c5a678baf 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -230,7 +230,10 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Override public void onAspectRatioChanged(float aspectRatio) { - mHandler.post(() -> mPipBoundsHandler.onAspectRatioChanged(aspectRatio)); + mHandler.post(() -> { + mPipBoundsHandler.onAspectRatioChanged(aspectRatio); + mTouchHandler.onAspectRatioChanged(); + }); } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java index 40699568aee3..ef73aa7cbbfe 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java @@ -364,6 +364,10 @@ public class PipResizeGestureHandler { mUserResizeBounds.set(bounds); } + void invalidateUserResizeBounds() { + mUserResizeBounds.setEmpty(); + } + Rect getUserResizeBounds() { return mUserResizeBounds; } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index 7c1c2f83a258..0127ff310b78 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -422,8 +422,21 @@ public class PipTouchHandler { } } + /** + * Responds to IPinnedStackListener on resetting aspect ratio for the pinned window. + */ + public void onAspectRatioChanged() { + mPipResizeGestureHandler.invalidateUserResizeBounds(); + } + public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect curBounds, boolean fromImeAdjustment, boolean fromShelfAdjustment, int displayRotation) { + // Set the user resized bounds equal to the new normal bounds in case they were + // invalidated (e.g. by an aspect ratio change). + if (mPipResizeGestureHandler.getUserResizeBounds().isEmpty()) { + mPipResizeGestureHandler.setUserResizeBounds(normalBounds); + } + final int bottomOffset = mIsImeShowing ? mImeHeight : 0; final boolean fromDisplayRotationChanged = (mDisplayRotation != displayRotation); if (fromDisplayRotationChanged) { -- GitLab From 53cf0ba71f679af93ae6d4a5d3634340804440ed Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Tue, 18 Aug 2020 12:35:31 +0000 Subject: [PATCH 232/536] Re-apply "Add bp-based disting of android stubs" The issue with missing resources has been fixed. This reverts commit 9b0a74f0a3ae653954f432bf8892533aa2522015. Bug: 161214753 Change-Id: I863e76f199f7e209dfc86a85320f394c2285e71a Test: diff sdk artifacts before and after --- StubLibraries.bp | 49 ++++++++++++++++++++++++++++++++++++++++++--- services/Android.bp | 4 ++++ 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/StubLibraries.bp b/StubLibraries.bp index a9e6e5af47f1..6b989951d331 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -311,6 +311,15 @@ java_defaults { compile_dex: true, } +java_defaults { + name: "android_stubs_dists_default", + dist: { + targets: ["sdk", "win_sdk"], + tag: ".jar", + dest: "android.jar", + }, +} + java_library_static { name: "android_monolith_stubs_current", srcs: [ ":api-stubs-docs" ], @@ -345,7 +354,21 @@ java_library_static { name: "android_system_monolith_stubs_current", srcs: [ ":system-api-stubs-docs" ], static_libs: [ "private-stub-annotations-jar" ], - defaults: ["android_defaults_stubs_current"], + defaults: [ + "android_defaults_stubs_current", + "android_stubs_dists_default", + ], + dist: { + dir: "apistubs/android/system", + }, + dists: [ + { + // Legacy dist path + targets: ["sdk", "win_sdk"], + tag: ".jar", + dest: "android_system.jar", + }, + ], } java_library_static { @@ -375,14 +398,34 @@ java_library_static { name: "android_test_stubs_current", srcs: [ ":test-api-stubs-docs" ], static_libs: [ "private-stub-annotations-jar" ], - defaults: ["android_defaults_stubs_current"], + defaults: [ + "android_defaults_stubs_current", + "android_stubs_dists_default", + ], + dist: { + dir: "apistubs/android/test", + }, + dists: [ + { + // Legacy dist path + targets: ["sdk", "win_sdk"], + tag: ".jar", + dest: "android_test.jar", + }, + ], } java_library_static { name: "android_module_lib_stubs_current", srcs: [ ":module-lib-api-stubs-docs-non-updatable" ], - defaults: ["android_defaults_stubs_current"], + defaults: [ + "android_defaults_stubs_current", + "android_stubs_dists_default", + ], libs: ["sdk_system_29_android"], + dist: { + dir: "apistubs/android/module-lib", + }, } java_library_static { diff --git a/services/Android.bp b/services/Android.bp index 40b925de95d6..f0144ac1c695 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -154,10 +154,14 @@ droidstubs { java_library { name: "android_system_server_stubs_current", + defaults: ["android_stubs_dists_default"], srcs: [":services-stubs.sources"], installable: false, static_libs: ["android_module_lib_stubs_current"], sdk_version: "none", system_modules: "none", java_version: "1.8", + dist: { + dir: "apistubs/android/system-server", + }, } -- GitLab From 533682ebb39456df26097753d1f5172bff0e3d5d Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Fri, 7 Aug 2020 20:13:55 +0800 Subject: [PATCH 233/536] Refine system bar position restoring The previous logic restores the system bar as long as its insets source is visible. There can be a timing issue that if the user swipes to show transient bars while an immersive app just becomes the control target but the hide-bar info haven't sent to WM yet, WM will re-show the bar incorrectly. This CL uses the requested visibility and the behavior to decide if we should restore the postion and the visibility. This CL also refines and caches the arguments of showTransient. In this way, we don't have to create the array every time while invoking that method. Fix: 161247175 Test: atest InsetsPolicyTest Merged-In: Idef314dfe6625399b88b3dacb4c74c7071453497 Change-Id: Idef314dfe6625399b88b3dacb4c74c7071453497 --- core/java/android/view/InsetsState.java | 2 ++ .../com/android/server/wm/DisplayPolicy.java | 28 ++++++++++++------- .../server/wm/InsetsControlTarget.java | 8 ++++++ .../com/android/server/wm/InsetsPolicy.java | 10 ++----- .../com/android/server/wm/WindowState.java | 3 +- .../android/server/wm/InsetsPolicyTest.java | 13 +++------ 6 files changed, 37 insertions(+), 27 deletions(-) diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 6b0b509932a8..593b37af26ad 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -60,6 +60,8 @@ import java.util.StringJoiner; */ public class InsetsState implements Parcelable { + public static final InsetsState EMPTY = new InsetsState(); + /** * Internal representation of inset source types. This is different from the public API in * {@link WindowInsets.Type} as one type from the public API might indicate multiple windows diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 6a90f2994238..5c5ec358d004 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -246,6 +246,9 @@ public class DisplayPolicy { | View.STATUS_BAR_TRANSPARENT | View.NAVIGATION_BAR_TRANSPARENT; + private static final int[] SHOW_TYPES_FOR_SWIPE = {ITYPE_NAVIGATION_BAR, ITYPE_STATUS_BAR}; + private static final int[] SHOW_TYPES_FOR_PANIC = {ITYPE_NAVIGATION_BAR}; + private final WindowManagerService mService; private final Context mContext; private final Context mUiContext; @@ -3330,8 +3333,15 @@ public class DisplayPolicy { return; } + final InsetsState requestedState = controlTarget.getRequestedInsetsState(); + final @InsetsType int restorePositionTypes = + (requestedState.getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR) + ? Type.navigationBars() : 0) + | (requestedState.getSourceOrDefaultVisibility(ITYPE_STATUS_BAR) + ? Type.statusBars() : 0); + if (swipeTarget == mNavigationBar - && !getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)) { + && (restorePositionTypes & Type.navigationBars()) != 0) { // Don't show status bar when swiping on already visible navigation bar. // But restore the position of navigation bar if it has been moved by the control // target. @@ -3339,14 +3349,13 @@ public class DisplayPolicy { return; } - int insetsTypesToShow = Type.systemBars(); - if (controlTarget.canShowTransient()) { - insetsTypesToShow &= ~mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap( - new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); - } - if (insetsTypesToShow != 0) { - controlTarget.showInsets(insetsTypesToShow, false); + // Show transient bars if they are hidden; restore position if they are visible. + mDisplayContent.getInsetsPolicy().showTransient(SHOW_TYPES_FOR_SWIPE); + controlTarget.showInsets(restorePositionTypes, false); + } else { + // Restore visibilities and positions of system bars. + controlTarget.showInsets(Type.statusBars() | Type.navigationBars(), false); } } else { boolean sb = mStatusBarController.checkShowTransientBarLw(); @@ -3923,8 +3932,7 @@ public class DisplayPolicy { mPendingPanicGestureUptime = SystemClock.uptimeMillis(); if (!isNavBarEmpty(mLastSystemUiFlags)) { mNavigationBarController.showTransient(); - mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap( - new int[] {ITYPE_NAVIGATION_BAR})); + mDisplayContent.getInsetsPolicy().showTransient(SHOW_TYPES_FOR_PANIC); } } } diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java index 3ffc26a7a8ad..5e7ed3f80e43 100644 --- a/services/core/java/com/android/server/wm/InsetsControlTarget.java +++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java @@ -17,6 +17,7 @@ package com.android.server.wm; import android.inputmethodservice.InputMethodService; +import android.view.InsetsState; import android.view.WindowInsets.Type.InsetsType; /** @@ -37,6 +38,13 @@ interface InsetsControlTarget { return null; } + /** + * @return The requested {@link InsetsState} of this target. + */ + default InsetsState getRequestedInsetsState() { + return InsetsState.EMPTY; + } + /** * Instructs the control target to show inset sources. * diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 82e7555c62ac..fd67db1d5cc9 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -42,7 +42,6 @@ import android.view.InsetsState.InternalInsetsType; import android.view.SurfaceControl; import android.view.SyncRtSurfaceTransactionApplier; import android.view.ViewRootImpl; -import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsAnimation; import android.view.WindowInsetsAnimation.Bounds; import android.view.WindowInsetsAnimationControlListener; @@ -154,15 +153,13 @@ class InsetsPolicy { return provider != null && provider.hasWindow() && !provider.getSource().isVisible(); } - @InsetsType int showTransient(IntArray types) { - @InsetsType int showingTransientTypes = 0; + void showTransient(@InternalInsetsType int[] types) { boolean changed = false; - for (int i = types.size() - 1; i >= 0; i--) { - final int type = types.get(i); + for (int i = types.length - 1; i >= 0; i--) { + final @InternalInsetsType int type = types[i]; if (!isHidden(type)) { continue; } - showingTransientTypes |= InsetsState.toPublicType(type); if (mShowingTransientTypes.indexOf(type) != -1) { continue; } @@ -190,7 +187,6 @@ class InsetsPolicy { } }); } - return showingTransientTypes; } void hideTransient() { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 11db705f4e04..6a2c54e0b292 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -725,7 +725,8 @@ class WindowState extends WindowContainer implements WindowManagerP * @return The insets state as requested by the client, i.e. the dispatched insets state * for which the visibilities are overridden with what the client requested. */ - InsetsState getRequestedInsetsState() { + @Override + public InsetsState getRequestedInsetsState() { return mRequestedInsetsState; } diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java index 87bc7f1bf781..90af8a1b3199 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -43,7 +43,6 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.spy; import android.platform.test.annotations.Presubmit; -import android.util.IntArray; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.test.InsetsModeSession; @@ -241,8 +240,7 @@ public class InsetsPolicyTest extends WindowTestsBase { }).when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(mAppWindow); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); waitUntilWindowAnimatorIdle(); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -269,8 +267,7 @@ public class InsetsPolicyTest extends WindowTestsBase { final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(mAppWindow); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); waitUntilWindowAnimatorIdle(); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -298,8 +295,7 @@ public class InsetsPolicyTest extends WindowTestsBase { final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(mAppWindow); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); waitUntilWindowAnimatorIdle(); InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -337,8 +333,7 @@ public class InsetsPolicyTest extends WindowTestsBase { final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(app); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(app); policy.updateBarControlTarget(app2); -- GitLab From cb4dbb8b80a52997e179e6f26943aecdd971b3ed Mon Sep 17 00:00:00 2001 From: Catherine Shi Date: Mon, 22 Jun 2020 12:12:03 -0700 Subject: [PATCH 234/536] system server watchdog caused by deadlock There is deadlock among ActivityManagerService, ActivityTaskManagerService and ConnectionServiceWrapper. Move stopLockTaskModeInternal out of mGlobalLock scope. This will remove the deadlock Bug: 159213837 Bug: 162950591 Test: presubmit Change-Id: I6aee6f9837bac22e480f42124bfcdba991e0fa1a (cherry picked from commit 3a17ba2f2560405ee8415d2d652eb3dd3c7449fc) --- .../server/wm/ActivityTaskManagerService.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 5992ff74dfa2..52d4b6fc78df 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -2997,13 +2997,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void stopLockTaskModeByToken(IBinder token) { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r == null) { - return; - } - stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */); - } + stopLockTaskModeInternal(token, false /* isSystemCaller */); } /** @@ -3045,11 +3039,19 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - private void stopLockTaskModeInternal(@Nullable Task task, boolean isSystemCaller) { + private void stopLockTaskModeInternal(@Nullable IBinder token, boolean isSystemCaller) { final int callingUid = Binder.getCallingUid(); long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { + Task task = null; + if (token != null) { + final ActivityRecord r = ActivityRecord.forTokenLocked(token); + if (r == null) { + return; + } + task = r.getTask(); + } getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid); } // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock -- GitLab From e49aa726f0687afec8ab6a040bff7016557ba3da Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Fri, 14 Aug 2020 09:43:06 -0700 Subject: [PATCH 235/536] Allow package verifier to hide specific fgs notifications. The package verifier performs some system critical work that the user doesn't need to be explicitly aware of. This adds a mechanism for the verifier to indicate which foreground service notifications should be hidden, if possible. Bug: 164440539 Test: use test app to confirm requested fgs notifications are hidden Change-Id: Ib3eb0b71cc676c145557ade9def98a363e5abebb --- core/java/android/app/ContextImpl.java | 13 +++++++ core/java/android/app/IActivityManager.aidl | 3 +- .../com/android/server/am/ActiveServices.java | 11 +++--- .../server/am/ActivityManagerService.java | 36 ++++++++++++++++--- .../am/ActivityManagerShellCommand.java | 2 +- .../com/android/server/am/ServiceRecord.java | 6 +++- 6 files changed, 58 insertions(+), 13 deletions(-) diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 505b498e3cf6..d0fd92294979 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -186,6 +186,16 @@ class ContextImpl extends Context { private static final String XATTR_INODE_CACHE = "user.inode_cache"; private static final String XATTR_INODE_CODE_CACHE = "user.inode_code_cache"; + /** + * Special intent extra that critical system apps can use to hide the notification for a + * foreground service. This extra should be placed in the intent passed into {@link + * #startForegroundService(Intent)}. + * + * @hide + */ + private static final String EXTRA_HIDDEN_FOREGROUND_SERVICE = + "android.intent.extra.HIDDEN_FOREGROUND_SERVICE"; + /** * Map from package name, to preference name, to cached preferences. */ @@ -1697,9 +1707,12 @@ class ContextImpl extends Context { try { validateServiceIntent(service); service.prepareToLeaveProcess(this); + final boolean hideForegroundNotification = requireForeground + && service.getBooleanExtra(EXTRA_HIDDEN_FOREGROUND_SERVICE, false); ComponentName cn = ActivityManager.getService().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), requireForeground, + hideForegroundNotification, getOpPackageName(), getAttributionTag(), user.getIdentifier()); if (cn != null) { if (cn.getPackageName().equals("!")) { diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 945957738f8e..2abe9cf9fce5 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -155,7 +155,8 @@ interface IActivityManager { boolean refContentProvider(in IBinder connection, int stableDelta, int unstableDelta); PendingIntent getRunningServiceControlPanel(in ComponentName service); ComponentName startService(in IApplicationThread caller, in Intent service, - in String resolvedType, boolean requireForeground, in String callingPackage, + in String resolvedType, boolean requireForeground, + boolean hideForegroundNotification, in String callingPackage, in String callingFeatureId, int userId); @UnsupportedAppUsage int stopService(in IApplicationThread caller, in Intent service, diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 3f867f656c24..7d88a8a4ec01 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -453,16 +453,16 @@ public final class ActiveServices { } ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, - int callingPid, int callingUid, boolean fgRequired, String callingPackage, - @Nullable String callingFeatureId, final int userId) + int callingPid, int callingUid, boolean fgRequired, boolean hideFgNotification, + String callingPackage, @Nullable String callingFeatureId, final int userId) throws TransactionTooLargeException { return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired, - callingPackage, callingFeatureId, userId, false); + hideFgNotification, callingPackage, callingFeatureId, userId, false); } ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, - int callingPid, int callingUid, boolean fgRequired, String callingPackage, - @Nullable String callingFeatureId, final int userId, + int callingPid, int callingUid, boolean fgRequired, boolean hideFgNotification, + String callingPackage, @Nullable String callingFeatureId, final int userId, boolean allowBackgroundActivityStarts) throws TransactionTooLargeException { if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service + " type=" + resolvedType + " args=" + service.getExtras()); @@ -609,6 +609,7 @@ public final class ActiveServices { r.startRequested = true; r.delayedStop = false; r.fgRequired = fgRequired; + r.hideFgNotification = hideFgNotification; r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), service, neededGrants, callingUid)); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 82abb988cb2c..44e3bbf91565 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1438,6 +1438,10 @@ public class ActivityManagerService extends IActivityManager.Stub final Injector mInjector; + /** The package verifier app. */ + private String mPackageVerifier; + private int mPackageVerifierUid = UserHandle.USER_NULL; + static final class ProcessChangeItem { static final int CHANGE_ACTIVITIES = 1<<0; static final int CHANGE_FOREGROUND_SERVICES = 1<<1; @@ -2362,6 +2366,18 @@ public class ActivityManagerService extends IActivityManager.Stub if (phase == PHASE_SYSTEM_SERVICES_READY) { mService.mBatteryStatsService.systemServicesReady(); mService.mServices.systemServicesReady(); + mService.mPackageVerifier = ArrayUtils.firstOrNull( + LocalServices.getService(PackageManagerInternal.class).getKnownPackageNames( + PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM)); + if (mService.mPackageVerifier != null) { + try { + mService.mPackageVerifierUid = + getContext().getPackageManager().getPackageUid( + mService.mPackageVerifier, UserHandle.USER_SYSTEM); + } catch (NameNotFoundException e) { + Slog.wtf(TAG, "Package manager couldn't get package verifier uid", e); + } + } } else if (phase == PHASE_ACTIVITY_MANAGER_READY) { mService.startBroadcastObservers(); } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { @@ -15007,8 +15023,8 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public ComponentName startService(IApplicationThread caller, Intent service, - String resolvedType, boolean requireForeground, String callingPackage, - String callingFeatureId, int userId) + String resolvedType, boolean requireForeground, boolean hideForegroundNotification, + String callingPackage, String callingFeatureId, int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("startService"); // Refuse possible leaked file descriptors @@ -15020,17 +15036,27 @@ public class ActivityManagerService extends IActivityManager.Stub throw new IllegalArgumentException("callingPackage cannot be null"); } + final int callingUid = Binder.getCallingUid(); + if (requireForeground && hideForegroundNotification) { + if (!UserHandle.isSameApp(callingUid, mPackageVerifierUid) + || !callingPackage.equals(mPackageVerifier)) { + throw new IllegalArgumentException( + "Only the package verifier can hide its foreground service notification"); + } + Slog.i(TAG, "Foreground service notification hiding requested by " + callingPackage); + } + if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground); synchronized(this) { final int callingPid = Binder.getCallingPid(); - final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res; try { res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, - requireForeground, callingPackage, callingFeatureId, userId); + requireForeground, hideForegroundNotification, + callingPackage, callingFeatureId, userId); } finally { Binder.restoreCallingIdentity(origId); } @@ -19470,7 +19496,7 @@ public class ActivityManagerService extends IActivityManager.Stub ComponentName res; try { res = mServices.startServiceLocked(null, service, - resolvedType, -1, uid, fgRequired, callingPackage, + resolvedType, -1, uid, fgRequired, false, callingPackage, callingFeatureId, userId, allowBackgroundActivityStarts); } finally { Binder.restoreCallingIdentity(origId); diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 149e3baa90e7..a512cca7bac4 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -654,7 +654,7 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println("Starting service: " + intent); pw.flush(); ComponentName cn = mInterface.startService(null, intent, intent.getType(), - asForeground, SHELL_PACKAGE_NAME, null, mUserId); + asForeground, false, SHELL_PACKAGE_NAME, null, mUserId); if (cn == null) { err.println("Error: Not found; no service started."); return -1; diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 828ac71eccfe..19d5a3125f3a 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -104,6 +104,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT? boolean delayed; // are we waiting to start this service in the background? boolean fgRequired; // is the service required to go foreground after starting? + boolean hideFgNotification; // Hide the fg service notification boolean fgWaiting; // is a timeout for going foreground already scheduled? boolean isForeground; // is service currently in foreground mode? int foregroundId; // Notification ID of last foreground req. @@ -823,6 +824,9 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } public void postNotification() { + if (hideFgNotification) { + return; + } final int appUid = appInfo.uid; final int appPid = app.pid; if (foregroundId != 0 && foregroundNoti != null) { @@ -915,7 +919,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } if (localForegroundNoti.getSmallIcon() == null) { // Notifications whose icon is 0 are defined to not show - // a notification, silently ignoring it. We don't want to + // a notification. We don't want to // just ignore it, we want to prevent the service from // being foreground. throw new RuntimeException("invalid service notification: " -- GitLab From bde40af6cafc29534d59f31c579145f2c14e34a9 Mon Sep 17 00:00:00 2001 From: jasonwshsu Date: Fri, 14 Aug 2020 00:59:48 +0800 Subject: [PATCH 236/536] Update language to comply with Android's inclusive language guidance 1. Rename isClientInWhitelist to isClientInAllowlist See https://source.android.com/setup/contribute/respectful-code for reference Bug: 162536543 Test: Build & run Change-Id: I915e09e4e64d5c268630cec2d0ef05ea0592fd6f Merged-In: Ibbd97bf31915d59b5110cbcc8f2126f7a7221060 --- .../AccessibilityManagerService.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 499a2711d8e6..fcf270b4ef35 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -1464,19 +1464,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub int serviceCount = userState.mBoundServices.size(); for (int i = 0; i < serviceCount; i++) { AccessibilityServiceConnection service = userState.mBoundServices.get(i); - relevantEventTypes |= isClientInPackageWhitelist(service.getServiceInfo(), client) + relevantEventTypes |= isClientInPackageAllowlist(service.getServiceInfo(), client) ? service.getRelevantEventTypes() : 0; } - relevantEventTypes |= isClientInPackageWhitelist( + relevantEventTypes |= isClientInPackageAllowlist( mUiAutomationManager.getServiceInfo(), client) ? mUiAutomationManager.getRelevantEventTypes() : 0; return relevantEventTypes; } - private static boolean isClientInPackageWhitelist( + private static boolean isClientInPackageAllowlist( @Nullable AccessibilityServiceInfo serviceInfo, Client client) { if (serviceInfo == null) return false; @@ -1495,7 +1495,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub Slog.d(LOG_TAG, "Dropping events: " + Arrays.toString(clientPackages) + " -> " + serviceInfo.getComponentName().flattenToShortString() - + " due to not being in package whitelist " + + " due to not being in package allowlist " + Arrays.toString(serviceInfo.packageNames)); } } @@ -1890,9 +1890,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } private void updateLegacyCapabilitiesLocked(AccessibilityUserState userState) { - // Up to JB-MR1 we had a white list with services that can enable touch + // Up to JB-MR1 we had a allowlist with services that can enable touch // exploration. When a service is first started we show a dialog to the - // use to get a permission to white list the service. + // use to get a permission to allowlist the service. final int installedServiceCount = userState.mInstalledServices.size(); for (int i = 0; i < installedServiceCount; i++) { AccessibilityServiceInfo serviceInfo = userState.mInstalledServices.get(i); @@ -2155,9 +2155,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } if (service.getServiceInfo().getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1) { - // Up to JB-MR1 we had a white list with services that can enable touch + // Up to JB-MR1 we had a allowlist with services that can enable touch // exploration. When a service is first started we show a dialog to the - // use to get a permission to white list the service. + // use to get a permission to allowlist the service. if (userState.mTouchExplorationGrantedServices.contains(service.mComponentName)) { return true; } else if (mEnableTouchExplorationDialog == null -- GitLab From 31fc73a70719ed9a07a9a865c71b602e2fd0c53e Mon Sep 17 00:00:00 2001 From: Jeff Chang Date: Fri, 7 Aug 2020 16:08:15 +0800 Subject: [PATCH 237/536] [RESTRICT AUTOMERGE] Update the visibility of activities on sleeping display Activity with showWhenLocked flag is visible when screen is off and leads to activity restart called. This CL update the visibility condition for showWhenLocked and dismisskeyguard activities and refer the keyguard visibility to ensure the function works as expected. Bug: 161036653 Test: atest ActivityRecordTests atest CtsWindowManagerDeviceTestCases:KeyguardTests atest CtsWindowManagerDeviceTestCases:KeyguardLockedTests Change-Id: I9d56e40de964e9d11193fec7008f8d880028ac50 (cherry picked from commit 73d6c7926d2cdc39de617f7213fc85f303501f37) --- .../com/android/server/wm/ActivityRecord.java | 15 ++++------ .../server/wm/ActivityRecordTests.java | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 3e9377ed0664..41e48b8ec9db 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -4578,15 +4578,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } - // Check if the activity is on a sleeping display, and if it can turn it ON. - if (getDisplay().isSleeping()) { - final boolean canTurnScreenOn = !mSetToSleep || canTurnScreenOn() - || canShowWhenLocked() || containsDismissKeyguardWindow(); - if (!canTurnScreenOn) { - return false; - } - } - // Now check whether it's really visible depending on Keyguard state, and update // {@link ActivityStack} internal states. // Inform the method if this activity is the top activity of this stack, but exclude the @@ -4597,6 +4588,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this, visibleIgnoringKeyguard, isTop && isTopNotPinnedStack); + // Check if the activity is on a sleeping display, and if it can turn it ON. + // TODO(b/163993448): Do not make activity visible before display awake. + if (visibleIgnoringDisplayStatus && getDisplay().isSleeping()) { + return !mSetToSleep || canTurnScreenOn(); + } + return visibleIgnoringDisplayStatus; } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index c7b45efb2de1..6ab0697206e3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -1099,6 +1099,34 @@ public class ActivityRecordTests extends ActivityTestsBase { verify(topActivity).destroyIfPossible(anyString()); } + /** + * Verify the visibility of a show-when-locked and dismiss keyguard activity on sleeping + * display. + */ + @Test + public void testDisplaySleeping_activityInvisible() { + final KeyguardController keyguardController = + mActivity.mStackSupervisor.getKeyguardController(); + doReturn(true).when(keyguardController).isKeyguardLocked(); + final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build(); + topActivity.mVisibleRequested = true; + topActivity.nowVisible = true; + topActivity.setState(RESUMED, "test" /*reason*/); + doReturn(true).when(topActivity).containsDismissKeyguardWindow(); + doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible( + any() /* starting */, anyInt() /* configChanges */, + anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */); + topActivity.setShowWhenLocked(true); + + // Verify the top activity is occluded keyguard. + assertEquals(topActivity, mStack.topRunningActivity()); + assertTrue(mStack.topActivityOccludesKeyguard()); + + final DisplayContent display = mActivity.mDisplayContent; + doReturn(true).when(display).isSleeping(); + assertFalse(topActivity.shouldBeVisible()); + } + /** * Verify that complete finish request for a show-when-locked activity must ensure the * keyguard occluded state being updated. -- GitLab From 27d5a1f5a1108d69a665b0f7ad6772592c35bba6 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Mon, 10 Aug 2020 13:17:22 +0800 Subject: [PATCH 238/536] Avoid adjusting top focused root task while clear task Top focused root task was updated while clear task for reuse, which isn't necessary. This was happening after 046523c merged. Also avoid resuming the top activity in next focused root task to prevent additional top-resumed-activity state changes. Bug: 160613519 Bug: 163003067 Test: asit/perf/junit/jank_systemui_test Change-Id: I8ddbfc3b0a62ddb29833d324e42812ed0dc096db (cherry picked from commit 2caec7ba30b63785d5d5ee5d1341bd11f373aa12) --- .../com/android/server/wm/ActivityRecord.java | 4 +++- .../android/server/wm/ActivityStarter.java | 2 -- .../core/java/com/android/server/wm/Task.java | 19 +++++++++++++++---- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index e9ceee3debee..f74684070d0b 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2543,7 +2543,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final ActivityStack stack = getRootTask(); final boolean mayAdjustTop = (isState(RESUMED) || stack.mResumedActivity == null) - && stack.isFocusedStackOnDisplay(); + && stack.isFocusedStackOnDisplay() + // Do not adjust focus task because the task will be reused to launch new activity. + && !task.isClearingToReuseTask(); final boolean shouldAdjustGlobalFocus = mayAdjustTop // It must be checked before {@link #makeFinishingLocked} is called, because a stack // is not visible if it only contains finishing activities. diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index b3786212ea72..b869eb56f536 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -2009,8 +2009,6 @@ class ActivityStarter { // of history or if it is finished immediately), thus disassociating the task. Also note // that mReuseTask is reset as a result of {@link Task#performClearTaskLocked} // launching another activity. - // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are - // already launching one. targetTask.performClearTaskLocked(); targetTask.setIntent(mStartActivity); mAddingToTask = true; diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 6785127d5953..4e923dac5c17 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -1528,14 +1528,25 @@ class Task extends WindowContainer { */ void performClearTaskLocked() { mReuseTask = true; - performClearTask("clear-task-all"); - mReuseTask = false; + mStackSupervisor.beginDeferResume(); + try { + performClearTask("clear-task-all"); + } finally { + mStackSupervisor.endDeferResume(); + mReuseTask = false; + } } ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) { mReuseTask = true; - final ActivityRecord result = performClearTaskLocked(newR, launchFlags); - mReuseTask = false; + mStackSupervisor.beginDeferResume(); + final ActivityRecord result; + try { + result = performClearTaskLocked(newR, launchFlags); + } finally { + mStackSupervisor.endDeferResume(); + mReuseTask = false; + } return result; } -- GitLab From b0ce703e9a1a87cc6df7058f2bfdd4eb72d58aba Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Tue, 18 Aug 2020 17:11:18 -0700 Subject: [PATCH 239/536] Rename driver build time manifest flag. The driver apk is an implication of updatable, hence the word updatable is redundant. Bug: b/164449016 Test: build Change-Id: Ia9477ed9277e20540f79e94e7229dc3760025eb8 --- core/java/android/os/GraphicsEnvironment.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index 1eb3fc11df7b..df1f1b21eba3 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -68,7 +68,7 @@ public class GraphicsEnvironment { private static final String PROPERTY_GFX_DRIVER_PRERELEASE = "ro.gfx.driver.1"; private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time"; private static final String METADATA_DRIVER_BUILD_TIME = - "com.android.graphics.updatabledriver.build_time"; + "com.android.graphics.driver.build_time"; private static final String METADATA_DEVELOPER_DRIVER_ENABLE = "com.android.graphics.developerdriver.enable"; private static final String METADATA_INJECT_LAYERS_ENABLE = @@ -878,9 +878,10 @@ public class GraphicsEnvironment { throw new NullPointerException("apk's meta-data cannot be null"); } - final String driverBuildTime = driverAppInfo.metaData.getString(METADATA_DRIVER_BUILD_TIME); - if (driverBuildTime == null || driverBuildTime.isEmpty()) { - Log.v(TAG, "com.android.graphics.updatabledriver.build_time is not set"); + String driverBuildTime = driverAppInfo.metaData.getString(METADATA_DRIVER_BUILD_TIME); + if (driverBuildTime == null || driverBuildTime.length() <= 1) { + Log.v(TAG, "com.android.graphics.driver.build_time is not set"); + driverBuildTime = "L0"; } // driver_build_time in the meta-data is in "L" format. e.g. L123456. // Long.parseLong will throw if the meta-data "driver_build_time" is not set properly. -- GitLab From b1dca9a89bea83ada282504964ce34387d6851d7 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Tue, 4 Aug 2020 16:48:49 +0800 Subject: [PATCH 240/536] Non-priv apps are not allowed to use always/never lock task mode It worked oppositely since 2bf2832. Bug: 162808850 Bug: 158833495 Test: atest ActivityRecordTests Change-Id: Ic5f1b1531816a90ff341597e6d012a6c62c04480 Merged-In: Ic5f1b1531816a90ff341597e6d012a6c62c04480 (cherry picked from commit 3d494aad99f96dd10e98ac91121dc458c37e29fa) --- .../com/android/server/wm/ActivityRecord.java | 3 +- .../server/wm/ActivityRecordTests.java | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index e9ceee3debee..dae9c9c88add 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1671,7 +1671,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A static int getLockTaskLaunchMode(ActivityInfo aInfo, @Nullable ActivityOptions options) { int lockTaskLaunchMode = aInfo.lockTaskLaunchMode; - if (aInfo.applicationInfo.isPrivilegedApp() + // Non-priv apps are not allowed to use always or never, fall back to default + if (!aInfo.applicationInfo.isPrivilegedApp() && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS || lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) { lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 6ab0697206e3..8ae21efe8223 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -20,6 +20,10 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; +import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS; +import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT; +import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; +import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; @@ -79,6 +83,7 @@ import android.app.servertransaction.PauseActivityItem; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; @@ -1685,6 +1690,32 @@ public class ActivityRecordTests extends ActivityTestsBase { .diff(wpc.getRequestedOverrideConfiguration())); } + @Test + public void testGetLockTaskLaunchMode() { + final ActivityOptions options = ActivityOptions.makeBasic().setLockTaskEnabled(true); + mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT; + assertEquals(LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED, + ActivityRecord.getLockTaskLaunchMode(mActivity.info, options)); + + mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_ALWAYS; + assertEquals(LOCK_TASK_LAUNCH_MODE_DEFAULT, + ActivityRecord.getLockTaskLaunchMode(mActivity.info, null /*options*/)); + + mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_NEVER; + assertEquals(LOCK_TASK_LAUNCH_MODE_DEFAULT, + ActivityRecord.getLockTaskLaunchMode(mActivity.info, null /*options*/)); + + mActivity.info.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; + mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_ALWAYS; + assertEquals(LOCK_TASK_LAUNCH_MODE_ALWAYS, + ActivityRecord.getLockTaskLaunchMode(mActivity.info, null /*options*/)); + + mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_NEVER; + assertEquals(LOCK_TASK_LAUNCH_MODE_NEVER, + ActivityRecord.getLockTaskLaunchMode(mActivity.info, null /*options*/)); + + } + /** * Creates an activity on display. For non-default display request it will also create a new * display with custom DisplayInfo. -- GitLab From 7dc8bf4acfe7cfe7f7f9257079de5847fb545d4d Mon Sep 17 00:00:00 2001 From: Bowgo Tsai Date: Thu, 9 Apr 2020 13:51:54 +0800 Subject: [PATCH 241/536] Add systrace tag for system property Introduce a new systrace tag, TRACE_TAG_SYSPROP, for use with system property. Bug: 147275573 Test: build Change-Id: Id78992d238a73257bb9b80bfaa6bbfeb16f477d8 Merged-In: Id78992d238a73257bb9b80bfaa6bbfeb16f477d8 (cherry picked from commit 98d0d4ba03c901be7262ad00d86fbc2f60ab1409) --- core/java/android/os/Trace.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java index 50cc764dd536..58c8efa3a972 100644 --- a/core/java/android/os/Trace.java +++ b/core/java/android/os/Trace.java @@ -102,6 +102,8 @@ public final class Trace { /** @hide */ public static final long TRACE_TAG_RRO = 1L << 26; /** @hide */ + public static final long TRACE_TAG_SYSPROP = 1L << 27; + /** @hide */ public static final long TRACE_TAG_APEX_MANAGER = 1L << 18; private static final long TRACE_TAG_NOT_READY = 1L << 63; -- GitLab From f8175d1a5b276386037006a77d1df132774e9ed8 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Mon, 27 Jul 2020 23:46:30 +0800 Subject: [PATCH 242/536] Dispatch insets to client if mState is changed Previous logic in onStateChanged notifies insetsChanged based on the change of mLastDispatchedState, which can make us dispatch redundant insets changes to the app. In this CL, we only notifies insetsChanged if mState is really changed in onStateChanged -- we use the final mState (after updateState and applyLocalVisibilityOverride) to compare with the one before changing. Fix: 161924448 Test: atest InsetsControllerTest WindowInsetsControllerTests Test: Swipe up to home while IME open and see if there is any jank Merged-In: Ia536cdf76805caa56ca1b6eaf2b3db83b6ecd94e Change-Id: Ia536cdf76805caa56ca1b6eaf2b3db83b6ecd94e --- core/java/android/view/InsetsController.java | 16 +-- .../android/view/InsetsControllerTest.java | 101 +++++++++++++++++- 2 files changed, 109 insertions(+), 8 deletions(-) diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index c383bc7a4d70..e9b7695e7b71 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -618,16 +618,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation return false; } if (DEBUG) Log.d(TAG, "onStateChanged: " + state); - updateState(state); - - boolean localStateChanged = !mState.equals(mLastDispatchedState, - true /* excludingCaptionInsets */, true /* excludeInvisibleIme */); mLastDispatchedState.set(state, true /* copySources */); + final InsetsState lastState = new InsetsState(mState, true /* copySources */); + updateState(state); applyLocalVisibilityOverride(); - if (localStateChanged) { - if (DEBUG) Log.d(TAG, "onStateChanged, notifyInsetsChanged, send state to WM: " + mState); + + if (!mState.equals(lastState, true /* excludingCaptionInsets */, + true /* excludeInvisibleIme */)) { + if (DEBUG) Log.d(TAG, "onStateChanged, notifyInsetsChanged"); mHost.notifyInsetsChanged(); + } + if (!mState.equals(mLastDispatchedState, true /* excludingCaptionInsets */, + true /* excludeInvisibleIme */)) { + if (DEBUG) Log.d(TAG, "onStateChanged, send state to WM: " + mState); updateRequestedState(); } return true; diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index 801cd4ddb94e..af02b7bdbd90 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -27,6 +27,7 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; import static android.view.WindowInsets.Type.ime; +import static android.view.WindowInsets.Type.navigationBars; import static android.view.WindowInsets.Type.statusBars; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; @@ -40,8 +41,11 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.notNull; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.content.Context; @@ -124,7 +128,7 @@ public class InsetsControllerTest { } mTestClock = new OffsettableClock(); mTestHandler = new TestHandler(null, mTestClock); - mTestHost = new TestHost(mViewRoot); + mTestHost = spy(new TestHost(mViewRoot)); mController = new InsetsController(mTestHost, (controller, type) -> { if (type == ITYPE_IME) { return new InsetsSourceConsumer(type, controller.getState(), @@ -745,6 +749,99 @@ public class InsetsControllerTest { }); } + @Test + public void testInsetsChangedCount_controlSystemBars() { + InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { + prepareControls(); + + // Hiding visible system bars should only causes insets change once for each bar. + clearInvocations(mTestHost); + mController.hide(statusBars() | navigationBars()); + verify(mTestHost, times(2)).notifyInsetsChanged(); + + // Sending the same insets state should not cause insets change. + // This simulates the callback from server after hiding system bars. + clearInvocations(mTestHost); + mController.onStateChanged(mController.getState()); + verify(mTestHost, never()).notifyInsetsChanged(); + + // Showing invisible system bars should only causes insets change once for each bar. + clearInvocations(mTestHost); + mController.show(statusBars() | navigationBars()); + verify(mTestHost, times(2)).notifyInsetsChanged(); + + // Sending the same insets state should not cause insets change. + // This simulates the callback from server after showing system bars. + clearInvocations(mTestHost); + mController.onStateChanged(mController.getState()); + verify(mTestHost, never()).notifyInsetsChanged(); + }); + } + + @Test + public void testInsetsChangedCount_controlIme() { + InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { + prepareControls(); + + // Showing invisible ime should only causes insets change once. + clearInvocations(mTestHost); + mController.show(ime(), true /* fromIme */); + verify(mTestHost, times(1)).notifyInsetsChanged(); + + // Sending the same insets state should not cause insets change. + // This simulates the callback from server after showing ime. + clearInvocations(mTestHost); + mController.onStateChanged(mController.getState()); + verify(mTestHost, never()).notifyInsetsChanged(); + + // Hiding visible ime should only causes insets change once. + clearInvocations(mTestHost); + mController.hide(ime()); + verify(mTestHost, times(1)).notifyInsetsChanged(); + + // Sending the same insets state should not cause insets change. + // This simulates the callback from server after hiding ime. + clearInvocations(mTestHost); + mController.onStateChanged(mController.getState()); + verify(mTestHost, never()).notifyInsetsChanged(); + }); + } + + @Test + public void testInsetsChangedCount_onStateChanged() { + InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { + final InsetsState localState = mController.getState(); + + // Changing status bar frame should cause notifyInsetsChanged. + clearInvocations(mTestHost); + InsetsState newState = new InsetsState(localState, true /* copySources */); + newState.getSource(ITYPE_STATUS_BAR).getFrame().bottom++; + mController.onStateChanged(newState); + verify(mTestHost, times(1)).notifyInsetsChanged(); + + // Changing status bar visibility should cause notifyInsetsChanged. + clearInvocations(mTestHost); + newState = new InsetsState(localState, true /* copySources */); + newState.getSource(ITYPE_STATUS_BAR).setVisible(false); + mController.onStateChanged(newState); + verify(mTestHost, times(1)).notifyInsetsChanged(); + + // Changing invisible IME frame should not cause notifyInsetsChanged. + clearInvocations(mTestHost); + newState = new InsetsState(localState, true /* copySources */); + newState.getSource(ITYPE_IME).getFrame().top--; + mController.onStateChanged(newState); + verify(mTestHost, never()).notifyInsetsChanged(); + + // Changing IME visibility should cause notifyInsetsChanged. + clearInvocations(mTestHost); + newState = new InsetsState(localState, true /* copySources */); + newState.getSource(ITYPE_IME).setVisible(true); + mController.onStateChanged(newState); + verify(mTestHost, times(1)).notifyInsetsChanged(); + }); + } + private void waitUntilNextFrame() throws Exception { final CountDownLatch latch = new CountDownLatch(1); Choreographer.getMainThreadInstance().postCallback(Choreographer.CALLBACK_COMMIT, @@ -777,7 +874,7 @@ public class InsetsControllerTest { return controls; } - private static class TestHost extends ViewRootInsetsControllerHost { + public static class TestHost extends ViewRootInsetsControllerHost { private InsetsState mModifiedState = new InsetsState(); -- GitLab From 64c342d2253d4d4fc419c634883eb24f847fef36 Mon Sep 17 00:00:00 2001 From: Zim Date: Wed, 19 Aug 2020 10:39:55 +0100 Subject: [PATCH 243/536] Avoid notifying the FUSE daemon for invisible volumes Invisible volumes/USB OTG volumes are neither exposed to apps nor the MediaStore. Calling into the FUSE daemon for invisible volumes can lead to unexpected exceptions if the MediaProvider tries to get more information about the StorageVolume from the StorageManagerService Test: Manual Bug: 163679723 Change-Id: I9e5e3418c1da15e61942fbedcf440ecca6cdca8c --- .../com/android/server/storage/StorageSessionController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/storage/StorageSessionController.java b/services/core/java/com/android/server/storage/StorageSessionController.java index 37df5481d3c4..0d059ae389e9 100644 --- a/services/core/java/com/android/server/storage/StorageSessionController.java +++ b/services/core/java/com/android/server/storage/StorageSessionController.java @@ -338,11 +338,12 @@ public final class StorageSessionController { } /** - * Returns {@code true} if {@code vol} is an emulated or public volume, + * Returns {@code true} if {@code vol} is an emulated or visible public volume, * {@code false} otherwise **/ public static boolean isEmulatedOrPublic(VolumeInfo vol) { - return vol.type == VolumeInfo.TYPE_EMULATED || vol.type == VolumeInfo.TYPE_PUBLIC; + return vol.type == VolumeInfo.TYPE_EMULATED + || (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isVisible()); } /** Exception thrown when communication with the {@link ExternalStorageService} fails. */ -- GitLab From 6afd939ba562ca463c29db805646eba6fe4e4297 Mon Sep 17 00:00:00 2001 From: junyulai Date: Tue, 18 Aug 2020 18:50:13 +0800 Subject: [PATCH 244/536] Skip RAT type listener registration if IMSI is not available Currently, if SIM is inserted but IMSI is not available, such as SIM PIN locked state. Information of such SIM will still be available but IMSI is not. Which makes NetworkStatsSubscriptionMonitor failed to store IMSI locally for later RAT type query. Hence, NETWORK_TYPE_UNKNOWN is always returned for such SIM. Skip the registration until the IMSI is available. This is safe since there will be another onSubscriptionsChanged event when that happens. Test: enable SIM PIN and manually test Test: atest NetworkStatsSubscriptionsMonitorTest#testSubscriberIdUnavailable Test: ./out/host/linux-x86/bin/statsd_testdrive 10082 Bug: 160941101 Merged-In: I408379b3c432d9e62e0837d6b4f6551cc7838e29 Change-Id: I408379b3c432d9e62e0837d6b4f6551cc7838e29 (cherry-picked from ag/12400327) --- .../net/NetworkStatsSubscriptionsMonitor.java | 13 ++++- .../NetworkStatsSubscriptionsMonitorTest.java | 56 +++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java index cb1c7e4fd0de..1c79332e9895 100644 --- a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java +++ b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java @@ -99,11 +99,16 @@ public class NetworkStatsSubscriptionsMonitor extends if (match != null) continue; // Create listener for every newly added sub. Also store subscriberId into it to - // prevent binder call to telephony when querying RAT. + // prevent binder call to telephony when querying RAT. If the subscriberId is empty + // for any reason, such as SIM PIN locked, skip registration. + // SubscriberId will be unavailable again if 1. modem crashed 2. reboot + // 3. re-insert SIM. If that happens, the listeners will be eventually synchronized + // with active sub list once all subscriberIds are ready. final String subscriberId = mTeleManager.getSubscriberId(subId); if (TextUtils.isEmpty(subscriberId)) { - Log.wtf(NetworkStatsService.TAG, - "Empty subscriberId for newly added sub: " + subId); + Log.d(NetworkStatsService.TAG, "Empty subscriberId for newly added sub " + + subId + ", skip listener registration"); + continue; } final RatTypeListener listener = new RatTypeListener(mExecutor, this, subId, subscriberId); @@ -112,6 +117,7 @@ public class NetworkStatsSubscriptionsMonitor extends // Register listener to the telephony manager that associated with specific sub. mTeleManager.createForSubscriptionId(subId) .listen(listener, PhoneStateListener.LISTEN_SERVICE_STATE); + Log.d(NetworkStatsService.TAG, "RAT type listener registered for sub " + subId); } for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) { @@ -164,6 +170,7 @@ public class NetworkStatsSubscriptionsMonitor extends private void handleRemoveRatTypeListener(@NonNull RatTypeListener listener) { mTeleManager.createForSubscriptionId(listener.mSubId) .listen(listener, PhoneStateListener.LISTEN_NONE); + Log.d(NetworkStatsService.TAG, "RAT type listener unregistered for sub " + listener.mSubId); mRatListeners.remove(listener); // Removal of subscriptions doesn't generate RAT changed event, fire it for every diff --git a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java b/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java index c91dfecf041b..7726c6637e0a 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.Context; import android.net.NetworkTemplate; import android.os.Looper; @@ -135,6 +136,11 @@ public final class NetworkStatsSubscriptionsMonitorTest { mMonitor.onSubscriptionsChanged(); } + private void updateSubscriberIdForTestSub(int subId, @Nullable final String subscriberId) { + when(mTelephonyManager.getSubscriberId(subId)).thenReturn(subscriberId); + mMonitor.onSubscriptionsChanged(); + } + private void removeTestSub(int subId) { // Remove subId from TestSubList. mTestSubList.removeIf(it -> it == subId); @@ -268,4 +274,54 @@ public final class NetworkStatsSubscriptionsMonitorTest { listener.onServiceStateChanged(serviceState); assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR); } + + @Test + public void testSubscriberIdUnavailable() { + final ArgumentCaptor ratTypeListenerCaptor = + ArgumentCaptor.forClass(RatTypeListener.class); + + mMonitor.start(); + // Insert sim1, set subscriberId to null which is normal in SIM PIN locked case. + // Verify RAT type is NETWORK_TYPE_UNKNOWN and service will not perform listener + // registration. + addTestSub(TEST_SUBID1, null); + verify(mTelephonyManager, never()).listen(any(), anyInt()); + assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); + + // Set IMSI for sim1, verify the listener will be registered. + updateSubscriberIdForTestSub(TEST_SUBID1, TEST_IMSI1); + verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(), + eq(PhoneStateListener.LISTEN_SERVICE_STATE)); + reset(mTelephonyManager); + when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); + + // Set RAT type of sim1 to UMTS. Verify RAT type of sim1 is changed. + setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, + TelephonyManager.NETWORK_TYPE_UMTS); + assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); + reset(mDelegate); + + // Set IMSI to null again to simulate somehow IMSI is not available, such as + // modem crash. Verify service should not unregister listener. + updateSubscriberIdForTestSub(TEST_SUBID1, null); + verify(mTelephonyManager, never()).listen(any(), anyInt()); + assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); + reset(mDelegate); + + // Set RAT type of sim1 to LTE. Verify RAT type of sim1 is still changed even if the IMSI + // is not available. The monitor keeps the listener even if the IMSI disappears because + // the IMSI can never change for any given subId, therefore even if the IMSI is updated + // to null, the monitor should continue accepting updates of the RAT type. However, + // telephony is never actually supposed to do this, if the IMSI disappears there should + // not be updates, but it's still the right thing to do theoretically. + setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, + TelephonyManager.NETWORK_TYPE_LTE); + assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_LTE); + reset(mDelegate); + + mMonitor.stop(); + verify(mTelephonyManager, times(1)).listen(eq(ratTypeListenerCaptor.getValue()), + eq(PhoneStateListener.LISTEN_NONE)); + assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); + } } -- GitLab From 23c75281ef0de8fb2b44fb93d8cf36ecf86454c7 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Thu, 13 Aug 2020 22:43:52 +0800 Subject: [PATCH 245/536] Update requested state after applying pending frames When there is an insets animation, we will stop updating insets source frames until the animation is done. The previous logic didn't update the frames within the requested state while the animation is done. And the frames was relied by InsetsPolicy while playing transient bar animation. If the frames don't match the display, the insets would be wrong, and the animation wouldn't be played correctly. Fix: 161134197 Test: atest InsetsControllerTest Merged-In: Id8f3c1956fbfe3ad16f167ff76297dde6c634e81 Change-Id: Id8f3c1956fbfe3ad16f167ff76297dde6c634e81 --- core/java/android/view/InsetsController.java | 9 ++++++--- .../src/android/view/InsetsControllerTest.java | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index e9b7695e7b71..403ac3ab29c0 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -1138,15 +1138,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (invokeCallback) { control.cancel(); } + boolean stateChanged = false; for (int i = mRunningAnimations.size() - 1; i >= 0; i--) { RunningAnimation runningAnimation = mRunningAnimations.get(i); if (runningAnimation.runner == control) { mRunningAnimations.remove(i); ArraySet types = toInternalType(control.getTypes()); for (int j = types.size() - 1; j >= 0; j--) { - if (getSourceConsumer(types.valueAt(j)).notifyAnimationFinished()) { - mHost.notifyInsetsChanged(); - } + stateChanged |= getSourceConsumer(types.valueAt(j)).notifyAnimationFinished(); } if (invokeCallback && runningAnimation.startDispatched) { dispatchAnimationEnd(runningAnimation.runner.getAnimation()); @@ -1154,6 +1153,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation break; } } + if (stateChanged) { + mHost.notifyInsetsChanged(); + updateRequestedState(); + } } private void applyLocalVisibilityOverride() { diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index af02b7bdbd90..de128ad6d78e 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -746,6 +746,20 @@ public class InsetsControllerTest { mController.onControlsChanged(createSingletonControl(ITYPE_IME)); assertEquals(newState.getSource(ITYPE_IME), mTestHost.getModifiedState().peekSource(ITYPE_IME)); + + // The modified frames cannot be updated if there is an animation. + mController.onControlsChanged(createSingletonControl(ITYPE_NAVIGATION_BAR)); + mController.hide(navigationBars()); + newState = new InsetsState(mController.getState(), true /* copySource */); + newState.getSource(ITYPE_NAVIGATION_BAR).getFrame().top--; + mController.onStateChanged(newState); + assertNotEquals(newState.getSource(ITYPE_NAVIGATION_BAR), + mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR)); + + // The modified frames can be updated while the animation is done. + mController.cancelExistingAnimations(); + assertEquals(newState.getSource(ITYPE_NAVIGATION_BAR), + mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR)); }); } -- GitLab From 48288a505dbcfc31a9a01f75dba24d5f62d428a4 Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Wed, 12 Aug 2020 13:00:02 +0800 Subject: [PATCH 246/536] Correct the return value of applyAnimationLocked. The starting window cannot be removed because it is waiting for the exiting animation finished, This may happen if the animation is not applied when #selectAnimation cannot find an appropriate animation. To make the state correct, the return result of #applyAnimationLocked should not only reference to the hierarchial animation state. Bug: 161847146 Test: atest WmTests Change-Id: I69bcd29f2587a3644485a0db05e622f6775cc82f Merged-In: I69bcd29f2587a3644485a0db05e622f6775cc82f --- .../core/java/com/android/server/wm/WindowStateAnimator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index da45300ed318..80c84ad66423 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -38,6 +38,7 @@ import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC; import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; @@ -1478,7 +1479,7 @@ class WindowStateAnimator { mWin.getDisplayContent().adjustForImeIfNeeded(); } - return mWin.isAnimating(PARENTS); + return mWin.isAnimating(0 /* flags */, ANIMATION_TYPE_WINDOW_ANIMATION); } void dumpDebug(ProtoOutputStream proto, long fieldId) { -- GitLab From 8ea64c4b6afc6628f97d0c8ef5ccd654d08065c2 Mon Sep 17 00:00:00 2001 From: jasonwshsu Date: Wed, 19 Aug 2020 23:14:41 +0800 Subject: [PATCH 247/536] Update language to comply with Android's inclusive language guidance 1. Rename isClientInWhitelist to isClientInAllowlist See https://source.android.com/setup/contribute/respectful-code for reference Bug: 162536543 Test: Build & run Merged-In: Ibbd97bf31915d59b5110cbcc8f2126f7a7221060 Merged-In: I915e09e4e64d5c268630cec2d0ef05ea0592fd6f Change-Id: I499c4574464862f3a1dcea2c6d51813e23ba4b82 --- .../AccessibilityManagerService.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 499a2711d8e6..fcf270b4ef35 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -1464,19 +1464,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub int serviceCount = userState.mBoundServices.size(); for (int i = 0; i < serviceCount; i++) { AccessibilityServiceConnection service = userState.mBoundServices.get(i); - relevantEventTypes |= isClientInPackageWhitelist(service.getServiceInfo(), client) + relevantEventTypes |= isClientInPackageAllowlist(service.getServiceInfo(), client) ? service.getRelevantEventTypes() : 0; } - relevantEventTypes |= isClientInPackageWhitelist( + relevantEventTypes |= isClientInPackageAllowlist( mUiAutomationManager.getServiceInfo(), client) ? mUiAutomationManager.getRelevantEventTypes() : 0; return relevantEventTypes; } - private static boolean isClientInPackageWhitelist( + private static boolean isClientInPackageAllowlist( @Nullable AccessibilityServiceInfo serviceInfo, Client client) { if (serviceInfo == null) return false; @@ -1495,7 +1495,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub Slog.d(LOG_TAG, "Dropping events: " + Arrays.toString(clientPackages) + " -> " + serviceInfo.getComponentName().flattenToShortString() - + " due to not being in package whitelist " + + " due to not being in package allowlist " + Arrays.toString(serviceInfo.packageNames)); } } @@ -1890,9 +1890,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } private void updateLegacyCapabilitiesLocked(AccessibilityUserState userState) { - // Up to JB-MR1 we had a white list with services that can enable touch + // Up to JB-MR1 we had a allowlist with services that can enable touch // exploration. When a service is first started we show a dialog to the - // use to get a permission to white list the service. + // use to get a permission to allowlist the service. final int installedServiceCount = userState.mInstalledServices.size(); for (int i = 0; i < installedServiceCount; i++) { AccessibilityServiceInfo serviceInfo = userState.mInstalledServices.get(i); @@ -2155,9 +2155,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } if (service.getServiceInfo().getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1) { - // Up to JB-MR1 we had a white list with services that can enable touch + // Up to JB-MR1 we had a allowlist with services that can enable touch // exploration. When a service is first started we show a dialog to the - // use to get a permission to white list the service. + // use to get a permission to allowlist the service. if (userState.mTouchExplorationGrantedServices.contains(service.mComponentName)) { return true; } else if (mEnableTouchExplorationDialog == null -- GitLab From 444e8dc6ce224f87b4d062d697a6db5a62e11183 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Fri, 7 Aug 2020 20:13:55 +0800 Subject: [PATCH 248/536] Refine system bar position restoring The previous logic restores the system bar as long as its insets source is visible. There can be a timing issue that if the user swipes to show transient bars while an immersive app just becomes the control target but the hide-bar info haven't sent to WM yet, WM will re-show the bar incorrectly. This CL uses the requested visibility and the behavior to decide if we should restore the postion and the visibility. This CL also refines and caches the arguments of showTransient. In this way, we don't have to create the array every time while invoking that method. Fix: 161247175 Test: atest InsetsPolicyTest Merged-In: Idef314dfe6625399b88b3dacb4c74c7071453497 Change-Id: Idef314dfe6625399b88b3dacb4c74c7071453497 (cherry picked from commit 533682ebb39456df26097753d1f5172bff0e3d5d) --- core/java/android/view/InsetsState.java | 2 ++ .../com/android/server/wm/DisplayPolicy.java | 28 ++++++++++++------- .../server/wm/InsetsControlTarget.java | 8 ++++++ .../com/android/server/wm/InsetsPolicy.java | 10 ++----- .../com/android/server/wm/WindowState.java | 3 +- .../android/server/wm/InsetsPolicyTest.java | 13 +++------ 6 files changed, 37 insertions(+), 27 deletions(-) diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 6b0b509932a8..593b37af26ad 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -60,6 +60,8 @@ import java.util.StringJoiner; */ public class InsetsState implements Parcelable { + public static final InsetsState EMPTY = new InsetsState(); + /** * Internal representation of inset source types. This is different from the public API in * {@link WindowInsets.Type} as one type from the public API might indicate multiple windows diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 0d467c50aa11..7f827e488af2 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -241,6 +241,9 @@ public class DisplayPolicy { | View.STATUS_BAR_TRANSPARENT | View.NAVIGATION_BAR_TRANSPARENT; + private static final int[] SHOW_TYPES_FOR_SWIPE = {ITYPE_NAVIGATION_BAR, ITYPE_STATUS_BAR}; + private static final int[] SHOW_TYPES_FOR_PANIC = {ITYPE_NAVIGATION_BAR}; + private final WindowManagerService mService; private final Context mContext; private final Context mUiContext; @@ -3215,8 +3218,15 @@ public class DisplayPolicy { return; } + final InsetsState requestedState = controlTarget.getRequestedInsetsState(); + final @InsetsType int restorePositionTypes = + (requestedState.getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR) + ? Type.navigationBars() : 0) + | (requestedState.getSourceOrDefaultVisibility(ITYPE_STATUS_BAR) + ? Type.statusBars() : 0); + if (swipeTarget == mNavigationBar - && !getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)) { + && (restorePositionTypes & Type.navigationBars()) != 0) { // Don't show status bar when swiping on already visible navigation bar. // But restore the position of navigation bar if it has been moved by the control // target. @@ -3224,14 +3234,13 @@ public class DisplayPolicy { return; } - int insetsTypesToShow = Type.systemBars(); - if (controlTarget.canShowTransient()) { - insetsTypesToShow &= ~mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap( - new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); - } - if (insetsTypesToShow != 0) { - controlTarget.showInsets(insetsTypesToShow, false); + // Show transient bars if they are hidden; restore position if they are visible. + mDisplayContent.getInsetsPolicy().showTransient(SHOW_TYPES_FOR_SWIPE); + controlTarget.showInsets(restorePositionTypes, false); + } else { + // Restore visibilities and positions of system bars. + controlTarget.showInsets(Type.statusBars() | Type.navigationBars(), false); } } else { boolean sb = mStatusBarController.checkShowTransientBarLw(); @@ -3809,8 +3818,7 @@ public class DisplayPolicy { mPendingPanicGestureUptime = SystemClock.uptimeMillis(); if (!isNavBarEmpty(mLastSystemUiFlags)) { mNavigationBarController.showTransient(); - mDisplayContent.getInsetsPolicy().showTransient(IntArray.wrap( - new int[] {ITYPE_NAVIGATION_BAR})); + mDisplayContent.getInsetsPolicy().showTransient(SHOW_TYPES_FOR_PANIC); } } } diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java index 3ffc26a7a8ad..5e7ed3f80e43 100644 --- a/services/core/java/com/android/server/wm/InsetsControlTarget.java +++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java @@ -17,6 +17,7 @@ package com.android.server.wm; import android.inputmethodservice.InputMethodService; +import android.view.InsetsState; import android.view.WindowInsets.Type.InsetsType; /** @@ -37,6 +38,13 @@ interface InsetsControlTarget { return null; } + /** + * @return The requested {@link InsetsState} of this target. + */ + default InsetsState getRequestedInsetsState() { + return InsetsState.EMPTY; + } + /** * Instructs the control target to show inset sources. * diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 254356d673e3..a145be0ab83c 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -42,7 +42,6 @@ import android.view.InsetsState.InternalInsetsType; import android.view.SurfaceControl; import android.view.SyncRtSurfaceTransactionApplier; import android.view.ViewRootImpl; -import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsAnimation; import android.view.WindowInsetsAnimation.Bounds; import android.view.WindowInsetsAnimationControlListener; @@ -133,15 +132,13 @@ class InsetsPolicy { return provider != null && provider.hasWindow() && !provider.getSource().isVisible(); } - @InsetsType int showTransient(IntArray types) { - @InsetsType int showingTransientTypes = 0; + void showTransient(@InternalInsetsType int[] types) { boolean changed = false; - for (int i = types.size() - 1; i >= 0; i--) { - final int type = types.get(i); + for (int i = types.length - 1; i >= 0; i--) { + final @InternalInsetsType int type = types[i]; if (!isHidden(type)) { continue; } - showingTransientTypes |= InsetsState.toPublicType(type); if (mShowingTransientTypes.indexOf(type) != -1) { continue; } @@ -169,7 +166,6 @@ class InsetsPolicy { } }); } - return showingTransientTypes; } void hideTransient() { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 11db705f4e04..6a2c54e0b292 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -725,7 +725,8 @@ class WindowState extends WindowContainer implements WindowManagerP * @return The insets state as requested by the client, i.e. the dispatched insets state * for which the visibilities are overridden with what the client requested. */ - InsetsState getRequestedInsetsState() { + @Override + public InsetsState getRequestedInsetsState() { return mRequestedInsetsState; } diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java index c794e1a3b328..da36ba9d3613 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -43,7 +43,6 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.spy; import android.platform.test.annotations.Presubmit; -import android.util.IntArray; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.test.InsetsModeSession; @@ -240,8 +239,7 @@ public class InsetsPolicyTest extends WindowTestsBase { }).when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(mAppWindow); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); waitUntilWindowAnimatorIdle(); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -268,8 +266,7 @@ public class InsetsPolicyTest extends WindowTestsBase { final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(mAppWindow); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); waitUntilWindowAnimatorIdle(); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -297,8 +294,7 @@ public class InsetsPolicyTest extends WindowTestsBase { final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(mAppWindow); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); waitUntilWindowAnimatorIdle(); InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); @@ -336,8 +332,7 @@ public class InsetsPolicyTest extends WindowTestsBase { final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy()); doNothing().when(policy).startAnimation(anyBoolean(), any(), any()); policy.updateBarControlTarget(app); - policy.showTransient( - IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR})); + policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}); final InsetsSourceControl[] controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(app); policy.updateBarControlTarget(app2); -- GitLab From 6212e2a6d0e54e4e179383db1f64ff0cdcccdd27 Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Tue, 18 Aug 2020 13:52:04 -0700 Subject: [PATCH 249/536] Fix screenlayout calculation with overridden screenW/Hdp Split-screen adjust-for-ime overrides screenW/Hdp in order to prevent the app-configuration from changing. However, the logic in Task#computeConfigResourceOverrides was ignoring the overrides and blindly using the display's non-decor bounds. This means that on loong screens, the app will flip into/out-of long layout when adjusting (non-adjusted task has no screenSizeDp overrides so it goes through logic which crops mTmpNonDecorBounds). Fix this by honoring the screenW/Hdp overrides when calculating screenLayout. Bug: 163848060 Test: On long screen (eg 21:9 aspect), open ime in second split. Also added regression unit-test. Change-Id: I0fcec4f035e466fafedc31be5925c0b04a6580f7 Merged-In: I0fcec4f035e466fafedc31be5925c0b04a6580f7 --- .../core/java/com/android/server/wm/Task.java | 12 +++++++-- .../server/wm/ActivityRecordTests.java | 2 +- .../android/server/wm/TaskRecordTests.java | 25 +++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 6785127d5953..efcb6dc9ada1 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -2371,8 +2371,16 @@ class Task extends WindowContainer { // For calculating screen layout, we need to use the non-decor inset screen area for the // calculation for compatibility reasons, i.e. screen area without system bars that // could never go away in Honeycomb. - final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density); - final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density); + int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density); + int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density); + // Use overrides if provided. If both overrides are provided, mTmpNonDecorBounds is + // undefined so it can't be used. + if (inOutConfig.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) { + compatScreenWidthDp = inOutConfig.screenWidthDp; + } + if (inOutConfig.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) { + compatScreenHeightDp = inOutConfig.screenHeightDp; + } // Reducing the screen layout starting from its parent config. inOutConfig.screenLayout = computeScreenLayoutOverride(parentConfig.screenLayout, compatScreenWidthDp, compatScreenHeightDp); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 6ab0697206e3..bb85c8aa1977 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -536,7 +536,7 @@ public class ActivityRecordTests extends ActivityTestsBase { mActivity = new ActivityBuilder(mService) .setTask(mTask) .setLaunchTaskBehind(true) - .setConfigChanges(CONFIG_ORIENTATION) + .setConfigChanges(CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT) .build(); mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing"); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java index fb24d868e970..ddaa586fae8a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java @@ -402,6 +402,31 @@ public class TaskRecordTests extends ActivityTestsBase { assertEquals(Configuration.ORIENTATION_LANDSCAPE, inOutConfig.orientation); } + @Test + public void testComputeConfigResourceLayoutOverrides() { + final Rect fullScreenBounds = new Rect(0, 0, 1000, 2500); + TestDisplayContent display = new TestDisplayContent.Builder( + mService, fullScreenBounds.width(), fullScreenBounds.height()).build(); + final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build(); + final Configuration inOutConfig = new Configuration(); + final Configuration parentConfig = new Configuration(); + final Rect nonLongBounds = new Rect(0, 0, 1000, 1250); + parentConfig.windowConfiguration.setBounds(fullScreenBounds); + parentConfig.windowConfiguration.setAppBounds(fullScreenBounds); + parentConfig.densityDpi = 400; + parentConfig.screenHeightDp = (fullScreenBounds.bottom * 160) / parentConfig.densityDpi; + parentConfig.screenWidthDp = (fullScreenBounds.right * 160) / parentConfig.densityDpi; + parentConfig.windowConfiguration.setRotation(ROTATION_0); + + // Set BOTH screenW/H to an override value + inOutConfig.screenWidthDp = nonLongBounds.width() * 160 / parentConfig.densityDpi; + inOutConfig.screenHeightDp = nonLongBounds.height() * 160 / parentConfig.densityDpi; + task.computeConfigResourceOverrides(inOutConfig, parentConfig); + + // screenLayout should honor override when both screenW/H are set. + assertTrue((inOutConfig.screenLayout & Configuration.SCREENLAYOUT_LONG_NO) != 0); + } + @Test public void testComputeNestedConfigResourceOverrides() { final Task task = new TaskBuilder(mSupervisor).build(); -- GitLab From 48c13b4f9a9f3329a7b8b540642a3b87372b9b38 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 19 Aug 2020 18:39:40 +0000 Subject: [PATCH 250/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I36607eb2b8dca3dcf95e435d6decc44ab686cfb3 --- packages/SettingsLib/res/values-hy/strings.xml | 2 +- packages/SettingsLib/res/values-nl/strings.xml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index f219d248e641..8b92640e9996 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -37,7 +37,7 @@ "Ինտերնետ կապ չկա" "Ով է պահել՝ %1$s" "Ավտոմատ կերպով կապակցվել է %1$s-ի միջոցով" - "Ավտոմատ կերպով միացել է ցանցի վարկանիշի ծառայության մատակարարի միջոցով" + "Ավտոմատ միացել է ցանցերի վարկանիշի մատակարարի միջոցով" "Միացված է %1$s-ի միջոցով" "Միացված է %1$s-ի միջոցով" "Հասանելի է %1$s-ի միջոցով" diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 83b72e925fe1..27f5dc9cc4d4 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -93,8 +93,8 @@ "Sim-toegang" "HD-audio: %1$s" "HD-audio" - "Gehoorapparaten" - "Verbonden met gehoorapparaten" + "Hoortoestellen" + "Verbonden met hoortoestellen" "Verbonden met audio van medium" "Verbonden met audio van telefoon" "Verbonden met server voor bestandsoverdracht" @@ -111,7 +111,7 @@ "Gebruiken voor audio van telefoon" "Gebruiken voor bestandsoverdracht" "Gebruiken voor invoer" - "Gebruiken voor gehoorapparaten" + "Gebruiken voor hoortoestellen" "Koppelen" "KOPPELEN" "Annuleren" @@ -127,8 +127,8 @@ "Hoofdtelefoon" "Randapparaat voor invoer" "Bluetooth" - "Linker gehoorapparaat koppelen…" - "Rechter gehoorapparaat koppelen…" + "Linker hoortoestel koppelen…" + "Rechter hoortoestel koppelen…" "Links: batterijniveau %1$s" "Rechts: batterijniveau %1$s" "Wifi: uitgeschakeld." -- GitLab From 68b3b2b79035ede7013cd92805cd31d58243288a Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 19 Aug 2020 19:14:58 +0000 Subject: [PATCH 251/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I0db0204c6788894b006348b2ba07dea09dff95eb --- packages/SettingsLib/res/values-hy/strings.xml | 2 +- packages/SettingsLib/res/values-nl/strings.xml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index f219d248e641..8b92640e9996 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -37,7 +37,7 @@ "Ինտերնետ կապ չկա" "Ով է պահել՝ %1$s" "Ավտոմատ կերպով կապակցվել է %1$s-ի միջոցով" - "Ավտոմատ կերպով միացել է ցանցի վարկանիշի ծառայության մատակարարի միջոցով" + "Ավտոմատ միացել է ցանցերի վարկանիշի մատակարարի միջոցով" "Միացված է %1$s-ի միջոցով" "Միացված է %1$s-ի միջոցով" "Հասանելի է %1$s-ի միջոցով" diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 83b72e925fe1..27f5dc9cc4d4 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -93,8 +93,8 @@ "Sim-toegang" "HD-audio: %1$s" "HD-audio" - "Gehoorapparaten" - "Verbonden met gehoorapparaten" + "Hoortoestellen" + "Verbonden met hoortoestellen" "Verbonden met audio van medium" "Verbonden met audio van telefoon" "Verbonden met server voor bestandsoverdracht" @@ -111,7 +111,7 @@ "Gebruiken voor audio van telefoon" "Gebruiken voor bestandsoverdracht" "Gebruiken voor invoer" - "Gebruiken voor gehoorapparaten" + "Gebruiken voor hoortoestellen" "Koppelen" "KOPPELEN" "Annuleren" @@ -127,8 +127,8 @@ "Hoofdtelefoon" "Randapparaat voor invoer" "Bluetooth" - "Linker gehoorapparaat koppelen…" - "Rechter gehoorapparaat koppelen…" + "Linker hoortoestel koppelen…" + "Rechter hoortoestel koppelen…" "Links: batterijniveau %1$s" "Rechts: batterijniveau %1$s" "Wifi: uitgeschakeld." -- GitLab From 6adc3669892e5177e3aa0ec3655033b431364ad8 Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Fri, 14 Aug 2020 11:32:59 -0400 Subject: [PATCH 252/536] Media - Don't animate during camera gesture More generally, block invalid transitions from lockscreen to QQS. Fixes: 161096422 Test: manual, camera gesture Change-Id: I5267defa75fcc28d34138608818ed26f60f4801b (cherry picked from commit 3cd5e8560de93d48a0d2d0a991d9c1b707cdf79a) --- .../android/systemui/media/MediaHierarchyManager.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt index 70f01d576a9c..b31390cf7474 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt @@ -389,6 +389,14 @@ class MediaHierarchyManager @Inject constructor( if (isCurrentlyInGuidedTransformation()) { return false } + // This is an invalid transition, and can happen when using the camera gesture from the + // lock screen. Disallow. + if (previousLocation == LOCATION_LOCKSCREEN && + desiredLocation == LOCATION_QQS && + statusbarState == StatusBarState.SHADE) { + return false + } + if (currentLocation == LOCATION_QQS && previousLocation == LOCATION_LOCKSCREEN && (statusBarStateController.leaveOpenOnKeyguardHide() || @@ -604,8 +612,8 @@ class MediaHierarchyManager @Inject constructor( // When collapsing on the lockscreen, we want to remain in QS return LOCATION_QS } - if (location != LOCATION_LOCKSCREEN && desiredLocation == LOCATION_LOCKSCREEN - && !fullyAwake) { + if (location != LOCATION_LOCKSCREEN && desiredLocation == LOCATION_LOCKSCREEN && + !fullyAwake) { // When unlocking from dozing / while waking up, the media shouldn't be transitioning // in an animated way. Let's keep it in the lockscreen until we're fully awake and // reattach it without an animation -- GitLab From 665f91bdaac08c19dd154ca35ce17060f088deb9 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Mon, 29 Jun 2020 16:54:21 -0700 Subject: [PATCH 253/536] Correctly expose EGL_ANDROID_native_fence_sync to hwui When we moved off of gui/SyncFeatures for retrieving this extension, we accidentally didn't include the eglQueryStringImplementationANDROID path for retrieving extensions. Fortunately this extension is only used for TextureView synchronization, but we should still use the extension when available. Bug: 159921224 Bug: 161767307 Test: Manually inject log statements to verify the extension is correctly visible. Change-Id: Idaa872778afc13e86bdea918da8631b4747fe9c1 Merged-In: Idaa872778afc13e86bdea918da8631b4747fe9c1 (cherry picked from commit 49d87e5c077fed85c48341be65e9eaff98654bef) --- libs/hwui/renderthread/EglManager.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 5e0471c08d67..7982ab664c1b 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -208,8 +208,12 @@ EGLConfig EglManager::loadFP16Config(EGLDisplay display, SwapBehavior swapBehavi return config; } +extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); + void EglManager::initExtensions() { auto extensions = StringUtils::split(eglQueryString(mEglDisplay, EGL_EXTENSIONS)); + auto extensionsAndroid = + StringUtils::split(eglQueryStringImplementationANDROID(mEglDisplay, EGL_EXTENSIONS)); // For our purposes we don't care if EGL_BUFFER_AGE is a result of // EGL_EXT_buffer_age or EGL_KHR_partial_update as our usage is covered @@ -228,9 +232,12 @@ void EglManager::initExtensions() { EglExtensions.displayP3 = extensions.has("EGL_EXT_gl_colorspace_display_p3_passthrough"); EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority"); EglExtensions.surfacelessContext = extensions.has("EGL_KHR_surfaceless_context"); - EglExtensions.nativeFenceSync = extensions.has("EGL_ANDROID_native_fence_sync"); EglExtensions.fenceSync = extensions.has("EGL_KHR_fence_sync"); EglExtensions.waitSync = extensions.has("EGL_KHR_wait_sync"); + + // EGL_ANDROID_native_fence_sync is not exposed to applications, so access + // this through the private Android-specific query instead. + EglExtensions.nativeFenceSync = extensionsAndroid.has("EGL_ANDROID_native_fence_sync"); } bool EglManager::hasEglContext() { -- GitLab From 732608a6be70f9756e9dfcb91941549c40ad5abb Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Mon, 17 Aug 2020 17:37:09 -0700 Subject: [PATCH 254/536] Add app-ops for camera/mic use during phone call Test: Started a phone call, verified app-op was active Bug: 162547999 Change-Id: I93bf59d24e3cfbeaede442571f09ba97f0990c75 --- core/java/android/app/AppOpsManager.java | 46 +++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 0a6827cde3d3..d13137d4a716 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1124,9 +1124,24 @@ public class AppOpsManager { /** @hide */ public static final int OP_NO_ISOLATED_STORAGE = AppProtoEnums.APP_OP_NO_ISOLATED_STORAGE; + /** + * Phone call is using microphone + * + * @hide + */ + // TODO: Add as AppProtoEnums + public static final int OP_PHONE_CALL_MICROPHONE = 100; + /** + * Phone call is using camera + * + * @hide + */ + // TODO: Add as AppProtoEnums + public static final int OP_PHONE_CALL_CAMERA = 101; + /** @hide */ @UnsupportedAppUsage - public static final int _NUM_OP = 100; + public static final int _NUM_OP = 102; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -1444,6 +1459,19 @@ public class AppOpsManager { */ public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage"; + /** + * Phone call is using microphone + * + * @hide + */ + public static final String OPSTR_PHONE_CALL_MICROPHONE = "android:phone_call_microphone"; + /** + * Phone call is using camera + * + * @hide + */ + public static final String OPSTR_PHONE_CALL_CAMERA = "android:phone_call_camera"; + /** {@link #sAppOpsToNote} not initialized yet for this op */ private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0; /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */ @@ -1633,6 +1661,8 @@ public class AppOpsManager { OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, //AUTO_REVOKE_PERMISSIONS_IF_UNUSED OP_AUTO_REVOKE_MANAGED_BY_INSTALLER, //OP_AUTO_REVOKE_MANAGED_BY_INSTALLER OP_NO_ISOLATED_STORAGE, // NO_ISOLATED_STORAGE + OP_PHONE_CALL_MICROPHONE, // OP_PHONE_CALL_MICROPHONE + OP_PHONE_CALL_CAMERA, // OP_PHONE_CALL_CAMERA }; /** @@ -1739,6 +1769,8 @@ public class AppOpsManager { OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER, OPSTR_NO_ISOLATED_STORAGE, + OPSTR_PHONE_CALL_MICROPHONE, + OPSTR_PHONE_CALL_CAMERA, }; /** @@ -1846,6 +1878,8 @@ public class AppOpsManager { "AUTO_REVOKE_PERMISSIONS_IF_UNUSED", "AUTO_REVOKE_MANAGED_BY_INSTALLER", "NO_ISOLATED_STORAGE", + "PHONE_CALL_MICROPHONE", + "PHONE_CALL_CAMERA", }; /** @@ -1954,6 +1988,8 @@ public class AppOpsManager { null, // no permission for OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED null, // no permission for OP_AUTO_REVOKE_MANAGED_BY_INSTALLER null, // no permission for OP_NO_ISOLATED_STORAGE + null, // no permission for OP_PHONE_CALL_MICROPHONE + null, // no permission for OP_PHONE_CALL_CAMERA }; /** @@ -2062,6 +2098,8 @@ public class AppOpsManager { null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED null, // AUTO_REVOKE_MANAGED_BY_INSTALLER null, // NO_ISOLATED_STORAGE + null, // PHONE_CALL_MICROPHONE + null, // PHONE_CALL_MICROPHONE }; /** @@ -2169,6 +2207,8 @@ public class AppOpsManager { null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED null, // AUTO_REVOKE_MANAGED_BY_INSTALLER null, // NO_ISOLATED_STORAGE + null, // PHONE_CALL_MICROPHONE + null, // PHONE_CALL_CAMERA }; /** @@ -2275,6 +2315,8 @@ public class AppOpsManager { AppOpsManager.MODE_DEFAULT, // OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED AppOpsManager.MODE_ALLOWED, // OP_AUTO_REVOKE_MANAGED_BY_INSTALLER AppOpsManager.MODE_ERRORED, // OP_NO_ISOLATED_STORAGE + AppOpsManager.MODE_ALLOWED, // PHONE_CALL_MICROPHONE + AppOpsManager.MODE_ALLOWED, // PHONE_CALL_CAMERA }; /** @@ -2385,6 +2427,8 @@ public class AppOpsManager { false, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED false, // AUTO_REVOKE_MANAGED_BY_INSTALLER true, // NO_ISOLATED_STORAGE + false, // PHONE_CALL_MICROPHONE + false, // PHONE_CALL_CAMERA }; /** -- GitLab From 94afe73ca26292e33bd1d51a4934e2313a551843 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Mon, 17 Aug 2020 18:37:30 -0700 Subject: [PATCH 255/536] Treat phone call mic/camera similar to other mic/camera app-ops Bug: 162547999 Test: Started a phone call and swiped clicked all way through privacy chip flow Change-Id: Icb933c7e4e430d3da54cef44b5aaab99093ffeca --- .../com/android/systemui/appops/AppOpsControllerImpl.java | 6 +++++- .../com/android/systemui/privacy/PrivacyItemController.kt | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index 01841249f4ac..6347cee7d892 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -82,8 +82,10 @@ public class AppOpsControllerImpl implements AppOpsController, protected static final int[] OPS = new int[] { AppOpsManager.OP_CAMERA, + AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, AppOpsManager.OP_RECORD_AUDIO, + AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION }; @@ -302,7 +304,9 @@ public class AppOpsControllerImpl implements AppOpsController, // does not correspond to a platform permission // which may be user sensitive, so for now always show it to the user. if (appOpCode == AppOpsManager.OP_SYSTEM_ALERT_WINDOW - || appOpCode == AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION) { + || appOpCode == AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION + || appOpCode == AppOpsManager.OP_PHONE_CALL_CAMERA + || appOpCode == AppOpsManager.OP_PHONE_CALL_MICROPHONE) { return true; } diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt index 2be69c10a77b..59118bf3534e 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt @@ -57,7 +57,8 @@ class PrivacyItemController @Inject constructor( @VisibleForTesting internal companion object { val OPS_MIC_CAMERA = intArrayOf(AppOpsManager.OP_CAMERA, - AppOpsManager.OP_RECORD_AUDIO) + AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_RECORD_AUDIO, + AppOpsManager.OP_PHONE_CALL_MICROPHONE) val OPS_LOCATION = intArrayOf( AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION) @@ -248,9 +249,11 @@ class PrivacyItemController @Inject constructor( private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? { val type: PrivacyType = when (appOpItem.code) { + AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_CAMERA - AppOpsManager.OP_COARSE_LOCATION -> PrivacyType.TYPE_LOCATION + AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION + AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE else -> return null } -- GitLab From 64c801d344aba147359875a1650003b52987b5b1 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Tue, 18 Aug 2020 19:39:01 -0700 Subject: [PATCH 256/536] Special case location provider camera accesses and show them as indicators Bug: 162547999 Test: Made location provider access camera and saw privacy chip Change-Id: I5960fdff38b38a0bd8f4d9c9826639cc89a94603 --- .../com/android/systemui/appops/AppOpsControllerImpl.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index 6347cee7d892..b70142826c1e 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -19,6 +19,7 @@ package com.android.systemui.appops; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; +import android.location.LocationManager; import android.media.AudioManager; import android.media.AudioRecordingConfiguration; import android.os.Handler; @@ -66,6 +67,7 @@ public class AppOpsControllerImpl implements AppOpsController, private final AppOpsManager mAppOps; private final AudioManager mAudioManager; + private final LocationManager mLocationManager; private H mBGHandler; private final List mCallbacks = new ArrayList<>(); private final ArrayMap> mCallbacksByCode = new ArrayMap<>(); @@ -106,6 +108,7 @@ public class AppOpsControllerImpl implements AppOpsController, mCallbacksByCode.put(OPS[i], new ArraySet<>()); } mAudioManager = audioManager; + mLocationManager = context.getSystemService(LocationManager.class); dumpManager.registerDumpable(TAG, this); } @@ -310,6 +313,11 @@ public class AppOpsControllerImpl implements AppOpsController, return true; } + if (appOpCode == AppOpsManager.OP_CAMERA && mLocationManager.isProviderPackage( + packageName)) { + return true; + } + return isUserSensitive(appOpCode, uid, packageName); } -- GitLab From c1dc1b8519397917796b59bfc8e28b47d1afedb5 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 19 Aug 2020 11:22:55 -0700 Subject: [PATCH 257/536] Cache location provider pkg name Bug: 162547999 Test: Accessed camera from location provider and saw camera indicator Change-Id: Id273b7d42c6ebb60219b515e2ebd4bd44961c2e0 --- .../systemui/appops/AppOpsControllerImpl.java | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index b70142826c1e..64b35caeeef2 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -68,6 +68,12 @@ public class AppOpsControllerImpl implements AppOpsController, private final AppOpsManager mAppOps; private final AudioManager mAudioManager; private final LocationManager mLocationManager; + + // mLocationProviderPackages are cached and updated only occasionally + private static final long LOCATION_PROVIDER_UPDATE_FREQUENCY_MS = 30000; + private long mLastLocationProviderPackageUpdate; + private List mLocationProviderPackages; + private H mBGHandler; private final List mCallbacks = new ArrayList<>(); private final ArrayMap> mCallbacksByCode = new ArrayMap<>(); @@ -292,6 +298,26 @@ public class AppOpsControllerImpl implements AppOpsController, return isUserVisible(item.getCode(), item.getUid(), item.getPackageName()); } + /** + * Checks if a package is the current location provider. + * + *

      Data is cached to avoid too many calls into system server + * + * @param packageName The package that might be the location provider + * + * @return {@code true} iff the package is the location provider. + */ + private boolean isLocationProvider(String packageName) { + long now = System.currentTimeMillis(); + + if (mLastLocationProviderPackageUpdate + LOCATION_PROVIDER_UPDATE_FREQUENCY_MS < now) { + mLastLocationProviderPackageUpdate = now; + mLocationProviderPackages = mLocationManager.getProviderPackages( + LocationManager.FUSED_PROVIDER); + } + + return mLocationProviderPackages.contains(packageName); + } /** * Does the app-op, uid and package name, refer to an operation that should be shown to the @@ -313,8 +339,7 @@ public class AppOpsControllerImpl implements AppOpsController, return true; } - if (appOpCode == AppOpsManager.OP_CAMERA && mLocationManager.isProviderPackage( - packageName)) { + if (appOpCode == AppOpsManager.OP_CAMERA && isLocationProvider(packageName)) { return true; } -- GitLab From 69e604fdb9ffc5e13a545e89c523b0edd391b7ad Mon Sep 17 00:00:00 2001 From: Songchun Fan Date: Wed, 29 Jul 2020 12:55:11 -0700 Subject: [PATCH 258/536] [SettingsProvider] fix WriteFallbackSettingsFilesJobService holding wakelock onStartJob() should return false otherwise the job service will hold a long wakelock until it times out. writeFallBackSettingsFiles() is blocking, so when it returns we should finish the job. BUG: 162438758 Test: manual Change-Id: I3bfbcf5a7b21f142fd00130e1a57232bc02aedb6 (cherry picked from commit 690888547af30bb18809505dd22eb6d76641c711) Merged-In: I3bfbcf5a7b21f142fd00130e1a57232bc02aedb6 --- .../WriteFallbackSettingsFilesJobService.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java b/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java index 6e5b8890438d..66aa7baa3b51 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/WriteFallbackSettingsFilesJobService.java @@ -35,19 +35,17 @@ import java.util.List; public class WriteFallbackSettingsFilesJobService extends JobService { @Override public boolean onStartJob(final JobParameters params) { - switch (params.getJobId()) { - case WRITE_FALLBACK_SETTINGS_FILES_JOB_ID: - final List settingsFiles = new ArrayList<>(); - settingsFiles.add(params.getExtras().getString(TABLE_GLOBAL, "")); - settingsFiles.add(params.getExtras().getString(TABLE_SYSTEM, "")); - settingsFiles.add(params.getExtras().getString(TABLE_SECURE, "")); - settingsFiles.add(params.getExtras().getString(TABLE_SSAID, "")); - settingsFiles.add(params.getExtras().getString(TABLE_CONFIG, "")); - SettingsProvider.writeFallBackSettingsFiles(settingsFiles); - return true; - default: - return false; + if (params.getJobId() != WRITE_FALLBACK_SETTINGS_FILES_JOB_ID) { + return false; } + final List settingsFiles = new ArrayList<>(); + settingsFiles.add(params.getExtras().getString(TABLE_GLOBAL, "")); + settingsFiles.add(params.getExtras().getString(TABLE_SYSTEM, "")); + settingsFiles.add(params.getExtras().getString(TABLE_SECURE, "")); + settingsFiles.add(params.getExtras().getString(TABLE_SSAID, "")); + settingsFiles.add(params.getExtras().getString(TABLE_CONFIG, "")); + SettingsProvider.writeFallBackSettingsFiles(settingsFiles); + return false; } @Override -- GitLab From 170c118b8105c9bb55d801e2eb4e6c12a89ac80c Mon Sep 17 00:00:00 2001 From: Jaewan Kim Date: Thu, 20 Aug 2020 16:58:32 +0900 Subject: [PATCH 259/536] DO NOT MERGE: Fix incorrect use of UserHandle#getUserHandleForUid(int uid) Two issues were mixed here. issue 1) User ID was used when UID was necessary. issue 2) Caller UID was used when checking target UID. Note that this bug would affect multi-user environment. (Cherry-picked from c8fc993b4260fbd10bfa9e3d12c4616ac0d5c6c9) Bug: 162548695 Test: Build and run CTS Change-Id: I83909b4a6c82af805a26848fe4a0189c579ddf0d --- .../server/media/MediaSessionService.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 9b356f0e8eef..803eb862e0f1 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -1937,7 +1937,8 @@ public class MediaSessionService extends SystemService implements Monitor { // Context#getPackageName() for getting package name that matches with the PID/UID, // but it doesn't tell which package has created the MediaController, so useless. return hasMediaControlPermission(controllerPid, controllerUid) - || hasEnabledNotificationListener(userId, controllerPackageName); + || hasEnabledNotificationListener( + userId, controllerPackageName, controllerUid); } finally { Binder.restoreCallingIdentity(token); } @@ -2001,29 +2002,29 @@ public class MediaSessionService extends SystemService implements Monitor { return resolvedUserId; } - private boolean hasEnabledNotificationListener(int resolvedUserId, String packageName) - throws RemoteException { - // You may not access another user's content as an enabled listener. - final int userId = UserHandle.getUserId(resolvedUserId); - if (resolvedUserId != userId) { + private boolean hasEnabledNotificationListener(int callingUserId, + String controllerPackageName, int controllerUid) throws RemoteException { + int controllerUserId = UserHandle.getUserHandleForUid(controllerUid).getIdentifier(); + if (callingUserId != controllerUserId) { + // Enabled notification listener only works within the same user. return false; } // TODO(jaewan): (Post-P) Propose NotificationManager#hasEnabledNotificationListener( // String pkgName) to notification team for optimization final List enabledNotificationListeners = - mNotificationManager.getEnabledNotificationListeners(userId); + mNotificationManager.getEnabledNotificationListeners(controllerUserId); if (enabledNotificationListeners != null) { for (int i = 0; i < enabledNotificationListeners.size(); i++) { - if (TextUtils.equals(packageName, + if (TextUtils.equals(controllerPackageName, enabledNotificationListeners.get(i).getPackageName())) { return true; } } } if (DEBUG) { - Log.d(TAG, packageName + " (uid=" + resolvedUserId + ") doesn't have an enabled " - + "notification listener"); + Log.d(TAG, controllerPackageName + " (uid=" + controllerUid + + ") doesn't have an enabled notification listener"); } return false; } -- GitLab From aa76a82dc30e16a9910f26b61b1eac0468fdef12 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 20 Aug 2020 13:41:03 +0000 Subject: [PATCH 260/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ifb9acb8e979f4cd7d7e5a2f15ace16e6193a2ef3 --- core/res/res/values-ar/strings.xml | 6 +++--- core/res/res/values-in/strings.xml | 2 +- core/res/res/values-mk/strings.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index cc4eb5a7fda7..6978a9aefb17 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -513,9 +513,9 @@ "‏للسماح للتطبيق بتلقّي الحِزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام جهاز Android TV فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق ما يتم استهلاكه في وضع البث غير المتعدد." "‏للسماح للتطبيق بتلقي الحزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام هاتفك فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق وضع البث غير المتعدد." "الدخول إلى إعدادات بلوتوث" - "للسماح للتطبيق بتهيئة لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها." + "للسماح للتطبيق بإعداد لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها." "‏للسماح للتطبيق بضبط البلوتوث على جهاز Android TV واكتشاف الأجهزة البعيدة والاقتران بها." - "للسماح للتطبيق بتهيئة هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها." + "للسماح للتطبيق بإعداد هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها." "‏الاتصال بـشبكة WiMAX وقطع الاتصال بها" "‏للسماح للتطبيق بتحديد ما إذا تم تفعيل WiMAX وتحديد معلومات حول أي شبكات WiMAX متصلة." "‏تغيير حالة WiMAX" @@ -1409,7 +1409,7 @@ "اختيار أسلوب الإدخال" "استمرار عرضها على الشاشة أثناء نشاط لوحة المفاتيح الفعلية" "إظهار لوحة المفاتيح الافتراضية" - "تهيئة لوحة المفاتيح الفعلية" + "إعداد لوحة المفاتيح الفعلية" "انقر لاختيار لغة وتنسيق" " أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي" " 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي" diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 5669c412b0b1..cac9168e2a2c 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -942,7 +942,7 @@ "Kode pos" "Negara Bagian" "Kode pos" - "Wilayah" + "County" "Pulau" "Distrik" "Departemen" diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index efedc40f128a..063bbbf0f066 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1773,7 +1773,7 @@ "Обиди се повторно подоцна" "Се прикажува на цел екран" "За да излезете, повлечете одозгора надолу." - "Разбрав" + "Сфатив" "Готово" "Приказ на часови во кружно движење" "Приказ на минути во кружно движење" -- GitLab From 6af009ab20d9b6445785c465a1e7ea88c1f9a259 Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Wed, 19 Aug 2020 13:07:15 -0700 Subject: [PATCH 261/536] DO NOT MERGE: Fix NPE bug in LocationManager Both null and non-null GnssRequest objects may be present in the list of requests to merge. Bug: 165375330 Test: presubmits Change-Id: I13284b1c32f1ad1fce39ad1ca2e4298194197015 --- location/java/android/location/LocationManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 2a2aaea035ff..05a9863cb266 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -3039,7 +3039,7 @@ public class LocationManager { protected GnssRequest merge(@NonNull List requests) { Preconditions.checkArgument(!requests.isEmpty()); for (GnssRequest request : requests) { - if (request.isFullTracking()) { + if (request != null && request.isFullTracking()) { return request; } } -- GitLab From ebceb0dd39aaeb8c6b657db5fbb6928945d86c25 Mon Sep 17 00:00:00 2001 From: Tyler Gunn Date: Wed, 19 Aug 2020 15:41:33 +0000 Subject: [PATCH 262/536] Add default constructor to NR cell classes The default constructor is missing in CellInfoNr and CellIdentityNr classes. All the other CellInfo* and CellIdentity* classes have it. Also, add setCellIdentity(CellIdentityNr) method to CellInfoNr. Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1202369 Bug: 147260058 Test: m Merged-In: I4617272446ffb32d5d33d14d825f4ed919cc1c47 Change-Id: I4617272446ffb32d5d33d14d825f4ed919cc1c47 (cherry picked from commit 23382679eb83c24dddbefbb749bb0db011e85076) --- .../java/android/telephony/CellIdentityNr.java | 12 ++++++++++++ telephony/java/android/telephony/CellInfoNr.java | 14 +++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java index 1794ac5b723a..a8206e69efd2 100644 --- a/telephony/java/android/telephony/CellIdentityNr.java +++ b/telephony/java/android/telephony/CellIdentityNr.java @@ -50,6 +50,18 @@ public final class CellIdentityNr extends CellIdentity { // a list of additional PLMN-IDs reported for this cell private final ArraySet mAdditionalPlmns; + /** @hide */ + public CellIdentityNr() { + super(TAG, CellInfo.TYPE_NR, null, null, null, null); + mNrArfcn = CellInfo.UNAVAILABLE; + mPci = CellInfo.UNAVAILABLE; + mTac = CellInfo.UNAVAILABLE; + mNci = CellInfo.UNAVAILABLE; + mBands = new int[] {}; + mAdditionalPlmns = new ArraySet(); + mGlobalCellId = null; + } + /** * * @param pci Physical Cell Id in range [0, 1007]. diff --git a/telephony/java/android/telephony/CellInfoNr.java b/telephony/java/android/telephony/CellInfoNr.java index a7e79f93ae89..e01e8f0d5b51 100644 --- a/telephony/java/android/telephony/CellInfoNr.java +++ b/telephony/java/android/telephony/CellInfoNr.java @@ -29,9 +29,16 @@ import java.util.Objects; public final class CellInfoNr extends CellInfo { private static final String TAG = "CellInfoNr"; - private final CellIdentityNr mCellIdentity; + private CellIdentityNr mCellIdentity; private final CellSignalStrengthNr mCellSignalStrength; + /** @hide */ + public CellInfoNr() { + super(); + mCellIdentity = new CellIdentityNr(); + mCellSignalStrength = new CellSignalStrengthNr(); + } + private CellInfoNr(Parcel in) { super(in); mCellIdentity = CellIdentityNr.CREATOR.createFromParcel(in); @@ -71,6 +78,11 @@ public final class CellInfoNr extends CellInfo { return mCellIdentity; } + /** @hide */ + public void setCellIdentity(CellIdentityNr cid) { + mCellIdentity = cid; + } + /** * @return a {@link CellSignalStrengthNr} instance. */ -- GitLab From e69b8a9006309cbdafc78dd00f0c1ff4430c7f9b Mon Sep 17 00:00:00 2001 From: Kevin Hufnagle Date: Thu, 20 Aug 2020 18:48:11 +0000 Subject: [PATCH 263/536] docs: Fix note about new intent action changes coming with Android 11. Bug: 155091482 Change-Id: I3dfeb333cbe95880142ed97d0d50fd9f85c52f50 Test: Documentation changes - no test necessary --- .../java/android/speech/tts/TextToSpeech.java | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java index 408e8504f408..2b8649f414d8 100644 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -62,17 +62,17 @@ import java.util.Set; * to release the native resources used by the TextToSpeech engine. * * Apps targeting Android 11 that use text-to-speech should declare {@link - * TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} in the elements of their + * TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} in the {@code queries} elements of their * manifest: * - * - * + *

      + * <queries>
        *   ...
      - *  
      - *      
      - *  
      - * 
      - * 
      + *  <intent>
      + *      <action android:name="android.intent.action.TTS_SERVICE" />
      + *  </intent>
      + * </queries>
      + * 
      */ public class TextToSpeech { @@ -254,18 +254,17 @@ public class TextToSpeech { *
    * * Apps targeting Android 11 that use text-to-speech should declare {@link - * #INTENT_ACTION_TTS_SERVICE} in the elements of their + * TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} in the {@code queries} elements of their * manifest: * - * - * + *
    +     * <queries>
          *   ...
    -     *  
    -     *      
    -     *  
    -     * 
    -     * 
    -
    +     *  <intent>
    +     *      <action android:name="android.intent.action.TTS_SERVICE" />
    +     *  </intent>
    +     * </queries>
    +     * 
    */ public class Engine { -- GitLab From 6fcdb6bf9e396f89cd497ee82811dbef6179caba Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Tue, 18 Aug 2020 16:51:36 -0400 Subject: [PATCH 264/536] Remove delete action from notification Fixes: 153621404 Test: manual Change-Id: I1c6046a84d15719c5bad8a840037fa08be05fe65 Merged-In: I1c6046a84d15719c5bad8a840037fa08be05fe65 (cherry picked from commit 1700fdca78c790a11de84d9c93b5f7131c99ab14) --- packages/SystemUI/res/values/strings.xml | 4 --- .../screenrecord/RecordingService.java | 35 ------------------- 2 files changed, 39 deletions(-) diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index f875ecb9354e..38501eb8da3d 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -278,14 +278,10 @@ Cancel Share - - Delete Screen recording canceled Screen recording saved, tap to view - - Screen recording deleted Error deleting screen recording diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java index 476ec798a35f..acc7f81eb722 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java @@ -21,7 +21,6 @@ import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.res.Resources; @@ -69,7 +68,6 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis private static final String ACTION_STOP_NOTIF = "com.android.systemui.screenrecord.STOP_FROM_NOTIF"; private static final String ACTION_SHARE = "com.android.systemui.screenrecord.SHARE"; - private static final String ACTION_DELETE = "com.android.systemui.screenrecord.DELETE"; private final RecordingController mController; @@ -181,23 +179,6 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis startActivity(Intent.createChooser(shareIntent, shareLabel) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); break; - case ACTION_DELETE: - // Close quick shade - sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); - - ContentResolver resolver = getContentResolver(); - Uri uri = Uri.parse(intent.getStringExtra(EXTRA_PATH)); - resolver.delete(uri, null, null); - - Toast.makeText( - this, - R.string.screenrecord_delete_description, - Toast.LENGTH_LONG).show(); - - // Remove notification - mNotificationManager.cancelAsUser(null, NOTIFICATION_VIEW_ID, currentUser); - Log.d(TAG, "Deleted recording " + uri); - break; } return Service.START_STICKY; } @@ -307,16 +288,6 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE)) .build(); - Notification.Action deleteAction = new Notification.Action.Builder( - Icon.createWithResource(this, R.drawable.ic_screenrecord), - getResources().getString(R.string.screenrecord_delete_label), - PendingIntent.getService( - this, - REQUEST_CODE, - getDeleteIntent(this, uri.toString()), - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE)) - .build(); - Bundle extras = new Bundle(); extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, getResources().getString(R.string.screenrecord_name)); @@ -330,7 +301,6 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis viewIntent, PendingIntent.FLAG_IMMUTABLE)) .addAction(shareAction) - .addAction(deleteAction) .setAutoCancel(true) .addExtras(extras); @@ -409,11 +379,6 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis .putExtra(EXTRA_PATH, path); } - private static Intent getDeleteIntent(Context context, String path) { - return new Intent(context, RecordingService.class).setAction(ACTION_DELETE) - .putExtra(EXTRA_PATH, path); - } - @Override public void onInfo(MediaRecorder mr, int what, int extra) { Log.d(TAG, "Media recorder info: " + what); -- GitLab From 252f5173b7f82bba52a6d6345ef1820bfed48092 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Thu, 20 Aug 2020 14:16:19 -0700 Subject: [PATCH 265/536] Do not trigger move animation during PiP transition When PiP is transiting to fullscreen mode, we set the activity windowing mode to fullscreen at the beginning and keep the task windowing mode in pinned mode. The hasMovementAnimation assertion should take that into account. Bug: 164101597 Bug: 159679271 Bug: 164321517 Video: http://rcll/aaaaaabFQoRHlzixHdtY/blXkl5mJF9lDto9RtnYcV2 Test: See video Change-Id: I4d887d8d2f0deab3405fd3dd38b01c3649bb51df --- .../core/java/com/android/server/wm/WindowState.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 11db705f4e04..b53627e6629a 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2051,10 +2051,17 @@ class WindowState extends WindowContainer implements WindowManagerP // animating... let's do something. final int left = mWindowFrames.mFrame.left; final int top = mWindowFrames.mFrame.top; + + // During the transition from pip to fullscreen, the activity windowing mode is set to + // fullscreen at the beginning while the task is kept in pinned mode. Skip the move + // animation in such case since the transition is handled in SysUI. + final boolean hasMovementAnimation = getTask() == null + ? getWindowConfiguration().hasMovementAnimations() + : getTask().getWindowConfiguration().hasMovementAnimations(); if (mToken.okToAnimate() && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0 && !isDragResizing() - && getWindowConfiguration().hasMovementAnimations() + && hasMovementAnimation && !mWinAnimator.mLastHidden && !mSeamlesslyRotated) { startMoveAnimation(left, top); -- GitLab From 88786f90f2ba04f87a7bff3b309b582a88ae25c0 Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Fri, 31 Jul 2020 14:38:37 -0700 Subject: [PATCH 266/536] Reduce RM createResources lock contention Reduce lock contention for processes that use ResourcesManager#createResources on background threads by preloading the apk assets into a temporary cache while the RM lock is not held. As a result, multiple threads may be performing I/O opening the same apk assets since multiple threads could be preloading the same apk at once. Bug: 111966000 Test: observe significantly less monitor contention with owner bg threads calling android.app.ResourcesManager.createResources Merged-In: Iccf383cb8e1a358af4f71ac242e2216dc5a19ff2 Change-Id: Iccf383cb8e1a358af4f71ac242e2216dc5a19ff2 (cherry picked from commit fb9a011b1db757892c3eae596aecd59cb8fbd604) --- core/java/android/app/ResourcesManager.java | 268 +++++++++++--------- 1 file changed, 146 insertions(+), 122 deletions(-) diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index 747789901b9d..0b278a9f972a 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -39,7 +39,6 @@ import android.os.Trace; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.Log; -import android.util.LruCache; import android.util.Pair; import android.util.Slog; import android.view.Display; @@ -62,7 +61,6 @@ import java.util.List; import java.util.Objects; import java.util.WeakHashMap; import java.util.function.Consumer; -import java.util.function.Predicate; /** @hide */ public class ResourcesManager { @@ -129,17 +127,30 @@ public class ResourcesManager { } } - private static final boolean ENABLE_APK_ASSETS_CACHE = false; - /** - * The ApkAssets we are caching and intend to hold strong references to. + * Loads {@link ApkAssets} and caches them to prevent their garbage collection while the + * instance is alive and reachable. */ - private final LruCache mLoadedApkAssets = - (ENABLE_APK_ASSETS_CACHE) ? new LruCache<>(3) : null; + private class ApkAssetsSupplier { + final ArrayMap mLocalCache = new ArrayMap<>(); + + /** + * Retrieves the {@link ApkAssets} corresponding to the specified key, caches the ApkAssets + * within this instance, and inserts the loaded ApkAssets into the {@link #mCachedApkAssets} + * cache. + */ + ApkAssets load(final ApkKey apkKey) throws IOException { + ApkAssets apkAssets = mLocalCache.get(apkKey); + if (apkAssets == null) { + apkAssets = loadApkAssets(apkKey); + mLocalCache.put(apkKey, apkAssets); + } + return apkAssets; + } + } /** - * The ApkAssets that are being referenced in the wild that we can reuse, even if they aren't - * in our LRU cache. Bonus resources :) + * The ApkAssets that are being referenced in the wild that we can reuse. */ private final ArrayMap> mCachedApkAssets = new ArrayMap<>(); @@ -337,113 +348,116 @@ public class ResourcesManager { return "/data/resource-cache/" + path.substring(1).replace('/', '@') + "@idmap"; } - private @NonNull ApkAssets loadApkAssets(String path, boolean sharedLib, boolean overlay) - throws IOException { - final ApkKey newKey = new ApkKey(path, sharedLib, overlay); - ApkAssets apkAssets = null; - if (mLoadedApkAssets != null) { - apkAssets = mLoadedApkAssets.get(newKey); - if (apkAssets != null && apkAssets.isUpToDate()) { - return apkAssets; - } - } + private @NonNull ApkAssets loadApkAssets(@NonNull final ApkKey key) throws IOException { + ApkAssets apkAssets; // Optimistically check if this ApkAssets exists somewhere else. - final WeakReference apkAssetsRef = mCachedApkAssets.get(newKey); - if (apkAssetsRef != null) { - apkAssets = apkAssetsRef.get(); - if (apkAssets != null && apkAssets.isUpToDate()) { - if (mLoadedApkAssets != null) { - mLoadedApkAssets.put(newKey, apkAssets); + synchronized (this) { + final WeakReference apkAssetsRef = mCachedApkAssets.get(key); + if (apkAssetsRef != null) { + apkAssets = apkAssetsRef.get(); + if (apkAssets != null && apkAssets.isUpToDate()) { + return apkAssets; + } else { + // Clean up the reference. + mCachedApkAssets.remove(key); } - - return apkAssets; - } else { - // Clean up the reference. - mCachedApkAssets.remove(newKey); } } // We must load this from disk. - if (overlay) { - apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(path), 0 /*flags*/); + if (key.overlay) { + apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(key.path), + 0 /*flags*/); } else { - apkAssets = ApkAssets.loadFromPath(path, sharedLib ? ApkAssets.PROPERTY_DYNAMIC : 0); + apkAssets = ApkAssets.loadFromPath(key.path, + key.sharedLib ? ApkAssets.PROPERTY_DYNAMIC : 0); } - if (mLoadedApkAssets != null) { - mLoadedApkAssets.put(newKey, apkAssets); + synchronized (this) { + mCachedApkAssets.put(key, new WeakReference<>(apkAssets)); } - mCachedApkAssets.put(newKey, new WeakReference<>(apkAssets)); return apkAssets; } /** - * Creates an AssetManager from the paths within the ResourcesKey. - * - * This can be overridden in tests so as to avoid creating a real AssetManager with - * real APK paths. - * @param key The key containing the resource paths to add to the AssetManager. - * @return a new AssetManager. - */ - @VisibleForTesting - @UnsupportedAppUsage - protected @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key) { - final AssetManager.Builder builder = new AssetManager.Builder(); + * Retrieves a list of apk keys representing the ApkAssets that should be loaded for + * AssetManagers mapped to the {@param key}. + */ + private static @NonNull ArrayList extractApkKeys(@NonNull final ResourcesKey key) { + final ArrayList apkKeys = new ArrayList<>(); // resDir can be null if the 'android' package is creating a new Resources object. // This is fine, since each AssetManager automatically loads the 'android' package // already. if (key.mResDir != null) { - try { - builder.addApkAssets(loadApkAssets(key.mResDir, false /*sharedLib*/, - false /*overlay*/)); - } catch (IOException e) { - Log.e(TAG, "failed to add asset path " + key.mResDir); - return null; - } + apkKeys.add(new ApkKey(key.mResDir, false /*sharedLib*/, false /*overlay*/)); } if (key.mSplitResDirs != null) { for (final String splitResDir : key.mSplitResDirs) { - try { - builder.addApkAssets(loadApkAssets(splitResDir, false /*sharedLib*/, - false /*overlay*/)); - } catch (IOException e) { - Log.e(TAG, "failed to add split asset path " + splitResDir); - return null; - } + apkKeys.add(new ApkKey(splitResDir, false /*sharedLib*/, false /*overlay*/)); } } if (key.mLibDirs != null) { for (final String libDir : key.mLibDirs) { + // Avoid opening files we know do not have resources, like code-only .jar files. if (libDir.endsWith(".apk")) { - // Avoid opening files we know do not have resources, - // like code-only .jar files. - try { - builder.addApkAssets(loadApkAssets(libDir, true /*sharedLib*/, - false /*overlay*/)); - } catch (IOException e) { - Log.w(TAG, "Asset path '" + libDir + - "' does not exist or contains no resources."); - - // continue. - } + apkKeys.add(new ApkKey(libDir, true /*sharedLib*/, false /*overlay*/)); } } } if (key.mOverlayDirs != null) { for (final String idmapPath : key.mOverlayDirs) { - try { - builder.addApkAssets(loadApkAssets(idmapPath, false /*sharedLib*/, - true /*overlay*/)); - } catch (IOException e) { - Log.w(TAG, "failed to add overlay path " + idmapPath); + apkKeys.add(new ApkKey(idmapPath, false /*sharedLib*/, true /*overlay*/)); + } + } + + return apkKeys; + } + + /** + * Creates an AssetManager from the paths within the ResourcesKey. + * + * This can be overridden in tests so as to avoid creating a real AssetManager with + * real APK paths. + * @param key The key containing the resource paths to add to the AssetManager. + * @return a new AssetManager. + */ + @VisibleForTesting + @UnsupportedAppUsage + protected @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key) { + return createAssetManager(key, /* apkSupplier */ null); + } - // continue. + /** + * Variant of {@link #createAssetManager(ResourcesKey)} that attempts to load ApkAssets + * from an {@link ApkAssetsSupplier} if non-null; otherwise ApkAssets are loaded using + * {@link #loadApkAssets(ApkKey)}. + */ + private @Nullable AssetManager createAssetManager(@NonNull final ResourcesKey key, + @Nullable ApkAssetsSupplier apkSupplier) { + final AssetManager.Builder builder = new AssetManager.Builder(); + + final ArrayList apkKeys = extractApkKeys(key); + for (int i = 0, n = apkKeys.size(); i < n; i++) { + final ApkKey apkKey = apkKeys.get(i); + try { + builder.addApkAssets( + (apkSupplier != null) ? apkSupplier.load(apkKey) : loadApkAssets(apkKey)); + } catch (IOException e) { + if (apkKey.overlay) { + Log.w(TAG, String.format("failed to add overlay path '%s'", apkKey.path), e); + } else if (apkKey.sharedLib) { + Log.w(TAG, String.format( + "asset path '%s' does not exist or contains no resources", + apkKey.path), e); + } else { + Log.e(TAG, String.format("failed to add asset path '%s'", apkKey.path), e); + return null; } } } @@ -480,24 +494,6 @@ public class ResourcesManager { pw.println("ResourcesManager:"); pw.increaseIndent(); - if (mLoadedApkAssets != null) { - pw.print("cached apks: total="); - pw.print(mLoadedApkAssets.size()); - pw.print(" created="); - pw.print(mLoadedApkAssets.createCount()); - pw.print(" evicted="); - pw.print(mLoadedApkAssets.evictionCount()); - pw.print(" hit="); - pw.print(mLoadedApkAssets.hitCount()); - pw.print(" miss="); - pw.print(mLoadedApkAssets.missCount()); - pw.print(" max="); - pw.print(mLoadedApkAssets.maxSize()); - } else { - pw.print("cached apks: 0 [cache disabled]"); - } - pw.println(); - pw.print("total apks: "); pw.println(countLiveReferences(mCachedApkAssets.values())); @@ -533,11 +529,12 @@ public class ResourcesManager { return config; } - private @Nullable ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key) { + private @Nullable ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key, + @Nullable ApkAssetsSupplier apkSupplier) { final DisplayAdjustments daj = new DisplayAdjustments(key.mOverrideConfiguration); daj.setCompatibilityInfo(key.mCompatInfo); - final AssetManager assets = createAssetManager(key); + final AssetManager assets = createAssetManager(key, apkSupplier); if (assets == null) { return null; } @@ -575,9 +572,18 @@ public class ResourcesManager { */ private @Nullable ResourcesImpl findOrCreateResourcesImplForKeyLocked( @NonNull ResourcesKey key) { + return findOrCreateResourcesImplForKeyLocked(key, /* apkSupplier */ null); + } + + /** + * Variant of {@link #findOrCreateResourcesImplForKeyLocked(ResourcesKey)} that attempts to + * load ApkAssets from a {@link ApkAssetsSupplier} when creating a new ResourcesImpl. + */ + private @Nullable ResourcesImpl findOrCreateResourcesImplForKeyLocked( + @NonNull ResourcesKey key, @Nullable ApkAssetsSupplier apkSupplier) { ResourcesImpl impl = findResourcesImplForKeyLocked(key); if (impl == null) { - impl = createResourcesImpl(key); + impl = createResourcesImpl(key, apkSupplier); if (impl != null) { mResourceImpls.put(key, new WeakReference<>(impl)); } @@ -766,7 +772,7 @@ public class ResourcesManager { } // Now request an actual Resources object. - return createResources(token, key, classLoader); + return createResources(token, key, classLoader, /* apkSupplier */ null); } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } @@ -809,6 +815,31 @@ public class ResourcesManager { (ref) -> ref == null || deadReferences.contains(ref)); } + /** + * Creates an {@link ApkAssetsSupplier} and loads all the ApkAssets required by the {@param key} + * into the supplier. This should be done while the lock is not held to prevent performing I/O + * while holding the lock. + */ + private @NonNull ApkAssetsSupplier createApkAssetsSupplierNotLocked(@NonNull ResourcesKey key) { + Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, + "ResourcesManager#createApkAssetsSupplierNotLocked"); + try { + final ApkAssetsSupplier supplier = new ApkAssetsSupplier(); + final ArrayList apkKeys = extractApkKeys(key); + for (int i = 0, n = apkKeys.size(); i < n; i++) { + final ApkKey apkKey = apkKeys.get(i); + try { + supplier.load(apkKey); + } catch (IOException e) { + Log.w(TAG, String.format("failed to preload asset path '%s'", apkKey.path), e); + } + } + return supplier; + } finally { + Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); + } + } + /** * Creates a Resources object set with a ResourcesImpl object matching the given key. * @@ -816,12 +847,14 @@ public class ResourcesManager { * @param key The key describing the parameters of the ResourcesImpl object. * @param classLoader The classloader to use for the Resources object. * If null, {@link ClassLoader#getSystemClassLoader()} is used. + * @param apkSupplier The apk assets supplier to use when creating a new ResourcesImpl object. * @return A Resources object that gets updated when * {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)} * is called. */ private @Nullable Resources createResources(@Nullable IBinder activityToken, - @NonNull ResourcesKey key, @NonNull ClassLoader classLoader) { + @NonNull ResourcesKey key, @NonNull ClassLoader classLoader, + @Nullable ApkAssetsSupplier apkSupplier) { synchronized (this) { if (DEBUG) { Throwable here = new Throwable(); @@ -829,7 +862,7 @@ public class ResourcesManager { Slog.w(TAG, "!! Get resources for activity=" + activityToken + " key=" + key, here); } - ResourcesImpl resourcesImpl = findOrCreateResourcesImplForKeyLocked(key); + ResourcesImpl resourcesImpl = findOrCreateResourcesImplForKeyLocked(key, apkSupplier); if (resourcesImpl == null) { return null; } @@ -898,7 +931,10 @@ public class ResourcesManager { rebaseKeyForActivity(activityToken, key); } - return createResources(activityToken, key, classLoader); + // Preload the ApkAssets required by the key to prevent performing heavy I/O while the + // ResourcesManager lock is held. + final ApkAssetsSupplier assetsSupplier = createApkAssetsSupplierNotLocked(key); + return createResources(activityToken, key, classLoader, assetsSupplier); } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } @@ -969,7 +1005,13 @@ public class ResourcesManager { final ResourcesKey newKey = rebaseActivityOverrideConfig(resources, oldConfig, overrideConfig, displayId); if (newKey != null) { - updateActivityResources(resources, newKey, false); + final ResourcesImpl resourcesImpl = + findOrCreateResourcesImplForKeyLocked(newKey); + if (resourcesImpl != null && resourcesImpl != resources.getImpl()) { + // Set the ResourcesImpl, updating it for all users of this Resources + // object. + resources.setImpl(resourcesImpl); + } } } } @@ -1024,24 +1066,6 @@ public class ResourcesManager { return newKey; } - private void updateActivityResources(Resources resources, ResourcesKey newKey, - boolean hasLoader) { - final ResourcesImpl resourcesImpl; - - if (hasLoader) { - // Loaders always get new Impls because they cannot be shared - resourcesImpl = createResourcesImpl(newKey); - } else { - resourcesImpl = findOrCreateResourcesImplForKeyLocked(newKey); - } - - if (resourcesImpl != null && resourcesImpl != resources.getImpl()) { - // Set the ResourcesImpl, updating it for all users of this Resources - // object. - resources.setImpl(resourcesImpl); - } - } - public final boolean applyConfigurationToResources(@NonNull Configuration config, @Nullable CompatibilityInfo compat) { synchronized(this) { -- GitLab From ae90e6c0b23449fb1e791eb16119486993ace5bf Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 21 Aug 2020 01:59:36 +0000 Subject: [PATCH 267/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Id7d0be5ecab5502def60286e7fed6dd247d836dd --- packages/SystemUI/res/values-mk/strings.xml | 2 +- packages/SystemUI/res/values-nl/strings.xml | 2 +- packages/SystemUI/res/values-sq/strings.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 9c78de6219fd..0fde26167d67 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -667,7 +667,7 @@ "Забава за некои, но не за сите" "Адаптерот на УИ на системот ви дава дополнителни начини за дотерување и приспособување на корисничкиот интерфејс на Android. Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост." "Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост." - "Разбрав" + "Сфатив" "Честито! Го додадовте Адаптерот на УИ на системот на Поставки" "Отстрани од поставки" "Да се отстрани Адаптерот на УИ на системот од Поставки и да престанат да се користат сите негови функции?" diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index d5c831cebb23..dfe41df5c340 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -354,7 +354,7 @@ "Audio" "Headset" "Invoer" - "Gehoorapparaten" + "Hoortoestellen" "Inschakelen..." "Helderheid" "Automatisch draaien" diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index a78c31381ad8..1dbf9dea9dd8 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -116,7 +116,7 @@ "Marrja e lejeve dështoi" "Gabim gjatë nisjes së regjistrimit të ekranit" "Opsionet e transferimit të dosjeve të USB-së" - "Lidh si një lexues \"media\" (MTP)" + "Lidh si një luajtës të medias (MTP)" "Montoje si kamerë (PTP)" "Instalo \"Transferimi i skedarëve të Android\" për Mac" "Prapa" -- GitLab From 4cac9f064d373c5e3d17ebb2dd20f035ec8c2cb8 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 20 Aug 2020 22:15:43 -0700 Subject: [PATCH 268/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I3914d55af5616bbae3c8441da1c0e53f3b0583a1 --- core/res/res/values-ar/strings.xml | 6 +++--- core/res/res/values-in/strings.xml | 2 +- core/res/res/values-mk/strings.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 1afef7911112..6d3ac1b5fdb0 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -513,9 +513,9 @@ "‏للسماح للتطبيق بتلقّي الحِزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام جهاز Android TV فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق ما يتم استهلاكه في وضع البث غير المتعدد." "‏للسماح للتطبيق بتلقي الحزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام هاتفك فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق وضع البث غير المتعدد." "الدخول إلى إعدادات بلوتوث" - "للسماح للتطبيق بتهيئة لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها." + "للسماح للتطبيق بإعداد لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها." "‏للسماح للتطبيق بضبط البلوتوث على جهاز Android TV واكتشاف الأجهزة البعيدة والاقتران بها." - "للسماح للتطبيق بتهيئة هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها." + "للسماح للتطبيق بإعداد هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها." "‏الاتصال بـشبكة WiMAX وقطع الاتصال بها" "‏للسماح للتطبيق بتحديد ما إذا تم تفعيل WiMAX وتحديد معلومات حول أي شبكات WiMAX متصلة." "‏تغيير حالة WiMAX" @@ -1409,7 +1409,7 @@ "اختيار أسلوب الإدخال" "استمرار عرضها على الشاشة أثناء نشاط لوحة المفاتيح الفعلية" "إظهار لوحة المفاتيح الافتراضية" - "تهيئة لوحة المفاتيح الفعلية" + "إعداد لوحة المفاتيح الفعلية" "انقر لاختيار لغة وتنسيق" " أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي" " 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي" diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 6a28d0a27d48..20df78f9f1d0 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -942,7 +942,7 @@ "Kode pos" "Negara Bagian" "Kode pos" - "Wilayah" + "County" "Pulau" "Distrik" "Departemen" diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index bca612cf018a..029836d473ce 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1773,7 +1773,7 @@ "Обиди се повторно подоцна" "Се прикажува на цел екран" "За да излезете, повлечете одозгора надолу." - "Разбрав" + "Сфатив" "Готово" "Приказ на часови во кружно движење" "Приказ на минути во кружно движење" -- GitLab From 1a1c93f964a9754c3824a2259872523fe992caf8 Mon Sep 17 00:00:00 2001 From: Ahan Wu Date: Mon, 17 Aug 2020 21:25:46 +0800 Subject: [PATCH 269/536] Handle NPE in LocalImageResolver to avoid crashing systemui ContentResolver#openInputStream may return null, and may lead to systemui keeps crashing, handle null to avoid this case. Bug: 163412636 Test: manually Change-Id: Ie149b75d4445b37afac82c8351a32cb17442936d --- .../internal/widget/LocalImageResolver.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/core/java/com/android/internal/widget/LocalImageResolver.java b/core/java/com/android/internal/widget/LocalImageResolver.java index 2302de2cd058..b4e108faee2d 100644 --- a/core/java/com/android/internal/widget/LocalImageResolver.java +++ b/core/java/com/android/internal/widget/LocalImageResolver.java @@ -23,6 +23,7 @@ import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.util.Log; import java.io.IOException; import java.io.InputStream; @@ -31,6 +32,7 @@ import java.io.InputStream; * A class to extract Bitmaps from a MessagingStyle message. */ public class LocalImageResolver { + private static final String TAG = LocalImageResolver.class.getSimpleName(); private static final int MAX_SAFE_ICON_SIZE_PX = 480; @@ -60,11 +62,18 @@ public class LocalImageResolver { private static BitmapFactory.Options getBoundsOptionsForImage(Uri uri, Context context) throws IOException { - InputStream input = context.getContentResolver().openInputStream(uri); BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options(); - onlyBoundsOptions.inJustDecodeBounds = true; - BitmapFactory.decodeStream(input, null, onlyBoundsOptions); - input.close(); + try (InputStream input = context.getContentResolver().openInputStream(uri)) { + if (input == null) { + throw new IllegalArgumentException(); + } + onlyBoundsOptions.inJustDecodeBounds = true; + BitmapFactory.decodeStream(input, null, onlyBoundsOptions); + } catch (IllegalArgumentException iae) { + onlyBoundsOptions.outWidth = -1; + onlyBoundsOptions.outHeight = -1; + Log.e(TAG, "error loading image", iae); + } return onlyBoundsOptions; } -- GitLab From 106f745c3a13d172c0e4d9935861d060edb4a98f Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Sat, 25 Jul 2020 01:44:51 +0800 Subject: [PATCH 270/536] Remove home snapshot immediately If the size of snapshot is mismatched, the removal of the starting window will be deferred. But if the snapshot target is home, since it is only presented for unlocking, it is better to dismiss it as soon as possible to avoid outdated content from being shown on screen if the windows of home have drawn. Bug: 161530286 Test: Keep home on top and turn off screen with secured lock. Use fingerprint to unlock. If home is drawn fast enough, the previous state won't show on screen (e.g. the time on clock). Change-Id: I103f49eb539f78455ad38f48f9cd853dee51b135 (cherry picked from commit a17c813b4029602fa3f1c2c9baa6455845496106) --- .../com/android/server/wm/TaskSnapshotSurface.java | 14 +++++++++++--- .../android/server/wm/TaskSnapshotSurfaceTest.java | 3 ++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index 448b4aae7a88..6cc0ba5e209c 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.graphics.Color.WHITE; import static android.graphics.Color.alpha; import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; @@ -142,6 +143,7 @@ class TaskSnapshotSurface implements StartingSurface { private final Handler mHandler; private boolean mSizeMismatch; private final Paint mBackgroundPaint = new Paint(); + private final int mActivityType; private final int mStatusBarColor; @VisibleForTesting final SystemBarBackgroundPainter mSystemBarBackgroundPainter; private final int mOrientationOnCreation; @@ -173,6 +175,7 @@ class TaskSnapshotSurface implements StartingSurface { final int windowFlags; final int windowPrivateFlags; final int currentOrientation; + final int activityType; final InsetsState insetsState; synchronized (service.mGlobalLock) { final WindowState mainWindow = activity.findMainWindow(); @@ -241,6 +244,7 @@ class TaskSnapshotSurface implements StartingSurface { taskBounds = new Rect(); task.getBounds(taskBounds); currentOrientation = topFullscreenOpaqueWindow.getConfiguration().orientation; + activityType = activity.getActivityType(); final InsetsPolicy insetsPolicy = topFullscreenOpaqueWindow.getDisplayContent() .getInsetsPolicy(); @@ -261,7 +265,8 @@ class TaskSnapshotSurface implements StartingSurface { } final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, window, surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, sysUiVis, - windowFlags, windowPrivateFlags, taskBounds, currentOrientation, insetsState); + windowFlags, windowPrivateFlags, taskBounds, currentOrientation, activityType, + insetsState); window.setOuter(snapshotSurface); try { session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, -1, @@ -282,7 +287,7 @@ class TaskSnapshotSurface implements StartingSurface { TaskSnapshotSurface(WindowManagerService service, Window window, SurfaceControl surfaceControl, TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, int sysUiVis, int windowFlags, int windowPrivateFlags, Rect taskBounds, - int currentOrientation, InsetsState insetsState) { + int currentOrientation, int activityType, InsetsState insetsState) { mService = service; mSurface = service.mSurfaceFactory.get(); mHandler = new Handler(mService.mH.getLooper()); @@ -298,6 +303,7 @@ class TaskSnapshotSurface implements StartingSurface { windowPrivateFlags, sysUiVis, taskDescription, 1f, insetsState); mStatusBarColor = taskDescription.getStatusBarColor(); mOrientationOnCreation = currentOrientation; + mActivityType = activityType; mTransaction = mService.mTransactionFactory.get(); } @@ -305,7 +311,9 @@ class TaskSnapshotSurface implements StartingSurface { public void remove() { synchronized (mService.mGlobalLock) { final long now = SystemClock.uptimeMillis(); - if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS) { + if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS + // Show the latest content as soon as possible for unlocking to home. + && mActivityType != ACTIVITY_TYPE_HOME) { mHandler.postAtTime(this::remove, mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS); ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Defer removing snapshot surface in %dms", (now - mShownTime)); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java index d6ec78837f7d..1a85f744f44f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; @@ -88,7 +89,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase { 0 /* systemUiVisibility */, false /* isTranslucent */); mSurface = new TaskSnapshotSurface(mWm, new Window(), new SurfaceControl(), snapshot, "Test", createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), sysuiVis, windowFlags, 0, - taskBounds, ORIENTATION_PORTRAIT, new InsetsState()); + taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState()); } private static TaskDescription createTaskDescription(int background, int statusBar, -- GitLab From 9c193197f256612f965e2df221dbec300a83f275 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 21 Aug 2020 05:34:58 -0700 Subject: [PATCH 271/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I2d9f76d3ce0b0c2d831e6529e8c439d68fe41a08 --- packages/PrintSpooler/res/values-fa/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml index 596947dfb6dc..719fc9219450 100644 --- a/packages/PrintSpooler/res/values-fa/strings.xml +++ b/packages/PrintSpooler/res/values-fa/strings.xml @@ -31,7 +31,7 @@ "همه %1$s صفحه" "محدوده %1$s صفحه" "‏‏‎مثلاً ۱—۵،‏۹،۷—۱۰" - "پیش‌نمایش چاپ" + "پیش‌نمای چاپ" "‏نصب نمایشگر PDF برای پیش‌نمایش" "برنامه چاپ خراب شد" "در حال ایجاد کار چاپ" -- GitLab From d93dade83381860e38772595ee4033c764ba29a0 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 21 Aug 2020 07:25:54 -0700 Subject: [PATCH 272/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I9e4b0eaf336bdbd8184bc0afb9ad85080fd74c90 --- packages/SystemUI/res/values-mk/strings.xml | 2 +- packages/SystemUI/res/values-nl/strings.xml | 2 +- packages/SystemUI/res/values-sq/strings.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index b5f64e884b7c..30d1b461038f 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -667,7 +667,7 @@ "Забава за некои, но не за сите" "Адаптерот на УИ на системот ви дава дополнителни начини за дотерување и приспособување на корисничкиот интерфејс на Android. Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост." "Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост." - "Разбрав" + "Сфатив" "Честито! Го додадовте Адаптерот на УИ на системот на Поставки" "Отстрани од поставки" "Да се отстрани Адаптерот на УИ на системот од Поставки и да престанат да се користат сите негови функции?" diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 4e30fc50a52b..20cc8501f315 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -354,7 +354,7 @@ "Audio" "Headset" "Invoer" - "Gehoorapparaten" + "Hoortoestellen" "Inschakelen..." "Helderheid" "Automatisch draaien" diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 104375867706..65c592168bd1 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -116,7 +116,7 @@ "Marrja e lejeve dështoi" "Gabim gjatë nisjes së regjistrimit të ekranit" "Opsionet e transferimit të dosjeve të USB-së" - "Lidh si një lexues \"media\" (MTP)" + "Lidh si një luajtës të medias (MTP)" "Montoje si kamerë (PTP)" "Instalo \"Transferimi i skedarëve të Android\" për Mac" "Prapa" -- GitLab From b0d0d7c46ab0425431912d2e03cc620be657a969 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Tue, 18 Aug 2020 16:44:38 -0700 Subject: [PATCH 273/536] Smooth out IME animation for automotive devices Automotive devices may request the navigation bar to be hidden when the IME shows up (controlled via config_automotiveHideNavBarForKeyboard) in order to maximize the visible screen real estate. When this happens, the IME window should animate from the bottom of the screen to reduce the jank that happens from the lack of synchronization between the bottom system window and the IME window. Bug: 163418214 Test: manual Change-Id: I5d7b03d5c829a2679efdd06fa961d1158494e08f --- .../inputmethodservice/InputMethodService.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index c5a11abe1136..4f0c84e586a2 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1208,15 +1208,19 @@ public class InputMethodService extends AbstractInputMethodService { mWindow.getWindow().getAttributes().setFitInsetsIgnoringVisibility(true); // IME layout should always be inset by navigation bar, no matter its current visibility, - // unless automotive requests it, since automotive may hide the navigation bar. + // unless automotive requests it. Automotive devices may request the navigation bar to be + // hidden when the IME shows up (controlled via config_automotiveHideNavBarForKeyboard) + // in order to maximize the visible screen real estate. When this happens, the IME window + // should animate from the bottom of the screen to reduce the jank that happens from the + // lack of synchronization between the bottom system window and the IME window. + if (mIsAutomotive && mAutomotiveHideNavBarForKeyboard) { + mWindow.getWindow().setDecorFitsSystemWindows(false); + } mWindow.getWindow().getDecorView().setOnApplyWindowInsetsListener( (v, insets) -> v.onApplyWindowInsets( new WindowInsets.Builder(insets).setInsets( navigationBars(), - mIsAutomotive && mAutomotiveHideNavBarForKeyboard - ? android.graphics.Insets.NONE - : insets.getInsetsIgnoringVisibility(navigationBars()) - ) + insets.getInsetsIgnoringVisibility(navigationBars())) .build())); // For ColorView in DecorView to work, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS needs to be set -- GitLab From 0a260fa74677a056511c22bf2072c191e2c8b2ad Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 22 Aug 2020 08:14:36 +0000 Subject: [PATCH 274/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I3ec355b2c117c385f6696e9c6f382d717e0ff27b --- packages/SettingsLib/res/values-fa/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index f3b22d355b77..5fc311af26b2 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -139,7 +139,7 @@ "‏قدرت سیگنال Wi‑Fi کامل است." "شبکه باز" "شبکه ایمن" - "‏سیستم عامل Android" + "‏سیستم‌عامل Android" "برنامه‌های حذف شده" "برنامه‌ها و کاربران حذف شده" "به‌روزرسانی‌های سیستم" -- GitLab From eb07221ebc230aa9e2ce04affacae703fae80280 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 22 Aug 2020 08:48:41 +0000 Subject: [PATCH 275/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Id59359fa20ca11efc8d60138c0216a941837c592 --- packages/SettingsLib/res/values-fa/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index f3b22d355b77..5fc311af26b2 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -139,7 +139,7 @@ "‏قدرت سیگنال Wi‑Fi کامل است." "شبکه باز" "شبکه ایمن" - "‏سیستم عامل Android" + "‏سیستم‌عامل Android" "برنامه‌های حذف شده" "برنامه‌ها و کاربران حذف شده" "به‌روزرسانی‌های سیستم" -- GitLab From 9fd9023250eb1099d42445a117ceba3798766dfd Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 22 Aug 2020 02:33:24 -0700 Subject: [PATCH 276/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I689c1afe36244a8493c913d87fdef58f48265a8b --- .../SearchWidget/res/values-bn/strings.xml | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 packages/SettingsLib/SearchWidget/res/values-bn/strings.xml diff --git a/packages/SettingsLib/SearchWidget/res/values-bn/strings.xml b/packages/SettingsLib/SearchWidget/res/values-bn/strings.xml deleted file mode 100644 index 23f46bf3d655..000000000000 --- a/packages/SettingsLib/SearchWidget/res/values-bn/strings.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - "সেটিংসে সার্চ করুন" - -- GitLab From 1cbc5741db62026b0381814ed60ed8d1eb4fd57e Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 22 Aug 2020 04:02:18 -0700 Subject: [PATCH 277/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I5756e3fc671d313c6c853fcfd8d44617ecadfb1a --- packages/SettingsLib/res/values-fa/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index f3b22d355b77..5fc311af26b2 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -139,7 +139,7 @@ "‏قدرت سیگنال Wi‑Fi کامل است." "شبکه باز" "شبکه ایمن" - "‏سیستم عامل Android" + "‏سیستم‌عامل Android" "برنامه‌های حذف شده" "برنامه‌ها و کاربران حذف شده" "به‌روزرسانی‌های سیستم" -- GitLab From dcb29f69d92fc173fb42211f3ccd6d3a2c958a0c Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 23 Aug 2020 02:42:32 -0700 Subject: [PATCH 278/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I5dfec64eb354ddd9a7dd16510162152490fa6d22 --- packages/PrintSpooler/res/values-uz/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/PrintSpooler/res/values-uz/strings.xml b/packages/PrintSpooler/res/values-uz/strings.xml index d17bce7ae54e..ea0a6ea2f7b8 100644 --- a/packages/PrintSpooler/res/values-uz/strings.xml +++ b/packages/PrintSpooler/res/values-uz/strings.xml @@ -100,7 +100,7 @@ "Tik holat" - "Eniga" + "Yotiq" "Faylga yozib bo‘lmadi" "Xatolik yuz berdi. Qaytadan urining." -- GitLab From 6b0ae2ef20e7360a2d396488bcd782b953dd11aa Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 23 Aug 2020 04:31:03 -0700 Subject: [PATCH 279/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Idf33aff085527105b79a56cb41faea2d4905a7fb --- packages/SystemUI/res/values-hy/strings.xml | 2 +- packages/SystemUI/res/values-uz/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 329679915c4b..6a7d0b28db83 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -337,7 +337,7 @@ "Էկրանը կողպված է ուղղաձիգ դիրքավորմամբ:" "Էկրանն այժմ ավտոմատ կպտտվի:" "Էկրանն այժմ կողպված է հորիզոնական դիրքում:" - "Էկրանն այժմ կողպված է ուղղահայաց դիրքում:" + "Էկրանն այժմ կողպված է ուղղաձիգ դիրքում:" "Dessert Case" "Էկրանապահ" "Ethernet" diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index d48d95b4edf2..18891da5626d 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -362,7 +362,7 @@ "%s rejimi" "Aylanmaydigan qilingan" "Tik holat" - "Eniga" + "Yotiq" "Kiritish usuli" "Joylashuv" "Joylashuvni aniqlash xizmati yoqilmagan" -- GitLab From c229eba162c5b4d20515b15a8b4fc27b069db101 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 23 Aug 2020 15:50:41 +0000 Subject: [PATCH 280/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ia2d827463a54137bce2efdcc89b78b81aade1161 --- packages/SystemUI/res/values-af/strings.xml | 2 -- packages/SystemUI/res/values-am/strings.xml | 2 -- packages/SystemUI/res/values-ar/strings.xml | 2 -- packages/SystemUI/res/values-as/strings.xml | 2 -- packages/SystemUI/res/values-az/strings.xml | 2 -- packages/SystemUI/res/values-b+sr+Latn/strings.xml | 2 -- packages/SystemUI/res/values-be/strings.xml | 2 -- packages/SystemUI/res/values-bg/strings.xml | 2 -- packages/SystemUI/res/values-bn/strings.xml | 2 -- packages/SystemUI/res/values-bs/strings.xml | 2 -- packages/SystemUI/res/values-ca/strings.xml | 2 -- packages/SystemUI/res/values-cs/strings.xml | 2 -- packages/SystemUI/res/values-da/strings.xml | 2 -- packages/SystemUI/res/values-de/strings.xml | 2 -- packages/SystemUI/res/values-el/strings.xml | 2 -- packages/SystemUI/res/values-en-rAU/strings.xml | 2 -- packages/SystemUI/res/values-en-rCA/strings.xml | 2 -- packages/SystemUI/res/values-en-rGB/strings.xml | 2 -- packages/SystemUI/res/values-en-rIN/strings.xml | 2 -- packages/SystemUI/res/values-en-rXC/strings.xml | 2 -- packages/SystemUI/res/values-es-rUS/strings.xml | 2 -- packages/SystemUI/res/values-es/strings.xml | 2 -- packages/SystemUI/res/values-et/strings.xml | 2 -- packages/SystemUI/res/values-eu/strings.xml | 2 -- packages/SystemUI/res/values-fa/strings.xml | 2 -- packages/SystemUI/res/values-fi/strings.xml | 2 -- packages/SystemUI/res/values-fr-rCA/strings.xml | 2 -- packages/SystemUI/res/values-fr/strings.xml | 2 -- packages/SystemUI/res/values-gl/strings.xml | 2 -- packages/SystemUI/res/values-gu/strings.xml | 2 -- packages/SystemUI/res/values-hi/strings.xml | 2 -- packages/SystemUI/res/values-hr/strings.xml | 2 -- packages/SystemUI/res/values-hu/strings.xml | 2 -- packages/SystemUI/res/values-hy/strings.xml | 4 +--- packages/SystemUI/res/values-in/strings.xml | 2 -- packages/SystemUI/res/values-is/strings.xml | 2 -- packages/SystemUI/res/values-it/strings.xml | 2 -- packages/SystemUI/res/values-iw/strings.xml | 2 -- packages/SystemUI/res/values-ja/strings.xml | 2 -- packages/SystemUI/res/values-ka/strings.xml | 2 -- packages/SystemUI/res/values-kk/strings.xml | 2 -- packages/SystemUI/res/values-km/strings.xml | 2 -- packages/SystemUI/res/values-kn/strings.xml | 2 -- packages/SystemUI/res/values-ko/strings.xml | 2 -- packages/SystemUI/res/values-ky/strings.xml | 2 -- packages/SystemUI/res/values-lo/strings.xml | 2 -- packages/SystemUI/res/values-lt/strings.xml | 2 -- packages/SystemUI/res/values-lv/strings.xml | 2 -- packages/SystemUI/res/values-mk/strings.xml | 2 -- packages/SystemUI/res/values-ml/strings.xml | 2 -- packages/SystemUI/res/values-mn/strings.xml | 2 -- packages/SystemUI/res/values-mr/strings.xml | 2 -- packages/SystemUI/res/values-ms/strings.xml | 2 -- packages/SystemUI/res/values-my/strings.xml | 2 -- packages/SystemUI/res/values-nb/strings.xml | 2 -- packages/SystemUI/res/values-ne/strings.xml | 2 -- packages/SystemUI/res/values-nl/strings.xml | 2 -- packages/SystemUI/res/values-or/strings.xml | 2 -- packages/SystemUI/res/values-pa/strings.xml | 2 -- packages/SystemUI/res/values-pl/strings.xml | 2 -- packages/SystemUI/res/values-pt-rBR/strings.xml | 2 -- packages/SystemUI/res/values-pt-rPT/strings.xml | 2 -- packages/SystemUI/res/values-pt/strings.xml | 2 -- packages/SystemUI/res/values-ro/strings.xml | 2 -- packages/SystemUI/res/values-ru/strings.xml | 2 -- packages/SystemUI/res/values-si/strings.xml | 2 -- packages/SystemUI/res/values-sk/strings.xml | 2 -- packages/SystemUI/res/values-sl/strings.xml | 2 -- packages/SystemUI/res/values-sq/strings.xml | 2 -- packages/SystemUI/res/values-sr/strings.xml | 2 -- packages/SystemUI/res/values-sv/strings.xml | 2 -- packages/SystemUI/res/values-sw/strings.xml | 2 -- packages/SystemUI/res/values-ta/strings.xml | 2 -- packages/SystemUI/res/values-te/strings.xml | 2 -- packages/SystemUI/res/values-th/strings.xml | 2 -- packages/SystemUI/res/values-tl/strings.xml | 2 -- packages/SystemUI/res/values-tr/strings.xml | 2 -- packages/SystemUI/res/values-uk/strings.xml | 2 -- packages/SystemUI/res/values-ur/strings.xml | 2 -- packages/SystemUI/res/values-uz/strings.xml | 4 +--- packages/SystemUI/res/values-vi/strings.xml | 2 -- packages/SystemUI/res/values-zh-rCN/strings.xml | 2 -- packages/SystemUI/res/values-zh-rHK/strings.xml | 2 -- packages/SystemUI/res/values-zh-rTW/strings.xml | 2 -- packages/SystemUI/res/values-zu/strings.xml | 2 -- 85 files changed, 2 insertions(+), 172 deletions(-) diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 4fc65dcb4951..51397657f305 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -108,10 +108,8 @@ "Hervat" "Kanselleer" "Deel" - "Vee uit" "Skermopname is gekanselleer" "Skermopname is gestoor, tik om te sien" - "Skermopname is uitgevee" "Kon nie skermopname uitvee nie" "Kon nie toestemmings kry nie" "Kon nie skermopname begin nie" diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 67d37739d43e..dad126cedee3 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -108,10 +108,8 @@ "ከቆመበት ቀጥል" "ይቅር" "አጋራ" - "ሰርዝ" "የማያ ገጽ ቀረጻ ተሰርዟል" "የማያ ገጽ ቀረጻ ተቀምጧል፣ ለመመልከት መታ ያድርጉ" - "የማያ ገጽ ቀረጻ ተሰርዟል" "የማያ ገጽ ቀረጻን መሰረዝ ላይ ስህተት" "ፈቃዶችን ማግኘት አልተቻለም" "የማያ ገጽ ቀረጻን መጀመር ላይ ስህተት" diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index f4adeddafcec..f906cf2a8f93 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -108,10 +108,8 @@ "استئناف" "إلغاء" "مشاركة" - "حذف" "تمّ إلغاء تسجيل الشاشة." "تمّ حفظ تسجيل الشاشة، انقر لعرضه." - "تمّ حذف تسجيل الشاشة." "حدث خطأ أثناء حذف تسجيل الشاشة." "تعذّر الحصول على أذونات." "حدث خطأ في بدء تسجيل الشاشة" diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 8fd20dfc4a8d..9185d95bf9dd 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -108,10 +108,8 @@ "ৰখোৱাৰ পৰা পুনৰ আৰম্ভ কৰক" "বাতিল কৰক" "শ্বেয়াৰ কৰক" - "মচক" "স্ক্রীণ ৰেকৰ্ড কৰাটো বাতিল কৰা হ’ল" "স্ক্রীণ ৰেকৰ্ডিং ছেভ কৰা হ’ল, চাবলৈ টিপক" - "স্ক্রীণ ৰেকৰ্ডিং মচা হ’ল" "স্ক্রীণ ৰেকৰ্ডিং মচি থাকোঁতে কিবা আসোঁৱাহ হ’ল" "অনুমতি পাব পৰা নগ\'ল" "স্ক্রীন ৰেকৰ্ড কৰা আৰম্ভ কৰোঁতে আসোঁৱাহ হৈছে" diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index f45fe634b5a9..32c2e9c2d45e 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -108,10 +108,8 @@ "Davam edin" "Ləğv edin" "Paylaşın" - "Silin" "Ekranın video çəkimi ləğv edildi" "Ekranın video çəkimi yadda saxlanıldı. Baxmaq üçün klikləyin" - "Ekranın video çəkimi silindi" "Ekranın video çəkiminin silinməsi zamanı xəta baş verdi" "İcazələr əldə edilmədi" "Ekranın yazılması ilə bağlı xəta" diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index daac5028f4ca..abb8a3a9122d 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -108,10 +108,8 @@ "Nastavi" "Otkaži" "Deli" - "Izbriši" "Snimanje ekrana je otkazano" "Snimak ekrana je sačuvan, dodirnite da biste pregledali" - "Snimak ekrana je izbrisan" "Došlo je do problema pri brisanju snimka ekrana" "Preuzimanje dozvola nije uspelo" "Greška pri pokretanju snimanja ekrana" diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 50227525fa07..77c1606d4130 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -108,10 +108,8 @@ "Узнавіць" "Скасаваць" "Абагуліць" - "Выдаліць" "Запіс экрана скасаваны" "Запіс экрана захаваны. Націсніце, каб прагледзець" - "Запіс экрана выдалены" "Памылка выдалення запісу экрана" "Не ўдалося атрымаць дазволы" "Памылка пачатку запісу экрана" diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 599cd6007b16..6ff1bfcee29c 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -108,10 +108,8 @@ "Възобновяване" "Отказ" "Споделяне" - "Изтриване" "Записването на екрана е анулирано" "Записът на екрана е запазен. Докоснете, за да го видите" - "Записът на екрана е изтрит" "При изтриването на записа на екрана възникна грешка" "Извличането на разрешенията не бе успешно." "При стартирането на записа на екрана възникна грешка" diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 657022b6a4ae..24805e067d12 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -108,10 +108,8 @@ "আবার চালু করুন" "বাতিল করুন" "শেয়ার করুন" - "মুছুন" "স্ক্রিন রেকর্ডিং বাতিল করা হয়েছে" "স্ক্রিন রেকর্ডিং সেভ করা হয়েছে, দেখতে ট্যাপ করুন" - "স্ক্রিন রেকর্ডিং মুছে ফেলা হয়েছে" "স্ক্রিন রেকডিং মুছে ফেলার সময় সমস্যা হয়েছে" "অনুমতি পাওয়া যায়নি" "স্ক্রিন রেকর্ডিং শুরু করার সময় সমস্যা হয়েছে" diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index a51e79a42da7..830929cf2d00 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -108,10 +108,8 @@ "Nastavi" "Otkaži" "Dijeli" - "Izbriši" "Snimanje ekrana je otkazano" "Snimak ekrana je sačuvan. Dodirnite za prikaz." - "Snimak ekrana je izbrisan" "Greška prilikom brisanja snimka ekrana" "Dobijanje odobrenja nije uspjelo" "Greška pri pokretanju snimanja ekrana" diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 5a70913c4fe3..78ab320b6556 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -108,10 +108,8 @@ "Reprèn" "Cancel·la" "Comparteix" - "Suprimeix" "S\'ha cancel·lat la gravació de la pantalla" "S\'ha desat la gravació de la pantalla; toca per mostrar" - "S\'ha suprimit la gravació de la pantalla" "S\'ha produït un error en suprimir la gravació de la pantalla" "No s\'han pogut obtenir els permisos" "S\'ha produït un error en iniciar la gravació de pantalla" diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index a4e831a256c3..4b1e733751ff 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -108,10 +108,8 @@ "Obnovit" "Zrušit" "Sdílet" - "Smazat" "Nahrávání obrazovky bylo zrušeno" "Záznam obrazovky byl uložen, zobrazíte jej klepnutím" - "Záznam obrazovky byl smazán" "Při mazání záznamu obrazovky došlo k chybě" "Nepodařilo se načíst oprávnění" "Při spouštění nahrávání obrazovky došlo k chybě" diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index c8a61a7051c8..30f92c039377 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -108,10 +108,8 @@ "Genoptag" "Annuller" "Del" - "Slet" "Skærmoptagelsen er annulleret" "Skærmoptagelsen er gemt. Tryk for at se den." - "Skærmoptagelsen er slettet" "Der opstod en fejl ved sletning af skærmoptagelsen" "Det lykkedes ikke et hente tilladelserne" "Skærmoptagelsen kunne ikke startes" diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 787f927d85f0..e4f5ac2f0e25 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -108,10 +108,8 @@ "Fortsetzen" "Abbrechen" "Teilen" - "Löschen" "Bildschirmaufzeichnung abgebrochen" "Bildschirmaufzeichnung gespeichert, zum Ansehen tippen" - "Bildschirmaufzeichnung gelöscht" "Fehler beim Löschen der Bildschirmaufzeichnung" "Berechtigungen nicht erhalten" "Fehler beim Start der Bildschirmaufzeichnung" diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index a2865b182c31..32b335ec480a 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -108,10 +108,8 @@ "Συνέχιση" "Ακύρωση" "Κοινοποίηση" - "Διαγραφή" "Η εγγραφή οθόνης ακυρώθηκε" "Η εγγραφή οθόνης αποθηκεύτηκε. Πατήστε για προβολή." - "Η εγγραφή οθόνης διαγράφηκε" "Παρουσιάστηκε σφάλμα κατά τη διαγραφή της εγγραφής οθόνης" "Η λήψη αδειών απέτυχε" "Σφάλμα κατά την έναρξη της εγγραφής οθόνης" diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index a96f3ef83a32..3a52a7269186 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -108,10 +108,8 @@ "Resume" "Cancel" "Share" - "Delete" "Screen recording cancelled" "Screen recording saved, tap to view" - "Screen recording deleted" "Error deleting screen recording" "Failed to get permissions" "Error starting screen recording" diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 931df88f4cd2..11e0fb9a1852 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -108,10 +108,8 @@ "Resume" "Cancel" "Share" - "Delete" "Screen recording cancelled" "Screen recording saved, tap to view" - "Screen recording deleted" "Error deleting screen recording" "Failed to get permissions" "Error starting screen recording" diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index a96f3ef83a32..3a52a7269186 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -108,10 +108,8 @@ "Resume" "Cancel" "Share" - "Delete" "Screen recording cancelled" "Screen recording saved, tap to view" - "Screen recording deleted" "Error deleting screen recording" "Failed to get permissions" "Error starting screen recording" diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index a96f3ef83a32..3a52a7269186 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -108,10 +108,8 @@ "Resume" "Cancel" "Share" - "Delete" "Screen recording cancelled" "Screen recording saved, tap to view" - "Screen recording deleted" "Error deleting screen recording" "Failed to get permissions" "Error starting screen recording" diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index dbb6eb7ef76b..1a02d596ca14 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -108,10 +108,8 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‏‏‎Resume‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‎Cancel‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎Share‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎Delete‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎Screen recording canceled‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎Screen recording saved, tap to view‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎Screen recording deleted‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎Error deleting screen recording‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎Failed to get permissions‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎Error starting screen recording‎‏‎‎‏‎" diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index de86271dca0e..c27bdd0f2c0c 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -108,10 +108,8 @@ "Reanudar" "Cancelar" "Compartir" - "Borrar" "Se canceló la grabación de pantalla" "Se guardó la grabación de pantalla; presiona para verla" - "Se borró la grabación de pantalla" "Error al borrar la grabación de pantalla" "Error al obtener permisos" "Error al iniciar la grabación de pantalla" diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index ef4e7522002d..3cbf9a174fcf 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -108,10 +108,8 @@ "Seguir" "Cancelar" "Compartir" - "Eliminar" "Se ha cancelado la grabación de la pantalla" "Se ha guardado la grabación de la pantalla; toca para verla" - "Se ha eliminado la grabación de la pantalla" "No se ha podido eliminar la grabación de la pantalla" "No se han podido obtener los permisos" "No se ha podido empezar a grabar la pantalla" diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 9a12f54608b1..ec91fcddf1da 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -108,10 +108,8 @@ "Jätka" "Tühista" "Jaga" - "Kustuta" "Ekraanikuva salvestamine on tühistatud" "Ekraanikuva salvestis on salvestatud, puudutage vaatamiseks" - "Ekraanikuva salvestis on kustutatud" "Viga ekraanikuva salvestise kustutamisel" "Lubade hankimine ebaõnnestus" "Viga ekraanikuva salvestamise alustamisel" diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index d0bf329fa46e..e4b63c8dfd87 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -108,10 +108,8 @@ "Berrekin" "Utzi" "Partekatu" - "Ezabatu" "Utzi zaio pantaila grabatzeari" "Gorde da pantailaren grabaketa; sakatu ikusteko" - "Ezabatu da pantailaren grabaketa" "Errore bat gertatu da pantailaren grabaketa ezabatzean" "Ezin izan dira lortu baimenak" "Errore bat gertatu da pantaila grabatzen hastean" diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 52ba23e17a32..703d5ec070eb 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -108,10 +108,8 @@ "ازسرگیری" "لغو" "هم‌رسانی" - "حذف" "ضبط صفحه‌نمایش لغو شد" "ضبط صفحه‌نمایش ذخیره شد، برای مشاهده ضربه بزنید" - "فایل ضبط صفحه‌نمایش حذف شد" "خطا در حذف فایل ضبط صفحه‌نمایش" "مجوزها دریافت نشدند" "خطا هنگام شروع ضبط صفحه‌نمایش" diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 332c512b1772..72e16203b4c7 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -108,10 +108,8 @@ "Jatka" "Peruuta" "Jaa" - "Poista" "Näytön tallennus peruutettu" "Näyttötallenne tallennettu, katso napauttamalla" - "Näyttötallenne poistettu" "Virhe poistettaessa näyttötallennetta" "Käyttöoikeuksien hakeminen epäonnistui." "Virhe näytön tallennuksen aloituksessa" diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index e1942a4ed98b..91bb30f8dc3d 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -108,10 +108,8 @@ "Reprendre" "Annuler" "Partager" - "Supprimer" "L\'enregistrement d\'écran a été annulé" "L\'enregistrement d\'écran est terminé. Touchez ici pour l\'afficher." - "L\'enregistrement d\'écran a été supprimé" "Une erreur s\'est produite lors de la suppression de l\'enregistrement d\'écran" "Impossible d\'obtenir les autorisations" "Une erreur s\'est produite lors du démarrage de l\'enregistrement d\'écran" diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 7fb9e968ec33..59b9cfc8a949 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -108,10 +108,8 @@ "Reprendre" "Annuler" "Partager" - "Supprimer" "Enregistrement de l\'écran annulé" "Enregistrement de l\'écran enregistré. Appuyez pour afficher" - "Enregistrement de l\'écran supprimé" "Erreur lors de la suppression de l\'enregistrement de l\'écran" "Échec d\'obtention des autorisations" "Erreur lors du démarrage de l\'enregistrement de l\'écran" diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 29be995a6cca..fe50a97943ae 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -108,10 +108,8 @@ "Retomar" "Cancelar" "Compartir" - "Eliminar" "Cancelouse a gravación de pantalla" "Gardouse a gravación de pantalla; toca esta notificación para visualizala" - "Eliminouse a gravación de pantalla" "Produciuse un erro ao eliminar a gravación de pantalla" "Produciuse un erro ao obter os permisos" "Produciuse un erro ao iniciar a gravación da pantalla" diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index bafa026ce4ce..1e58b04c6dfb 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -108,10 +108,8 @@ "ફરી શરૂ કરો" "રદ કરો" "શેર કરો" - "ડિલીટ કરો" "સ્ક્રીન રેકોર્ડિંગ રદ કર્યું" "સ્ક્રીન રેકોર્ડિંગ સાચવ્યું, જોવા માટે ટૅપ કરો" - "સ્ક્રીન રેકોર્ડિંગ ડિલીટ કર્યું" "સ્ક્રીન રેકોર્ડિંગ ડિલીટ કરવામાં ભૂલ આવી" "પરવાનગીઓ મેળવવામાં નિષ્ફળ રહ્યાં" "સ્ક્રીનને રેકૉર્ડ કરવાનું શરૂ કરવામાં ભૂલ" diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index be2cd0bd2218..24f2e6dfdd78 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -108,10 +108,8 @@ "फिर से शुरू करें" "रद्द करें" "शेयर करें" - "मिटाएं" "स्क्रीन रिकॉर्डिंग रद्द कर दी गई" "स्क्रीन रिकॉर्डिंग सेव की गई, देखने के लिए टैप करें" - "स्क्रीन रिकॉर्डिंग मिटा दी गई" "स्क्रीन रिकॉर्डिंग मिटाने में गड़बड़ी हुई" "मंज़ूरी नहीं मिल सकी" "स्क्रीन को रिकॉर्ड करने में गड़बड़ी आ रही है" diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 96880773f19e..3ebaef95112d 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -108,10 +108,8 @@ "Nastavi" "Odustani" "Dijeli" - "Izbriši" "Snimanje zaslona otkazano" "Snimanje zaslona spremljeno je, dodirnite da biste ga pregledali" - "Snimanje zaslona izbrisano" "Pogreška prilikom brisanja snimanja zaslona" "Dohvaćanje dopuštenja nije uspjelo" "Pogreška prilikom pokretanja snimanja zaslona" diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 607c05a13468..f01ac1da64bd 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -108,10 +108,8 @@ "Folytatás" "Mégse" "Megosztás" - "Törlés" "A képernyő rögzítése megszakítva" "Képernyőfelvétel mentve, koppintson a megtekintéshez" - "A képernyőről készült felvétel törölve" "Hiba történt a képernyőről készült felvétel törlésekor" "Nincs engedély" "Hiba a képernyőrögzítés indításakor" diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 56b8d32a1324..65f4325e515e 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -108,10 +108,8 @@ "Վերսկսել" "Չեղարկել" "Կիսվել" - "Ջնջել" "Էկրանի տեսագրումը չեղարկվեց" "Էկրանի տեսագրությունը պահվեց։ Հպեք՝ դիտելու համար:" - "Էկրանի տեսագրությունը ջնջվեց" "Չհաջողվեց ջնջել տեսագրությունը" "Չհաջողվեց ստանալ անհրաժեշտ թույլտվությունները" "Չհաջողվեց սկսել տեսագրումը" @@ -337,7 +335,7 @@ "Էկրանը կողպված է ուղղաձիգ դիրքավորմամբ:" "Էկրանն այժմ ավտոմատ կպտտվի:" "Էկրանն այժմ կողպված է հորիզոնական դիրքում:" - "Էկրանն այժմ կողպված է ուղղահայաց դիրքում:" + "Էկրանն այժմ կողպված է ուղղաձիգ դիրքում:" "Dessert Case" "Էկրանապահ" "Ethernet" diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 9417d483bb62..ea0dd97c5b37 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -108,10 +108,8 @@ "Lanjutkan" "Batal" "Bagikan" - "Hapus" "Rekaman layar dibatalkan" "Rekaman layar disimpan, ketuk untuk melihat" - "Rekaman layar dihapus" "Error saat menghapus rekaman layar" "Gagal mendapatkan izin" "Terjadi error saat memulai perekaman layar" diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 379666906f11..f185c193c952 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -108,10 +108,8 @@ "Halda áfram" "Hætta við" "Deila" - "Eyða" "Hætt við skjáupptöku" "Skjáupptaka vistuð, ýttu til að skoða" - "Skjáupptöku eytt" "Villa við að eyða skjáupptöku" "Ekki tókst að fá heimildir" "Villa við að hefja upptöku skjás" diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 7d7785caa866..6ee4415387b1 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -108,10 +108,8 @@ "Riprendi" "Annulla" "Condividi" - "CANC" "Registrazione dello schermo annullata" "Registrazione dello schermo salvata. Tocca per visualizzarla." - "Registrazione dello schermo eliminata" "Errore durante l\'eliminazione della registrazione dello schermo" "Impossibile ottenere le autorizzazioni" "Errore durante l\'avvio della registrazione dello schermo" diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 778ab9bbb873..29411a6e531f 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -108,10 +108,8 @@ "המשך" "ביטול" "שיתוף" - "מחיקה" "הקלטת המסך בוטלה" "הקלטת המסך נשמרה, יש להקיש כדי להציג" - "הקלטת המסך נמחקה" "שגיאה במחיקת הקלטת המסך" "קבלת ההרשאות נכשלה" "שגיאה בהפעלה של הקלטת המסך" diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index ef80212874d8..a5a92b85630f 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -108,10 +108,8 @@ "再開" "キャンセル" "共有" - "削除" "画面の録画をキャンセルしました" "画面の録画を保存しました。タップで表示できます" - "画面の録画を削除しました" "画面の録画の削除中にエラーが発生しました" "権限を取得できませんでした" "画面の録画中にエラーが発生しました" diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index c2888117ca6b..0fbabcd9b43d 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -108,10 +108,8 @@ "გაგრძელება" "გაუქმება" "გაზიარება" - "წაშლა" "ეკრანის ჩაწერა გაუქმდა" "ეკრანის ჩანაწერი შენახულია, შეეხეთ სანახავად" - "ეკრანის ჩანაწერი წაიშალა" "ეკრანის ჩანაწერის წაშლისას წარმოიშვა შეცდომა" "ნებართვების მიღება ვერ მოხერხდა" "ეკრანის ჩაწერის დაწყებისას წარმოიქმნა შეცდომა" diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 501e92e2de0b..0906c7163d69 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -108,10 +108,8 @@ "Жалғастыру" "Бас тарту" "Бөлісу" - "Жою" "Экранды бейнеге жазудан бас тартылды" "Экран бейне жазбасы сақталды, көру үшін түртіңіз" - "Экран бейне жазбасы жойылды" "Экран бейне жазбасын жою кезінде қате кетті" "Рұқсаттар алынбады" "Экрандағы бейнені жазу кезінде қате шықты." diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 1ddca55e9aa8..5bf8f48104db 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -108,10 +108,8 @@ "បន្ត" "បោះបង់" "ចែករំលែក" - "លុប" "បាន​បោះបង់​ការថត​សកម្មភាព​អេក្រង់" "បានរក្សាទុក​ការថត​សកម្មភាព​អេក្រង់។ សូមចុច​ដើម្បី​មើល" - "បានលុប​ការថត​សកម្មភាព​អេក្រង់" "មានបញ្ហា​ក្នុងការ​លុបការថត​សកម្មភាព​អេក្រង់" "មិនអាច​ទទួលបាន​ការអនុញ្ញាត​ទេ" "មានបញ្ហា​ក្នុងការ​ចាប់ផ្ដើម​ថត​អេក្រង់" diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index c726e00ce131..044ecda5230e 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -108,10 +108,8 @@ "ಮುಂದುವರಿಸಿ" "ರದ್ದುಮಾಡಿ" "ಹಂಚಿಕೊಳ್ಳಿ" - "ಅಳಿಸಿ" "ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ರದ್ದುಮಾಡಲಾಗಿದೆ" "ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ಉಳಿಸಲಾಗಿದೆ, ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ" - "ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸಲಾಗಿದೆ" "ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ" "ಅನುಮತಿಗಳನ್ನು ಪಡೆಯುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ" "ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ" diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 9f8aafdf911f..30ed951177c2 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -108,10 +108,8 @@ "재개" "취소" "공유" - "삭제" "화면 녹화가 취소되었습니다." "화면 녹화본이 저장되었습니다. 확인하려면 탭하세요." - "화면 녹화가 삭제되었습니다." "화면 녹화는 삭제하는 중에 오류가 발생했습니다." "권한을 확보하지 못했습니다." "화면 녹화 시작 중 오류 발생" diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 134d04d3f702..8eab2f19ec17 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -108,10 +108,8 @@ "Улантуу" "Жокко чыгаруу" "Бөлүшүү" - "Ооба" "Экранды жаздыруу жокко чыгарылды" "Экранды жаздыруу сакталды, көрүү үчүн таптап коюңуз" - "Экранды жаздыруу өчүрүлдү" "Экранды жаздырууну өчүрүүдө ката кетти" "Уруксаттар алынбай калды" "Экранды жаздырууну баштоодо ката кетти" diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 862e1458937d..14cd2113da6d 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -108,10 +108,8 @@ "ສືບຕໍ່" "ຍົກເລີກ" "ແບ່ງປັນ" - "ລຶບ" "ຍົກເລີກການບັນທຶກໜ້າຈໍແລ້ວ" "ຈັດເກັບການບັນທຶກໜ້າຈໍ, ແຕະເພື່ອເບິ່ງ" - "ລຶບການບັນທຶກໜ້າຈໍອອກແລ້ວ" "ເກີດຄວາມຜິດພາດໃນການລຶບການບັນທຶກໜ້າຈໍ" "ໂຫຼດສິດອະນຸຍາດບໍ່ສຳເລັດ" "ເກີດຄວາມຜິດພາດໃນການບັນທຶກໜ້າຈໍ" diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index e50ceaf023c3..f8f1dc03905c 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -108,10 +108,8 @@ "Tęsti" "Atšaukti" "Bendrinti" - "Ištrinti" "Ekrano įrašymas atšauktas" "Ekrano įrašas išsaugotas, palieskite ir peržiūrėkite" - "Ekrano įrašas ištrintas" "Ištrinant ekrano įrašą įvyko klaida" "Nepavyko gauti leidimų" "Pradedant ekrano vaizdo įrašymą iškilo problema" diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index d05fa08f1bbe..ea1bc77db679 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -108,10 +108,8 @@ "Atsākt" "Atcelt" "Kopīgot" - "Dzēst" "Ekrāna ierakstīšana ir atcelta." "Ekrāna ieraksts ir saglabāts. Pieskarieties, lai to skatītu." - "Ekrāna ieraksts ir izdzēsts." "Dzēšot ekrāna ierakstu, radās kļūda." "Neizdevās iegūt atļaujas." "Sākot ierakstīt ekrāna saturu, radās kļūda." diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 0fde26167d67..9ec598a7090f 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -108,10 +108,8 @@ "Продолжи" "Откажи" "Сподели" - "Избриши" "Снимањето екран е откажано" "Снимката од екранот е зачувана, допрете за да ја видите" - "Снимката од екранот е избришана" "Грешка при бришењето на снимката од екранот" "Не успеаја да се добијат дозволи" "Грешка при почетокот на снимањето на екранот" diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 9624be9430a2..277169e2f630 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -108,10 +108,8 @@ "പുനരാരംഭിക്കുക" "റദ്ദാക്കുക" "പങ്കിടുക" - "ഇല്ലാതാക്കുക" "സ്ക്രീൻ റെക്കോർഡിംഗ് റദ്ദാക്കി" "സ്ക്രീൻ റെക്കോർഡിംഗ് സംരക്ഷിച്ചു, കാണാൻ ടാപ്പ് ചെയ്യുക" - "സ്ക്രീൻ റെക്കോർഡിംഗ് ഇല്ലാതാക്കി" "സ്ക്രീൻ റെക്കോർഡിംഗ് ഇല്ലാതാക്കുന്നതിൽ പിശക്" "അനുമതികൾ ലഭിച്ചില്ല" "സ്ക്രീൻ റെക്കോർഡിംഗ് ആരംഭിക്കുന്നതിൽ പിശക്" diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 59305949d529..49421f6d3ea8 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -108,10 +108,8 @@ "Үргэлжлүүлэх" "Цуцлах" "Хуваалцах" - "Устгах" "Дэлгэцийн бичлэгийг цуцалсан" "Дэлгэцийн бичлэгийг хадгалсан. Харахын тулд товшино уу" - "Дэлгэцийн бичлэгийг устгасан" "Дэлгэцийн бичлэгийг устгахад алдаа гарлаа" "Зөвшөөрөл авч чадсангүй" "Дэлгэцийн бичлэгийг эхлүүлэхэд алдаа гарлаа" diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 3c87b3136ee8..6bbf77f781f0 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -108,10 +108,8 @@ "पुन्हा सुरू करा" "रद्द करा" "शेअर करा" - "हटवा" "स्क्रीन रेकॉर्डिंग रद्द केले" "स्क्रीन रेकॉर्डिंग सेव्ह केली, पाहण्यासाठी टॅप करा" - "स्क्रीन रेकॉर्डिंग हटवले" "स्क्रीन रेकॉर्डिंग हटवताना एरर आली" "परवानग्या मिळवता आल्या नाहीत" "स्क्रीन रेकॉर्डिंग सुरू करताना एरर आली" diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index f72e3ef75607..789525450c23 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -108,10 +108,8 @@ "Sambung semula" "Batal" "Kongsi" - "Padam" "Rakaman skrin dibatalkan" "Rakaman skrin disimpan, ketik untuk melihat" - "Rakaman skrin dipadamkan" "Ralat semasa memadamkan rakaman skrin" "Gagal mendapatkan kebenaran" "Ralat semasa memulakan rakaman skrin" diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 8f5b47e9fbcf..6d71f1d5fcdd 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -108,10 +108,8 @@ "ဆက်လုပ်ရန်" "မလုပ်တော့" "မျှဝေရန်" - "ဖျက်ရန်" "ဖန်သားပြင် ရိုက်ကူးမှု ပယ်ဖျက်လိုက်ပါပြီ" "ဖန်သားပြင် ရိုက်ကူးမှု သိမ်းထားသည်၊ ကြည့်ရန် တို့ပါ" - "ဖန်သားပြင် ရိုက်ကူးမှု ဖျက်ပြီးပါပြီ" "ဖန်သားပြင် ရိုက်ကူးမှု ဖျက်ရာတွင် အမှားအယွင်းရှိနေသည်" "ခွင့်ပြုချက် မရယူနိုင်ပါ" "ဖန်သားပြင် ရိုက်ကူးမှု စတင်ရာတွင် အမှားအယွင်းရှိနေသည်" diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 56851e421dc7..14de00ae2c85 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -108,10 +108,8 @@ "Gjenoppta" "Avbryt" "Del" - "Slett" "Skjermopptak er avbrutt" "Skjermopptaket er lagret. Trykk for å se det" - "Skjermopptaket er slettet" "Feil ved sletting av skjermopptaket" "Kunne ikke få tillatelser" "Feil ved start av skjermopptaket" diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 61e500afeb4a..7b84193632dc 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -108,10 +108,8 @@ "जारी राख्नुहोस्" "रद्द गर्नुहोस्" "सेयर गर्नुहोस्" - "मेट्नुहोस्" "स्क्रिन रेकर्ड गर्ने कार्य रद्द गरियो" "स्क्रिन रेकर्डिङ सुरक्षित गरियो, हेर्न ट्याप गर्नुहोस्‌" - "स्क्रिनको रेकर्डिङ मेटाइयो" "स्क्रिनको रेकर्डिङ मेट्ने क्रममा त्रुटि" "अनुमति प्राप्त गर्न सकिएन" "स्क्रिन रेकर्ड गर्न थाल्ने क्रममा त्रुटि भयो" diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index dfe41df5c340..679be33181ba 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -108,10 +108,8 @@ "Hervatten" "Annuleren" "Delen" - "Verwijderen" "Schermopname geannuleerd" "Schermopname opgeslagen, tik om te bekijken" - "Schermopname verwijderd" "Fout bij verwijderen van schermopname" "Kan rechten niet ophalen" "Fout bij starten van schermopname" diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 6ab0791ad9c8..8cacc97aa79b 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -108,10 +108,8 @@ "ପୁଣି ଚାଲୁ କରନ୍ତୁ" "ବାତିଲ୍‌ କରନ୍ତୁ" "ସେୟାର୍‍ କରନ୍ତୁ" - "ଡିଲିଟ୍ କରନ୍ତୁ" "ସ୍କ୍ରିନ୍‍ ରେକର୍ଡିଂ ବାତିଲ୍‌ କରିଦିଆଯାଇଛି" "ସ୍କ୍ରିନ୍‍ ରେକର୍ଡିଂ ସେଭ୍‍ ହୋଇଛି, ଦେଖିବାକୁ ଟାପ୍‍ କରନ୍ତୁ" - "ସ୍କ୍ରିନ୍‍ ରେକର୍ଡିଂ ଡିଲିଟ୍‍ କରିଦିଆଯାଇଛି" "ସ୍କ୍ରିନ୍‍ ରେକର୍ଡିଂ ଡିଲିଟ୍‍ କରିବାରେ ତ୍ରୁଟି" "ଅନୁମତି ପାଇବାରେ ଅସଫଳ ହେଲା।" "ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବାରେ ତ୍ରୁଟି" diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 2e481f53963b..a3bc4e0644ae 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -108,10 +108,8 @@ "ਮੁੜ-ਚਾਲੂ ਕਰੋ" "ਰੱਦ ਕਰੋ" "ਸਾਂਝਾ ਕਰੋ" - "ਮਿਟਾਓ" "ਸਕ੍ਰੀਨ ਦੀ ਰਿਕਾਰਡਿੰਗ ਰੱਦ ਕੀਤੀ ਗਈ" "ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਰੱਖਿਅਤ ਕੀਤੀ ਗਈ, ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ" - "ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਮਿਟਾਇਆ ਗਿਆ" "ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਮਿਟਾਉਣ ਦੌਰਾਨ ਗੜਬੜ ਹੋਈ" "ਇਜਾਜ਼ਤਾਂ ਪ੍ਰਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ" "ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋਈ" diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index d946f9a4fbb4..443c8f15f400 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -108,10 +108,8 @@ "Wznów" "Anuluj" "Udostępnij" - "Usuń" "Anulowano nagrywanie zawartości ekranu" "Zapisano nagranie zawartości ekranu – kliknij, by je obejrzeć" - "Usunięto nagranie zawartości ekranu" "Błąd podczas usuwania nagrania zawartości ekranu" "Nie udało się uzyskać uprawnień" "Błąd podczas rozpoczynania rejestracji zawartości ekranu" diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 9c0db7a4e71d..6918ad8ffa09 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -108,10 +108,8 @@ "Retomar" "Cancelar" "Compartilhar" - "Excluir" "Gravação de tela cancelada" "Gravação de tela salva, toque para ver" - "Gravação de tela excluída" "Erro ao excluir a gravação de tela" "Não foi possível acessar as permissões" "Erro ao iniciar a gravação de tela" diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 478d8fdd644c..907199217827 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -108,10 +108,8 @@ "Retomar" "Cancelar" "Partilhar" - "Eliminar" "Gravação de ecrã cancelada." "Gravação de ecrã guardada. Toque para ver." - "Gravação de ecrã eliminada." "Erro ao eliminar a gravação de ecrã." "Falha ao obter as autorizações." "Ocorreu um erro ao iniciar a gravação do ecrã." diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 9c0db7a4e71d..6918ad8ffa09 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -108,10 +108,8 @@ "Retomar" "Cancelar" "Compartilhar" - "Excluir" "Gravação de tela cancelada" "Gravação de tela salva, toque para ver" - "Gravação de tela excluída" "Erro ao excluir a gravação de tela" "Não foi possível acessar as permissões" "Erro ao iniciar a gravação de tela" diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 54d6d5583bc0..12a622c8d90f 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -108,10 +108,8 @@ "Reluați" "Anulați" "Trimiteți" - "Ștergeți" "Înregistrarea ecranului a fost anulată" "Înregistrarea ecranului a fost salvată. Atingeți pentru vizualizare" - "Înregistrarea ecranului a fost ștearsă." "Eroare la ștergerea înregistrării ecranului" "Nu s-au obținut permisiunile" "Eroare la începerea înregistrării ecranului" diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index a9bb44b79a97..117e2b28c95a 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -108,10 +108,8 @@ "Возобновить" "Отмена" "Поделиться" - "Удалить" "Запись видео с экрана отменена" "Запись видео с экрана сохранена. Чтобы открыть ее, нажмите на уведомление." - "Запись видео с экрана удалена" "Не удалось удалить запись видео с экрана" "Не удалось получить необходимые разрешения" "Не удалось начать запись видео с экрана." diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index fe3457b5f45a..2be74df2dc47 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -108,10 +108,8 @@ "නැවත අරඹන්න" "අවලංගු කරන්න" "බෙදා ගන්න" - "මකන්න" "තිර පටිගත කිරීම අවලංගු කරන ලදී" "තිර පටිගත කිරීම සුරකින ලදී, බැලීමට තට්ටු කරන්න" - "තිර පටිගත කිරීම මකන ලදී" "තිර පටිගත කිරීම මැකීමේ දෝෂයකි" "අවසර ලබා ගැනීමට අසමත් විය" "තිර පටිගත කිරීම ආරම්භ කිරීමේ දෝෂයකි" diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index ae6154d8ef9a..001b4740e264 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -108,10 +108,8 @@ "Obnoviť" "Zrušiť" "Zdieľať" - "Odstrániť" "Záznam obrazovky bol zrušený" "Záznam obrazovky bol uložený, zobrazíte ho klepnutím" - "Záznam obrazovky bol odstránený" "Pri odstraňovaní záznamu obrazovky sa vyskytla chyba" "Nepodarilo sa získať povolenia" "Pri spustení nahrávania obrazovky sa vyskytla chyba" diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 8e9544edf7b1..937bb79de3c8 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -108,10 +108,8 @@ "Nadaljuj" "Prekliči" "Deli" - "Izbriši" "Snemanje zaslona je preklicano" "Videoposnetek zaslona je shranjen, dotaknite se za ogled" - "Videoposnetek zaslona je izbrisan" "Napaka pri brisanju videoposnetka zaslona" "Dovoljenj ni bilo mogoče pridobiti" "Napaka pri začenjanju snemanja zaslona" diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 1dbf9dea9dd8..97fb0323c947 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -108,10 +108,8 @@ "Vazhdo" "Anulo" "Ndaj" - "Fshi" "Regjistrimi i ekranit u anulua" "Regjistrimi i ekranit u ruajt, trokit për ta parë" - "Regjistrimi i ekranit u fshi" "Gabim gjatë fshirjes së regjistrimit të ekranit" "Marrja e lejeve dështoi" "Gabim gjatë nisjes së regjistrimit të ekranit" diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index cfb33e89856f..083e45efc026 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -108,10 +108,8 @@ "Настави" "Откажи" "Дели" - "Избриши" "Снимање екрана је отказано" "Снимак екрана је сачуван, додирните да бисте прегледали" - "Снимак екрана је избрисан" "Дошло је до проблема при брисању снимка екрана" "Преузимање дозвола није успело" "Грешка при покретању снимања екрана" diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index baa69b491a07..e2e6b7d31359 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -108,10 +108,8 @@ "Återuppta" "Avbryt" "Dela" - "Radera" "Skärminspelningen har avbrutits" "Skärminspelningen har sparats, tryck här om du vill titta på den" - "Skärminspelningen har raderats" "Det gick inte att radera skärminspelningen" "Behörighet saknas" "Det gick inte att starta skärminspelningen" diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 09c42e771156..0abb58fdd15f 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -108,10 +108,8 @@ "Endelea" "Ghairi" "Shiriki" - "Futa" "Imeghairi mchakato wa kurekodi skrini" "Imehifadhi rekodi ya skrini, gusa ili uangalie" - "Imefuta rekodi ya skrini" "Hitilafu imetokea wakati wa kufuta rekodi ya skrini" "Imeshindwa kupata ruhusa" "Hitilafu imetokea wakati wa kuanza kurekodi skrini" diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 134fc2dcaa7d..f98e103ed9c4 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -108,10 +108,8 @@ "மீண்டும் தொடங்கு" "ரத்துசெய்" "பகிர்" - "நீக்கு" "திரை ரெக்கார்டிங் ரத்துசெய்யப்பட்டது" "திரை ரெக்கார்டிங் சேமிக்கப்பட்டது, பார்க்கத் தட்டவும்" - "திரை ரெக்கார்டிங் நீக்கப்பட்டது" "திரை ரெக்கார்டிங்கை நீக்குவதில் பிழை" "அனுமதிகளைப் பெற இயலவில்லை" "ஸ்கிரீன் ரெக்கார்டிங்கைத் தொடங்குவதில் பிழை" diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index a50399069ca3..c9d211cf2b86 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -108,10 +108,8 @@ "కొనసాగించు" "రద్దు చేయి" "షేర్ చేయి" - "తొలగించు" "స్క్రీన్ రికార్డ్ రద్దు చేయబడింది" "స్క్రీన్ రికార్డింగ్ సేవ్ చేయబడింది, చూడటం కోసం నొక్కండి" - "స్క్రీన్ రికార్డింగ్ తొలగించబడింది" "స్క్రీన్ రికార్డింగ్‌ని తొలగిస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది" "అనుమతులను పొందడం విఫలమైంది" "స్క్రీన్ రికార్డింగ్ ప్రారంభించడంలో ఎర్రర్ ఏర్పడింది" diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 52d99171d654..7705be92c5e0 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -108,10 +108,8 @@ "ทำต่อ" "ยกเลิก" "แชร์" - "ลบ" "ยกเลิกการบันทึกหน้าจอแล้ว" "บันทึกการบันทึกหน้าจอแล้ว แตะเพื่อดู" - "ลบการบันทึกหน้าจอแล้ว" "เกิดข้อผิดพลาดในการลบการบันทึกหน้าจอ" "ขอสิทธิ์ไม่สำเร็จ" "เกิดข้อผิดพลาดขณะเริ่มบันทึกหน้าจอ" diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index b7eca6399b7b..c37c1116de9e 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -108,10 +108,8 @@ "Ituloy" "Kanselahin" "Ibahagi" - "I-delete" "Kinansela ang pag-record ng screen" "Na-save ang pag-record ng screen, i-tap para tingnan" - "Na-delete ang pag-record ng screen" "Error sa pag-delete sa pag-record ng screen" "Hindi nakuha ang mga pahintulot" "Nagkaroon ng error sa pagsisimula ng pag-record ng screen" diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index e5cd3f6b8204..108f00c41be6 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -108,10 +108,8 @@ "Devam ettir" "İptal" "Paylaş" - "Sil" "Ekran kaydı iptal edildi" "Ekran kaydı tamamlandı, görüntülemek için dokunun" - "Ekran kaydı silindi" "Ekran kaydı silinirken hata oluştu" "İzinler alınamadı" "Ekran kaydı başlatılırken hata oluştu" diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 412e5133fdac..90a512f3ecbe 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -108,10 +108,8 @@ "Відновити" "Скасувати" "Поділитися" - "Видалити" "Запис екрана скасовано" "Запис екрана збережено. Натисніть, щоб переглянути" - "Запис екрана видалено" "Не вдалося видалити запис екрана" "Не вдалось отримати дозволи" "Не вдалося почати запис екрана" diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index ab096baeebae..8a69b1cfb3dc 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -108,10 +108,8 @@ "دوبارہ شروع کریں" "منسوخ کریں" "اشتراک کریں" - "حذف کریں" "اسکرین ریکارڈنگ منسوخ ہو گئی" "اسکرین ریکارڈنگ محفوظ ہو گئی، دیکھنے کیلئے تھپتھپائیں" - "اسکرین ریکارڈنگ حذف ہو گئی" "اسکرین ریکارڈنگ کو حذف کرنے میں خرابی" "اجازتیں حاصل کرنے میں ناکامی" "اسکرین ریکارڈنگ شروع کرنے میں خرابی" diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 123e9460a85b..47dd75c55b8d 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -108,10 +108,8 @@ "Davom etish" "Bekor qilish" "Ulashish" - "O‘chirish" "Ekrandan yozib olish bekor qilindi" "Ekrandan yozib olingan video saqlandi. Uni ochish uchun bildirishnomani bosing." - "Ekrandan yozib olingan video o‘chirib tashlandi" "Ekrandan yozib olingan vi olib tashlanmadi" "Zarur ruxsatlar olinmadi" "Ekranni yozib olish boshlanmadi" @@ -362,7 +360,7 @@ "%s rejimi" "Aylanmaydigan qilingan" "Tik holat" - "Eniga" + "Yotiq" "Kiritish usuli" "Joylashuv" "Joylashuvni aniqlash xizmati yoqilmagan" diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 41033e5fc6eb..344e292f1bd5 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -108,10 +108,8 @@ "Tiếp tục" "Hủy" "Chia sẻ" - "Xóa" "Đã hủy bản ghi màn hình" "Đã lưu bản ghi màn hình, nhấn để xem" - "Đã xóa bản ghi màn hình" "Lỗi khi xóa bản ghi màn hình" "Không được cấp đủ quyền" "Lỗi khi bắt đầu ghi màn hình" diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 9b3c55ddf943..2a720d8f715f 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -108,10 +108,8 @@ "继续" "取消" "分享" - "删除" "已取消录制屏幕" "屏幕录制内容已保存,点按即可查看" - "已删除屏幕录制内容" "删除屏幕录制内容时出错" "无法获取权限" "启动屏幕录制时出错" diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index e061aebcafdd..88e3fb7f967b 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -108,10 +108,8 @@ "繼續" "取消" "分享" - "刪除" "已取消錄影畫面" "已儲存錄影畫面,輕按即可查看" - "已刪除錄影畫面" "刪除錄影畫面時發生錯誤" "無法獲得權限" "開始錄影畫面時發生錯誤" diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index a340e37fa2e1..ad5e370b9c66 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -108,10 +108,8 @@ "繼續" "取消" "分享" - "刪除" "已取消錄製螢幕畫面" "已儲存螢幕畫面錄製內容,輕觸即可查看" - "已刪除螢幕畫面錄製內容" "刪除螢幕畫面錄製內容時發生錯誤" "無法取得權限" "開始錄製螢幕畫面時發生錯誤" diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 679659587d6e..7303e142f929 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -108,10 +108,8 @@ "Qalisa kabusha" "Khansela" "Yabelana" - "Susa" "Ukurekhoda isikrini kukhanseliwe" "Ukurekhoda isikrini kulondoloziwe, thepha ukuze ubuke" - "Ukurekhoda isikrini kususiwe" "Iphutha lokususa ukurekhoda isikrini" "Yehlulekile ukuthola izimvume" "Iphutha lokuqala ukurekhoda isikrini" -- GitLab From 174baaccc7ff8a621e10815f69d952375a226b82 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Wed, 12 Aug 2020 17:01:54 +0800 Subject: [PATCH 281/536] [Wi-Fi] Show Pie+x Wi-Fi icon when a connected Wi-Fi is not default route From Android 11, a connected Wi-Fi network may not be default route if rating provider thinks it has bad connection quality. Framework service will keep the Wi-Fi connection but uses other connection as default route. This change shows Pie+x Wi-Fi icon for a connected Wi-Fi network which is not default route. Bug: 163627176 Test: make RunSettingsLibRoboTests ROBOTEST_FILTER=WifiEntryPreferenceTest make RunSettingsLibRoboTests ROBOTEST_FILTER=com.android.settingslib.UtilsTest Change-Id: Ia9c98db59a5eb61ae22a5e9249d1219443876e16 --- .../res/drawable/ic_show_x_wifi_signal_0.xml | 31 ++++++ .../res/drawable/ic_show_x_wifi_signal_1.xml | 27 +++++ .../res/drawable/ic_show_x_wifi_signal_2.xml | 27 +++++ .../res/drawable/ic_show_x_wifi_signal_3.xml | 27 +++++ .../res/drawable/ic_show_x_wifi_signal_4.xml | 27 +++++ .../src/com/android/settingslib/Utils.java | 32 ++++-- .../settingslib/wifi/WifiEntryPreference.java | 20 ++-- .../wifi/WifiEntryPreferenceTest.java | 98 ++++++++++++++++++- 8 files changed, 272 insertions(+), 17 deletions(-) create mode 100644 packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_0.xml create mode 100644 packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_1.xml create mode 100644 packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_2.xml create mode 100644 packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_3.xml create mode 100644 packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_4.xml diff --git a/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_0.xml b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_0.xml new file mode 100644 index 000000000000..16e91903084f --- /dev/null +++ b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_0.xml @@ -0,0 +1,31 @@ + + + + + + + diff --git a/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_1.xml b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_1.xml new file mode 100644 index 000000000000..4c338c968194 --- /dev/null +++ b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_1.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_2.xml b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_2.xml new file mode 100644 index 000000000000..79037dbccf2d --- /dev/null +++ b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_2.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_3.xml b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_3.xml new file mode 100644 index 000000000000..21ad128f81ff --- /dev/null +++ b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_3.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_4.xml b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_4.xml new file mode 100644 index 000000000000..2ec5ba30cdc3 --- /dev/null +++ b/packages/SettingsLib/res/drawable/ic_show_x_wifi_signal_4.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java index a43412e116c8..b2808061586b 100644 --- a/packages/SettingsLib/src/com/android/settingslib/Utils.java +++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java @@ -49,11 +49,19 @@ public class Utils { private static String sSharedSystemSharedLibPackageName; static final int[] WIFI_PIE = { - com.android.internal.R.drawable.ic_wifi_signal_0, - com.android.internal.R.drawable.ic_wifi_signal_1, - com.android.internal.R.drawable.ic_wifi_signal_2, - com.android.internal.R.drawable.ic_wifi_signal_3, - com.android.internal.R.drawable.ic_wifi_signal_4 + com.android.internal.R.drawable.ic_wifi_signal_0, + com.android.internal.R.drawable.ic_wifi_signal_1, + com.android.internal.R.drawable.ic_wifi_signal_2, + com.android.internal.R.drawable.ic_wifi_signal_3, + com.android.internal.R.drawable.ic_wifi_signal_4 + }; + + static final int[] SHOW_X_WIFI_PIE = { + R.drawable.ic_show_x_wifi_signal_0, + R.drawable.ic_show_x_wifi_signal_1, + R.drawable.ic_show_x_wifi_signal_2, + R.drawable.ic_show_x_wifi_signal_3, + R.drawable.ic_show_x_wifi_signal_4 }; public static void updateLocationEnabled(Context context, boolean enabled, int userId, @@ -353,10 +361,22 @@ public class Utils { * @throws IllegalArgumentException if an invalid RSSI level is given. */ public static int getWifiIconResource(int level) { + return getWifiIconResource(false /* showX */, level); + } + + /** + * Returns the Wifi icon resource for a given RSSI level. + * + * @param showX True if a connected Wi-Fi network has the problem which should show Pie+x + * signal icon to users. + * @param level The number of bars to show (0-4) + * @throws IllegalArgumentException if an invalid RSSI level is given. + */ + public static int getWifiIconResource(boolean showX, int level) { if (level < 0 || level >= WIFI_PIE.length) { throw new IllegalArgumentException("No Wifi icon found for level: " + level); } - return WIFI_PIE[level]; + return showX ? SHOW_X_WIFI_PIE[level] : WIFI_PIE[level]; } public static int getDefaultStorageManagerDaysToRetain(Resources resources) { diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java index a53bc9f966d2..bba69f29a290 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java @@ -35,6 +35,7 @@ import androidx.preference.PreferenceViewHolder; import com.android.settingslib.R; import com.android.settingslib.Utils; import com.android.wifitrackerlib.WifiEntry; +import com.android.wifitrackerlib.WifiEntry.ConnectedInfo; /** * Preference to display a WifiEntry in a wifi picker. @@ -64,6 +65,7 @@ public class WifiEntryPreference extends Preference implements WifiEntry.WifiEnt private final IconInjector mIconInjector; private WifiEntry mWifiEntry; private int mLevel = -1; + private boolean mShowX; // Shows the Wi-Fi signl icon of Pie+x when it's true. private CharSequence mContentDescription; private OnButtonClickListener mOnButtonClickListener; @@ -136,9 +138,15 @@ public class WifiEntryPreference extends Preference implements WifiEntry.WifiEnt public void refresh() { setTitle(mWifiEntry.getTitle()); final int level = mWifiEntry.getLevel(); - if (level != mLevel) { + final ConnectedInfo connectedInfo = mWifiEntry.getConnectedInfo(); + boolean showX = false; + if (connectedInfo != null) { + showX = !connectedInfo.isDefaultNetwork || !connectedInfo.isValidated; + } + if (level != mLevel || showX != mShowX) { mLevel = level; - updateIcon(mLevel); + mShowX = showX; + updateIcon(mShowX, mLevel); notifyChanged(); } @@ -184,13 +192,13 @@ public class WifiEntryPreference extends Preference implements WifiEntry.WifiEnt } - private void updateIcon(int level) { + private void updateIcon(boolean showX, int level) { if (level == -1) { setIcon(null); return; } - final Drawable drawable = mIconInjector.getIcon(level); + final Drawable drawable = mIconInjector.getIcon(showX, level); if (drawable != null) { drawable.setTintList(Utils.getColorAttr(getContext(), android.R.attr.colorControlNormal)); @@ -260,8 +268,8 @@ public class WifiEntryPreference extends Preference implements WifiEntry.WifiEnt mContext = context; } - public Drawable getIcon(int level) { - return mContext.getDrawable(Utils.getWifiIconResource(level)); + public Drawable getIcon(boolean showX, int level) { + return mContext.getDrawable(Utils.getWifiIconResource(showX, level)); } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java index 46e699d3bed5..40af7dc797b3 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java @@ -17,6 +17,7 @@ package com.android.settingslib.wifi; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.Context; @@ -29,6 +30,7 @@ import androidx.preference.PreferenceViewHolder; import com.android.settingslib.R; import com.android.wifitrackerlib.WifiEntry; +import com.android.wifitrackerlib.WifiEntry.ConnectedInfo; import org.junit.Before; import org.junit.Test; @@ -62,6 +64,17 @@ public class WifiEntryPreferenceTest { @Mock private Drawable mMockDrawable4; + @Mock + private Drawable mMockShowXDrawable0; + @Mock + private Drawable mMockShowXDrawable1; + @Mock + private Drawable mMockShowXDrawable2; + @Mock + private Drawable mMockShowXDrawable3; + @Mock + private Drawable mMockShowXDrawable4; + private static final String MOCK_TITLE = "title"; private static final String MOCK_SUMMARY = "summary"; private static final String FAKE_URI_STRING = "fakeuri"; @@ -75,11 +88,22 @@ public class WifiEntryPreferenceTest { when(mMockWifiEntry.getTitle()).thenReturn(MOCK_TITLE); when(mMockWifiEntry.getSummary(false /* concise */)).thenReturn(MOCK_SUMMARY); - when(mMockIconInjector.getIcon(0)).thenReturn(mMockDrawable0); - when(mMockIconInjector.getIcon(1)).thenReturn(mMockDrawable1); - when(mMockIconInjector.getIcon(2)).thenReturn(mMockDrawable2); - when(mMockIconInjector.getIcon(3)).thenReturn(mMockDrawable3); - when(mMockIconInjector.getIcon(4)).thenReturn(mMockDrawable4); + when(mMockIconInjector.getIcon(false /* showX */, 0)).thenReturn(mMockDrawable0); + when(mMockIconInjector.getIcon(false /* showX */, 1)).thenReturn(mMockDrawable1); + when(mMockIconInjector.getIcon(false /* showX */, 2)).thenReturn(mMockDrawable2); + when(mMockIconInjector.getIcon(false /* showX */, 3)).thenReturn(mMockDrawable3); + when(mMockIconInjector.getIcon(false /* showX */, 4)).thenReturn(mMockDrawable4); + + when(mMockIconInjector.getIcon(true /* showX */, 0)) + .thenReturn(mMockShowXDrawable0); + when(mMockIconInjector.getIcon(true /* showX */, 1)) + .thenReturn(mMockShowXDrawable1); + when(mMockIconInjector.getIcon(true /* showX */, 2)) + .thenReturn(mMockShowXDrawable2); + when(mMockIconInjector.getIcon(true /* showX */, 3)) + .thenReturn(mMockShowXDrawable3); + when(mMockIconInjector.getIcon(true /* showX */, 4)) + .thenReturn(mMockShowXDrawable4); } @Test @@ -154,6 +178,70 @@ public class WifiEntryPreferenceTest { mMockDrawable2, mMockDrawable3, mMockDrawable4, null); } + @Test + public void levelChanged_notDefaultWifiRefresh_shouldUpdateLevelIcon() { + final List iconList = new ArrayList<>(); + final ConnectedInfo mockConnectedInfo = mock(ConnectedInfo.class); + mockConnectedInfo.isDefaultNetwork = false; + when(mMockWifiEntry.getConnectedInfo()).thenReturn(mockConnectedInfo); + final WifiEntryPreference pref = + new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector); + + when(mMockWifiEntry.getLevel()).thenReturn(0); + pref.refresh(); + iconList.add(pref.getIcon()); + when(mMockWifiEntry.getLevel()).thenReturn(1); + pref.refresh(); + iconList.add(pref.getIcon()); + when(mMockWifiEntry.getLevel()).thenReturn(2); + pref.refresh(); + iconList.add(pref.getIcon()); + when(mMockWifiEntry.getLevel()).thenReturn(3); + pref.refresh(); + iconList.add(pref.getIcon()); + when(mMockWifiEntry.getLevel()).thenReturn(4); + pref.refresh(); + iconList.add(pref.getIcon()); + when(mMockWifiEntry.getLevel()).thenReturn(-1); + pref.refresh(); + iconList.add(pref.getIcon()); + + assertThat(iconList).containsExactly(mMockShowXDrawable0, mMockShowXDrawable1, + mMockShowXDrawable2, mMockShowXDrawable3, mMockShowXDrawable4, null); + } + + @Test + public void levelChanged_notValidatedWifiRefresh_shouldUpdateLevelIcon() { + final List iconList = new ArrayList<>(); + final ConnectedInfo mockConnectedInfo = mock(ConnectedInfo.class); + mockConnectedInfo.isValidated = false; + when(mMockWifiEntry.getConnectedInfo()).thenReturn(mockConnectedInfo); + final WifiEntryPreference pref = + new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector); + + when(mMockWifiEntry.getLevel()).thenReturn(0); + pref.refresh(); + iconList.add(pref.getIcon()); + when(mMockWifiEntry.getLevel()).thenReturn(1); + pref.refresh(); + iconList.add(pref.getIcon()); + when(mMockWifiEntry.getLevel()).thenReturn(2); + pref.refresh(); + iconList.add(pref.getIcon()); + when(mMockWifiEntry.getLevel()).thenReturn(3); + pref.refresh(); + iconList.add(pref.getIcon()); + when(mMockWifiEntry.getLevel()).thenReturn(4); + pref.refresh(); + iconList.add(pref.getIcon()); + when(mMockWifiEntry.getLevel()).thenReturn(-1); + pref.refresh(); + iconList.add(pref.getIcon()); + + assertThat(iconList).containsExactly(mMockShowXDrawable0, mMockShowXDrawable1, + mMockShowXDrawable2, mMockShowXDrawable3, mMockShowXDrawable4, null); + } + @Test public void notNull_whenGetHelpUriString_shouldSetImageButtonVisible() { when(mMockWifiEntry.getHelpUriString()).thenReturn(FAKE_URI_STRING); -- GitLab From a4f73d7f1f73ca45b99bd35dac5ae5726289060f Mon Sep 17 00:00:00 2001 From: Charles Chen Date: Wed, 5 Aug 2020 12:21:35 +0800 Subject: [PATCH 282/536] Respect UI Context for getDisplay Before InputMethodService initializes, InputMethodService#getDisplay will throw UnsupportedOperationException because it doesn't attach to any display. However, it may make developers confuse about why throwing exception for an UI context. This CL workarounds to also check isUiContext flags to make the result of IMS#getDisplay consistent. It should be considered to remove after IMS migrate to WindowContext concept. fixes: 161964893 Test: atest InputMethodServiceTest#testGetDisplayBeforeInitialization Change-Id: Ie0bda707f0196b45a8851f645da7ecab6814bed6 --- core/java/android/app/ContextImpl.java | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index d0fd92294979..3a18b870d7f6 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1914,10 +1914,8 @@ class ContextImpl extends Context { @Override public Object getSystemService(String name) { if (vmIncorrectContextUseEnabled()) { - // We may override this API from outer context. - final boolean isUiContext = isUiContext() || isOuterUiContext(); // Check incorrect Context usage. - if (isUiComponent(name) && !isUiContext) { + if (isUiComponent(name) && !isSelfOrOuterUiContext()) { final String errorMessage = "Tried to access visual service " + SystemServiceRegistry.getSystemServiceClassName(name) + " from a non-visual Context:" + getOuterContext(); @@ -1934,15 +1932,17 @@ class ContextImpl extends Context { return SystemServiceRegistry.getSystemService(this, name); } - private boolean isOuterUiContext() { - return getOuterContext() != null && getOuterContext().isUiContext(); - } - @Override public String getSystemServiceName(Class serviceClass) { return SystemServiceRegistry.getSystemServiceName(serviceClass); } + // TODO(b/149463653): check if we still need this method after migrating IMS to WindowContext. + private boolean isSelfOrOuterUiContext() { + // We may override outer context's isUiContext + return isUiContext() || getOuterContext() != null && getOuterContext().isUiContext(); + } + /** @hide */ @Override public boolean isUiContext() { @@ -2389,7 +2389,7 @@ class ContextImpl extends Context { context.setResources(createResources(mToken, mPackageInfo, mSplitName, displayId, overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo(), mResources.getLoaders())); - context.mIsUiContext = isUiContext() || isOuterUiContext(); + context.mIsUiContext = isSelfOrOuterUiContext(); return context; } @@ -2494,9 +2494,9 @@ class ContextImpl extends Context { @Override public Display getDisplay() { - if (!mIsSystemOrSystemUiContext && !mIsAssociatedWithDisplay) { + if (!mIsSystemOrSystemUiContext && !mIsAssociatedWithDisplay && !isSelfOrOuterUiContext()) { throw new UnsupportedOperationException("Tried to obtain display from a Context not " - + "associated with one. Only visual Contexts (such as Activity or one created " + + "associated with one. Only visual Contexts (such as Activity or one created " + "with Context#createWindowContext) or ones created with " + "Context#createDisplayContext are associated with displays. Other types of " + "Contexts are typically related to background entities and may return an " -- GitLab From 151afab95b583900fc724c187cc1e26fc05fcd4e Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 24 Aug 2020 03:32:36 -0700 Subject: [PATCH 283/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I62484ed4cc2cc5cad6fbffb4bb30c559cc7283a7 --- packages/SettingsLib/res/values-fa/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index f3b22d355b77..5fc311af26b2 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -139,7 +139,7 @@ "‏قدرت سیگنال Wi‑Fi کامل است." "شبکه باز" "شبکه ایمن" - "‏سیستم عامل Android" + "‏سیستم‌عامل Android" "برنامه‌های حذف شده" "برنامه‌ها و کاربران حذف شده" "به‌روزرسانی‌های سیستم" -- GitLab From d631c648b3e6575ccaa22c1e43f57bc2364374fd Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Sat, 15 Aug 2020 12:32:18 +0800 Subject: [PATCH 284/536] Add a SettingsProvider key for Adaptive connectivity Adaptive connectivity is a feature to manage 5G connectivity for better battery life. Bug: 162871294 Test: compile Change-Id: I719e44a29a54ee886e5d3a7180fd3ad9a7dff599 Merged-In: I719e44a29a54ee886e5d3a7180fd3ad9a7dff599 --- core/java/android/provider/Settings.java | 7 +++++++ core/proto/android/app/settings_enums.proto | 5 +++++ core/proto/android/providers/settings/secure.proto | 3 ++- .../android/provider/settings/backup/SecureSettings.java | 3 ++- .../settings/validators/SecureSettingsValidators.java | 1 + .../android/providers/settings/SettingsProtoDumpUtil.java | 3 +++ 6 files changed, 20 insertions(+), 2 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index b5d0b78dcc76..10ac27ca57fd 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -8965,6 +8965,13 @@ public final class Settings { */ public static final int ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW = 0x2; + /** + * Whether the Adaptive connectivity option is enabled. + * + * @hide + */ + public static final String ADAPTIVE_CONNECTIVITY_ENABLED = "adaptive_connectivity_enabled"; + /** * Keys we no longer back up under the current schema, but want to continue to * process when restoring historical backup datasets. diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto index 69b32c264d3d..2cfd6105fcd4 100644 --- a/core/proto/android/app/settings_enums.proto +++ b/core/proto/android/app/settings_enums.proto @@ -2683,4 +2683,9 @@ enum PageId { // CATEGORY: SETTINGS // OS: R MEDIA_CONTROLS_SETTINGS = 1845; + + // OPEN: Settings > Network & internet > Adaptive connectivity + // CATEGORY: SETTINGS + // OS: R QPR + ADAPTIVE_CONNECTIVITY_CATEGORY = 1850; } diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto index fe8a0f183546..acf8cc4944d9 100644 --- a/core/proto/android/providers/settings/secure.proto +++ b/core/proto/android/providers/settings/secure.proto @@ -180,6 +180,7 @@ message SecureSettingsProto { optional SettingProto cmas_additional_broadcast_pkg = 14 [ (android.privacy).dest = DEST_AUTOMATIC ]; repeated SettingProto completed_categories = 15; optional SettingProto connectivity_release_pending_intent_delay_ms = 16 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto adaptive_connectivity_enabled = 84 [ (android.privacy).dest = DEST_AUTOMATIC ]; message Controls { option (android.msg_privacy).dest = DEST_EXPLICIT; @@ -595,5 +596,5 @@ message SecureSettingsProto { // Please insert fields in alphabetical order and group them into messages // if possible (to avoid reaching the method limit). - // Next tag = 82; + // Next tag = 85; } diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index 0977799a6976..efaef2191987 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -167,6 +167,7 @@ public class SecureSettings { Settings.Secure.MEDIA_CONTROLS_RESUME, Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED, Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, - Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS + Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, + Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED }; } diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index c62fdc6a2780..6436355255a8 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -253,5 +253,6 @@ public class SecureSettingsValidators { VALIDATORS.put( Secure.ACCESSIBILITY_BUTTON_TARGETS, ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR); + VALIDATORS.put(Secure.ADAPTIVE_CONNECTIVITY_ENABLED, BOOLEAN_VALIDATOR); } } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index aae72e55b549..845c0a3847c1 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -1979,6 +1979,9 @@ class SettingsProtoDumpUtil { dumpSetting(s, p, Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, SecureSettingsProto.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS); + dumpSetting(s, p, + Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED, + SecureSettingsProto.ADAPTIVE_CONNECTIVITY_ENABLED); final long controlsToken = p.start(SecureSettingsProto.CONTROLS); dumpSetting(s, p, -- GitLab From cd1aec744c5e09313dc412e3fdc4a92fe9e55bbe Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Wed, 5 Aug 2020 10:47:21 -0400 Subject: [PATCH 285/536] Grant URI permissions to NotificationListenerServices when added. Bug: 162233630 Test: android.app.cts.NotificationManagerTest Change-Id: I54b8aa8cf99e0713ee903bee00f5b6361b276608 (cherry picked from commit 41fe38a9e5d995a72f434dfcd9da7430799f92c5) --- .../NotificationManagerService.java | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 8dc7b93302a0..2172aa5d4435 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -9191,6 +9191,7 @@ public class NotificationManagerService extends SystemService { final NotificationRankingUpdate update; synchronized (mNotificationLock) { update = makeRankingUpdateLocked(info); + grantUriPermissionsForActiveNotificationsLocked(info); } try { listener.onListenerConnected(update); @@ -9293,13 +9294,8 @@ public class NotificationManagerService extends SystemService { // This notification became invisible -> remove the old one. if (oldSbnVisible && !sbnVisible) { final StatusBarNotification oldSbnLightClone = oldSbn.cloneLight(); - mHandler.post(new Runnable() { - @Override - public void run() { - notifyRemoved( - info, oldSbnLightClone, update, null, REASON_USER_STOPPED); - } - }); + mHandler.post(() -> notifyRemoved( + info, oldSbnLightClone, update, null, REASON_USER_STOPPED)); continue; } @@ -9309,18 +9305,39 @@ public class NotificationManagerService extends SystemService { updateUriPermissions(r, old, info.component.getPackageName(), targetUserId); final StatusBarNotification sbnToPost = trimCache.ForListener(info); - mHandler.post(new Runnable() { - @Override - public void run() { - notifyPosted(info, sbnToPost, update); - } - }); + mHandler.post(() -> notifyPosted(info, sbnToPost, update)); } } catch (Exception e) { Slog.e(TAG, "Could not notify listeners for " + r.getKey(), e); } } + /** + * Synchronously grant permissions to Uris for all active and visible notifications to the + * NotificationListenerService provided. + */ + @GuardedBy("mNotificationLock") + private void grantUriPermissionsForActiveNotificationsLocked(ManagedServiceInfo info) { + try { + for (final NotificationRecord r : mNotificationList) { + // This notification isn't visible -> ignore. + if (!isVisibleToListener(r.getSbn(), info)) { + continue; + } + // If the notification is hidden, permissions are not required by the listener. + if (r.isHidden() && info.targetSdkVersion < Build.VERSION_CODES.P) { + continue; + } + // Grant access before listener is initialized + final int targetUserId = (info.userid == UserHandle.USER_ALL) + ? UserHandle.USER_SYSTEM : info.userid; + updateUriPermissions(r, null, info.component.getPackageName(), targetUserId); + } + } catch (Exception e) { + Slog.e(TAG, "Could not grant Uri permissions to " + info.component, e); + } + } + /** * asynchronously notify all listeners about a removed notification */ -- GitLab From b28236132d5b3172962851e0f671838192943a73 Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Fri, 7 Aug 2020 13:35:57 -0400 Subject: [PATCH 286/536] Revoke Uri access after a NotificationListener is removed. Fixes: 162233630 Test: android.app.cts.NotificationManagerTest Change-Id: Ib08bfa96b1ff9497251659ff5cc8465fb3da63c0 (cherry picked from commit 55e611dafb5a40f60b7279eea7ab0f049ba81ac9) --- .../NotificationManagerService.java | 81 +++++++++++++------ .../server/uri/UriGrantsManagerInternal.java | 23 +++++- .../server/uri/UriGrantsManagerService.java | 19 ++--- .../server/uri/UriPermissionOwner.java | 38 ++++++--- .../NotificationManagerServiceTest.java | 2 +- 5 files changed, 116 insertions(+), 47 deletions(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 2172aa5d4435..f8d54adbeb5b 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -7733,6 +7733,13 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting void updateUriPermissions(@Nullable NotificationRecord newRecord, @Nullable NotificationRecord oldRecord, String targetPkg, int targetUserId) { + updateUriPermissions(newRecord, oldRecord, targetPkg, targetUserId, false); + } + + @VisibleForTesting + void updateUriPermissions(@Nullable NotificationRecord newRecord, + @Nullable NotificationRecord oldRecord, String targetPkg, int targetUserId, + boolean onlyRevokeCurrentTarget) { final String key = (newRecord != null) ? newRecord.getKey() : oldRecord.getKey(); if (DBG) Slog.d(TAG, key + ": updating permissions"); @@ -7760,7 +7767,9 @@ public class NotificationManagerService extends SystemService { } // If we have no Uris to grant, but an existing owner, go destroy it - if (newUris == null && permissionOwner != null) { + // When revoking permissions of a single listener, destroying the owner will revoke + // permissions of other listeners who need to keep access. + if (newUris == null && permissionOwner != null && !onlyRevokeCurrentTarget) { destroyPermissionOwner(permissionOwner, UserHandle.getUserId(oldRecord.getUid()), key); permissionOwner = null; } @@ -7783,9 +7792,20 @@ public class NotificationManagerService extends SystemService { final Uri uri = oldUris.valueAt(i); if (newUris == null || !newUris.contains(uri)) { if (DBG) Slog.d(TAG, key + ": revoking " + uri); - int userId = ContentProvider.getUserIdFromUri( - uri, UserHandle.getUserId(oldRecord.getUid())); - revokeUriPermission(permissionOwner, uri, userId); + if (onlyRevokeCurrentTarget) { + // We're revoking permission from one listener only; other listeners may + // still need access because the notification may still exist + revokeUriPermission(permissionOwner, uri, + UserHandle.getUserId(oldRecord.getUid()), targetPkg, targetUserId); + } else { + // This is broad to unilaterally revoke permissions to this Uri as granted + // by this notification. But this code-path can only be used when the + // reason for revoking is that the notification posted again without this + // Uri, not when removing an individual listener. + revokeUriPermission(permissionOwner, uri, + UserHandle.getUserId(oldRecord.getUid()), + null, UserHandle.USER_ALL); + } } } } @@ -7814,8 +7834,10 @@ public class NotificationManagerService extends SystemService { } } - private void revokeUriPermission(IBinder owner, Uri uri, int userId) { + private void revokeUriPermission(IBinder owner, Uri uri, int sourceUserId, String targetPkg, + int targetUserId) { if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return; + int userId = ContentProvider.getUserIdFromUri(uri, sourceUserId); final long ident = Binder.clearCallingIdentity(); try { @@ -7823,7 +7845,7 @@ public class NotificationManagerService extends SystemService { owner, ContentProvider.getUriWithoutUserId(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION, - userId); + userId, targetPkg, targetUserId); } finally { Binder.restoreCallingIdentity(ident); } @@ -9191,7 +9213,7 @@ public class NotificationManagerService extends SystemService { final NotificationRankingUpdate update; synchronized (mNotificationLock) { update = makeRankingUpdateLocked(info); - grantUriPermissionsForActiveNotificationsLocked(info); + updateUriPermissionsForActiveNotificationsLocked(info, true); } try { listener.onListenerConnected(update); @@ -9203,6 +9225,7 @@ public class NotificationManagerService extends SystemService { @Override @GuardedBy("mNotificationLock") protected void onServiceRemovedLocked(ManagedServiceInfo removed) { + updateUriPermissionsForActiveNotificationsLocked(removed, false); if (removeDisabledHints(removed)) { updateListenerHintsLocked(); updateEffectsSuppressorLocked(); @@ -9269,8 +9292,7 @@ public class NotificationManagerService extends SystemService { for (final ManagedServiceInfo info : getServices()) { boolean sbnVisible = isVisibleToListener(sbn, info); - boolean oldSbnVisible = oldSbn != null ? isVisibleToListener(oldSbn, info) - : false; + boolean oldSbnVisible = (oldSbn != null) && isVisibleToListener(oldSbn, info); // This notification hasn't been and still isn't visible -> ignore. if (!oldSbnVisible && !sbnVisible) { continue; @@ -9313,28 +9335,42 @@ public class NotificationManagerService extends SystemService { } /** - * Synchronously grant permissions to Uris for all active and visible notifications to the - * NotificationListenerService provided. + * Synchronously grant or revoke permissions to Uris for all active and visible + * notifications to just the NotificationListenerService provided. */ @GuardedBy("mNotificationLock") - private void grantUriPermissionsForActiveNotificationsLocked(ManagedServiceInfo info) { + private void updateUriPermissionsForActiveNotificationsLocked( + ManagedServiceInfo info, boolean grant) { try { for (final NotificationRecord r : mNotificationList) { - // This notification isn't visible -> ignore. - if (!isVisibleToListener(r.getSbn(), info)) { + // When granting permissions, ignore notifications which are invisible. + // When revoking permissions, all notifications are invisible, so process all. + if (grant && !isVisibleToListener(r.getSbn(), info)) { continue; } // If the notification is hidden, permissions are not required by the listener. if (r.isHidden() && info.targetSdkVersion < Build.VERSION_CODES.P) { continue; } - // Grant access before listener is initialized + // Grant or revoke access synchronously final int targetUserId = (info.userid == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : info.userid; - updateUriPermissions(r, null, info.component.getPackageName(), targetUserId); + if (grant) { + // Grant permissions by passing arguments as if the notification is new. + updateUriPermissions(/* newRecord */ r, /* oldRecord */ null, + info.component.getPackageName(), targetUserId); + } else { + // Revoke permissions by passing arguments as if the notification was + // removed, but set `onlyRevokeCurrentTarget` to avoid revoking permissions + // granted to *other* targets by this notification's URIs. + updateUriPermissions(/* newRecord */ null, /* oldRecord */ r, + info.component.getPackageName(), targetUserId, + /* onlyRevokeCurrentTarget */ true); + } } } catch (Exception e) { - Slog.e(TAG, "Could not grant Uri permissions to " + info.component, e); + Slog.e(TAG, "Could not " + (grant ? "grant" : "revoke") + " Uri permissions to " + + info.component, e); } } @@ -9373,18 +9409,11 @@ public class NotificationManagerService extends SystemService { final NotificationStats stats = mAssistants.isServiceTokenValidLocked(info.service) ? notificationStats : null; final NotificationRankingUpdate update = makeRankingUpdateLocked(info); - mHandler.post(new Runnable() { - @Override - public void run() { - notifyRemoved(info, sbnLight, update, stats, reason); - } - }); + mHandler.post(() -> notifyRemoved(info, sbnLight, update, stats, reason)); } // Revoke access after all listeners have been updated - mHandler.post(() -> { - updateUriPermissions(null, r, null, UserHandle.USER_SYSTEM); - }); + mHandler.post(() -> updateUriPermissions(null, r, null, UserHandle.USER_SYSTEM)); } /** diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java b/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java index cdb61995c336..5772dea287fc 100644 --- a/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java +++ b/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java @@ -75,10 +75,31 @@ public interface UriGrantsManagerInternal { void removeUriPermissionsForPackage( String packageName, int userHandle, boolean persistable, boolean targetOnly); /** - * @param uri This uri must NOT contain an embedded userId. + * Remove any {@link UriPermission} associated with the owner whose values match the given + * filtering parameters. + * + * @param token An opaque owner token as returned by {@link #newUriPermissionOwner(String)}. + * @param uri This uri must NOT contain an embedded userId. {@code null} to apply to all Uris. + * @param mode The modes (as a bitmask) to revoke. * @param userId The userId in which the uri is to be resolved. */ void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId); + + /** + * Remove any {@link UriPermission} associated with the owner whose values match the given + * filtering parameters. + * + * @param token An opaque owner token as returned by {@link #newUriPermissionOwner(String)}. + * @param uri This uri must NOT contain an embedded userId. {@code null} to apply to all Uris. + * @param mode The modes (as a bitmask) to revoke. + * @param userId The userId in which the uri is to be resolved. + * @param targetPkg Calling package name to match, or {@code null} to apply to all packages. + * @param targetUserId Calling user to match, or {@link UserHandle#USER_ALL} to apply to all + * users. + */ + void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId, + String targetPkg, int targetUserId); + boolean checkAuthorityGrants( int callingUid, ProviderInfo cpi, int userId, boolean checkUser); void dump(PrintWriter pw, boolean dumpAll, String dumpPackage); diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java index f14c3a53940d..8eefd8fa4a91 100644 --- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java +++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java @@ -51,7 +51,6 @@ import android.app.AppGlobals; import android.app.GrantedUriPermission; import android.app.IUriGrantsManager; import android.content.ClipData; -import android.content.ComponentName; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; @@ -88,11 +87,11 @@ import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.SystemServiceManager; -import libcore.io.IoUtils; - import com.google.android.collect.Lists; import com.google.android.collect.Maps; +import libcore.io.IoUtils; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -1431,16 +1430,18 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub { @Override public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { + revokeUriPermissionFromOwner(token, uri, mode, userId, null, UserHandle.USER_ALL); + } + + @Override + public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId, + String targetPkg, int targetUserId) { final UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); if (owner == null) { throw new IllegalArgumentException("Unknown owner: " + token); } - - if (uri == null) { - owner.removeUriPermissions(mode); - } else { - owner.removeUriPermission(new GrantUri(userId, uri, mode), mode); - } + GrantUri grantUri = uri == null ? null : new GrantUri(userId, uri, mode); + owner.removeUriPermission(grantUri, mode, targetPkg, targetUserId); } @Override diff --git a/services/core/java/com/android/server/uri/UriPermissionOwner.java b/services/core/java/com/android/server/uri/UriPermissionOwner.java index 2b404a43a338..0c263997a8b5 100644 --- a/services/core/java/com/android/server/uri/UriPermissionOwner.java +++ b/services/core/java/com/android/server/uri/UriPermissionOwner.java @@ -21,6 +21,7 @@ import static android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION; import android.os.Binder; import android.os.IBinder; +import android.os.UserHandle; import android.util.ArraySet; import android.util.proto.ProtoOutputStream; @@ -74,30 +75,47 @@ public class UriPermissionOwner { } void removeUriPermission(GrantUri grantUri, int mode) { + removeUriPermission(grantUri, mode, null, UserHandle.USER_ALL); + } + + void removeUriPermission(GrantUri grantUri, int mode, String targetPgk, int targetUserId) { if ((mode & FLAG_GRANT_READ_URI_PERMISSION) != 0 && mReadPerms != null) { Iterator it = mReadPerms.iterator(); while (it.hasNext()) { UriPermission perm = it.next(); - if (grantUri == null || grantUri.equals(perm.uri)) { - perm.removeReadOwner(this); - mService.removeUriPermissionIfNeeded(perm); - it.remove(); + if (grantUri != null && !grantUri.equals(perm.uri)) { + continue; + } + if (targetPgk != null && !targetPgk.equals(perm.targetPkg)) { + continue; } + if (targetUserId != UserHandle.USER_ALL && targetUserId != perm.targetUserId) { + continue; + } + perm.removeReadOwner(this); + mService.removeUriPermissionIfNeeded(perm); + it.remove(); } if (mReadPerms.isEmpty()) { mReadPerms = null; } } - if ((mode & FLAG_GRANT_WRITE_URI_PERMISSION) != 0 - && mWritePerms != null) { + if ((mode & FLAG_GRANT_WRITE_URI_PERMISSION) != 0 && mWritePerms != null) { Iterator it = mWritePerms.iterator(); while (it.hasNext()) { UriPermission perm = it.next(); - if (grantUri == null || grantUri.equals(perm.uri)) { - perm.removeWriteOwner(this); - mService.removeUriPermissionIfNeeded(perm); - it.remove(); + if (grantUri != null && !grantUri.equals(perm.uri)) { + continue; + } + if (targetPgk != null && !targetPgk.equals(perm.targetPkg)) { + continue; + } + if (targetUserId != UserHandle.USER_ALL && targetUserId != perm.targetUserId) { + continue; } + perm.removeWriteOwner(this); + mService.removeUriPermissionIfNeeded(perm); + it.remove(); } if (mWritePerms.isEmpty()) { mWritePerms = null; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 16aa87b3e59c..52e08187b2ca 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -3865,7 +3865,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.updateUriPermissions(recordB, recordA, mContext.getPackageName(), USER_SYSTEM); verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(any(), - eq(message1.getDataUri()), anyInt(), anyInt()); + eq(message1.getDataUri()), anyInt(), anyInt(), eq(null), eq(-1)); // Update back means we grant access to first again reset(mUgm); -- GitLab From 4477d12e0db07bf1517949a63dfb38797a3ccabc Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Wed, 19 Aug 2020 12:57:19 -0400 Subject: [PATCH 287/536] Don't create a file with empty favorites A file could be created with empty favorites, preventing a late restore (from D2D) from overwriting it. Test: atest ControlsFavoritePersistenceWrapperTest Test: manual D2d restore Bug: 165200632 Change-Id: Ia99b8e98e4f62d8d0c7385c820c645f3aaabe6f3 Merged-In: Ia99b8e98e4f62d8d0c7385c820c645f3aaabe6f3 (cherry picked from commit 9c892d30f1b51c45eed2081d23a28b22cd98fb54) --- .../controller/ControlsFavoritePersistenceWrapper.kt | 4 ++++ .../ControlsFavoritePersistenceWrapperTest.kt | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapper.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapper.kt index 1bda841d4a63..d930c98cabe1 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapper.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapper.kt @@ -87,6 +87,10 @@ class ControlsFavoritePersistenceWrapper( * @param list a list of favorite controls. The list will be stored in the same order. */ fun storeFavorites(structures: List) { + if (structures.isEmpty() && !file.exists()) { + // Do not create a new file to store nothing + return + } executor.execute { Log.d(TAG, "Saving data to file: $file") val atomicFile = AtomicFile(file) diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt index 861c6207f5b0..690b9a7248be 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt @@ -25,6 +25,7 @@ import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.time.FakeSystemClock import org.junit.After import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -78,4 +79,15 @@ class ControlsFavoritePersistenceWrapperTest : SysuiTestCase() { assertEquals(list, wrapper.readFavorites()) } + + @Test + fun testSaveEmptyOnNonExistingFile() { + if (file.exists()) { + file.delete() + } + + wrapper.storeFavorites(emptyList()) + + assertFalse(file.exists()) + } } -- GitLab From 68b3c98e14249e375edb4a19fe724359f933c283 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Thu, 20 Aug 2020 17:16:14 +0100 Subject: [PATCH 288/536] AppOpsManager: Add OP_RECORD_AUDIO_HOTWORD Bug: 162547999 Test: make Change-Id: I1d072d93cb2e2b021b58d37d9340f8298acffa1b --- core/java/android/app/AppOpsManager.java | 25 +++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index d13137d4a716..eea5d62298fd 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1139,9 +1139,17 @@ public class AppOpsManager { // TODO: Add as AppProtoEnums public static final int OP_PHONE_CALL_CAMERA = 101; + /** + * Audio is being recorded for hotword detection. + * + * @hide + */ + // TODO: Add as AppProtoEnums + public static final int OP_RECORD_AUDIO_HOTWORD = 102; + /** @hide */ @UnsupportedAppUsage - public static final int _NUM_OP = 102; + public static final int _NUM_OP = 103; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -1472,6 +1480,13 @@ public class AppOpsManager { */ public static final String OPSTR_PHONE_CALL_CAMERA = "android:phone_call_camera"; + /** + * Audio is being recorded for hotword detection. + * + * @hide + */ + public static final String OPSTR_RECORD_AUDIO_HOTWORD = "android:record_audio_hotword"; + /** {@link #sAppOpsToNote} not initialized yet for this op */ private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0; /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */ @@ -1663,6 +1678,7 @@ public class AppOpsManager { OP_NO_ISOLATED_STORAGE, // NO_ISOLATED_STORAGE OP_PHONE_CALL_MICROPHONE, // OP_PHONE_CALL_MICROPHONE OP_PHONE_CALL_CAMERA, // OP_PHONE_CALL_CAMERA + OP_RECORD_AUDIO_HOTWORD, // RECORD_AUDIO_HOTWORD }; /** @@ -1771,6 +1787,7 @@ public class AppOpsManager { OPSTR_NO_ISOLATED_STORAGE, OPSTR_PHONE_CALL_MICROPHONE, OPSTR_PHONE_CALL_CAMERA, + OPSTR_RECORD_AUDIO_HOTWORD, }; /** @@ -1880,6 +1897,7 @@ public class AppOpsManager { "NO_ISOLATED_STORAGE", "PHONE_CALL_MICROPHONE", "PHONE_CALL_CAMERA", + "RECORD_AUDIO_HOTWORD", }; /** @@ -1990,6 +2008,7 @@ public class AppOpsManager { null, // no permission for OP_NO_ISOLATED_STORAGE null, // no permission for OP_PHONE_CALL_MICROPHONE null, // no permission for OP_PHONE_CALL_CAMERA + null, // no permission for OP_RECORD_AUDIO_HOTWORD }; /** @@ -2100,6 +2119,7 @@ public class AppOpsManager { null, // NO_ISOLATED_STORAGE null, // PHONE_CALL_MICROPHONE null, // PHONE_CALL_MICROPHONE + null, // RECORD_AUDIO_HOTWORD }; /** @@ -2209,6 +2229,7 @@ public class AppOpsManager { null, // NO_ISOLATED_STORAGE null, // PHONE_CALL_MICROPHONE null, // PHONE_CALL_CAMERA + null, // RECORD_AUDIO_HOTWORD }; /** @@ -2317,6 +2338,7 @@ public class AppOpsManager { AppOpsManager.MODE_ERRORED, // OP_NO_ISOLATED_STORAGE AppOpsManager.MODE_ALLOWED, // PHONE_CALL_MICROPHONE AppOpsManager.MODE_ALLOWED, // PHONE_CALL_CAMERA + AppOpsManager.MODE_ALLOWED, // OP_RECORD_AUDIO_HOTWORD }; /** @@ -2429,6 +2451,7 @@ public class AppOpsManager { true, // NO_ISOLATED_STORAGE false, // PHONE_CALL_MICROPHONE false, // PHONE_CALL_CAMERA + false, // RECORD_AUDIO_HOTWORD }; /** -- GitLab From 298ab92a0e81ced4e506dab55008a3c54cdfed86 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Mon, 24 Aug 2020 13:53:56 -0700 Subject: [PATCH 289/536] DO NOT MERGE Add unused StatusBar to prevent crashes Bug: 165390412 Test: manual (ensure UnusedStatusBar is used instead of StatusBar) Change-Id: I3c9f48f86a599f950fb4e1268dd4a15468aa5839 --- .../android/systemui/CarSystemUIBinder.java | 9 +- .../android/systemui/CarSystemUIModule.java | 5 + .../car/statusbar/UnusedStatusBar.java | 224 ++++++++++++++ .../car/statusbar/UnusedStatusBarModule.java | 285 ++++++++++++++++++ 4 files changed, 519 insertions(+), 4 deletions(-) create mode 100644 packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBar.java create mode 100644 packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBarModule.java diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java index ccf078b38e0c..b3102e248ab2 100644 --- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java +++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java @@ -21,6 +21,8 @@ import com.android.systemui.bubbles.dagger.BubbleModule; import com.android.systemui.car.navigationbar.CarNavigationBar; import com.android.systemui.car.notification.CarNotificationModule; import com.android.systemui.car.sideloaded.SideLoadedAppController; +import com.android.systemui.car.statusbar.UnusedStatusBar; +import com.android.systemui.car.statusbar.UnusedStatusBarModule; import com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier; import com.android.systemui.car.volume.VolumeUI; import com.android.systemui.car.window.OverlayWindowModule; @@ -34,7 +36,6 @@ import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsModule; import com.android.systemui.shortcut.ShortcutKeyDispatcher; import com.android.systemui.stackdivider.Divider; -import com.android.systemui.statusbar.dagger.StatusBarModule; import com.android.systemui.statusbar.notification.InstantAppNotifier; import com.android.systemui.statusbar.notification.dagger.NotificationsModule; import com.android.systemui.statusbar.phone.StatusBar; @@ -48,9 +49,9 @@ import dagger.multibindings.ClassKey; import dagger.multibindings.IntoMap; /** Binder for car specific {@link SystemUI} modules. */ -@Module(includes = {RecentsModule.class, StatusBarModule.class, NotificationsModule.class, +@Module(includes = {RecentsModule.class, NotificationsModule.class, BubbleModule.class, KeyguardModule.class, OverlayWindowModule.class, - CarNotificationModule.class}) + CarNotificationModule.class, UnusedStatusBarModule.class}) public abstract class CarSystemUIBinder { /** Inject into AuthController. */ @Binds @@ -153,7 +154,7 @@ public abstract class CarSystemUIBinder { @Binds @IntoMap @ClassKey(StatusBar.class) - public abstract SystemUI bindsStatusBar(StatusBar sysui); + public abstract SystemUI bindsStatusBar(UnusedStatusBar sysui); /** Inject into VolumeUI. */ @Binds diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java index cde3699f3084..0e3c7f31886b 100644 --- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java +++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java @@ -30,6 +30,7 @@ import com.android.systemui.car.CarDeviceProvisionedControllerImpl; import com.android.systemui.car.keyguard.CarKeyguardViewController; import com.android.systemui.car.statusbar.DozeServiceHost; import com.android.systemui.car.statusbar.DummyNotificationShadeWindowController; +import com.android.systemui.car.statusbar.UnusedStatusBar; import com.android.systemui.car.volume.CarVolumeDialogComponent; import com.android.systemui.dagger.SystemUIRootComponent; import com.android.systemui.dagger.qualifiers.Background; @@ -57,6 +58,7 @@ import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.ShadeControllerImpl; +import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryControllerImpl; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -175,4 +177,7 @@ public abstract class CarSystemUIModule { @Binds abstract DozeHost bindDozeHost(DozeServiceHost dozeServiceHost); + + @Binds + abstract StatusBar bindStatusBar(UnusedStatusBar statusBar); } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBar.java new file mode 100644 index 000000000000..48334bd6e5c7 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBar.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2020 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.car.statusbar; + +import android.content.Context; +import android.os.Handler; +import android.os.PowerManager; +import android.util.DisplayMetrics; + +import com.android.internal.logging.MetricsLogger; +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.ViewMediatorCallback; +import com.android.systemui.InitController; +import com.android.systemui.assist.AssistManager; +import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.bubbles.BubbleController; +import com.android.systemui.colorextraction.SysuiColorExtractor; +import com.android.systemui.keyguard.DismissCallbackRegistry; +import com.android.systemui.keyguard.KeyguardViewMediator; +import com.android.systemui.keyguard.ScreenLifecycle; +import com.android.systemui.keyguard.WakefulnessLifecycle; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.plugins.PluginDependencyProvider; +import com.android.systemui.recents.Recents; +import com.android.systemui.recents.ScreenPinningRequest; +import com.android.systemui.shared.plugins.PluginManager; +import com.android.systemui.stackdivider.Divider; +import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.KeyguardIndicationController; +import com.android.systemui.statusbar.NavigationBarController; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.NotificationMediaManager; +import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.NotificationShadeDepthController; +import com.android.systemui.statusbar.NotificationViewHierarchyManager; +import com.android.systemui.statusbar.PulseExpansionHandler; +import com.android.systemui.statusbar.SuperStatusBarViewFactory; +import com.android.systemui.statusbar.SysuiStatusBarStateController; +import com.android.systemui.statusbar.VibratorHelper; +import com.android.systemui.statusbar.notification.DynamicPrivacyController; +import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; +import com.android.systemui.statusbar.notification.VisualStabilityManager; +import com.android.systemui.statusbar.notification.init.NotificationsController; +import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier; +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; +import com.android.systemui.statusbar.notification.logging.NotificationLogger; +import com.android.systemui.statusbar.notification.row.NotificationGutsManager; +import com.android.systemui.statusbar.phone.AutoHideController; +import com.android.systemui.statusbar.phone.BiometricUnlockController; +import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.statusbar.phone.DozeScrimController; +import com.android.systemui.statusbar.phone.DozeServiceHost; +import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; +import com.android.systemui.statusbar.phone.KeyguardBypassController; +import com.android.systemui.statusbar.phone.KeyguardDismissUtil; +import com.android.systemui.statusbar.phone.KeyguardLiftController; +import com.android.systemui.statusbar.phone.LightBarController; +import com.android.systemui.statusbar.phone.LightsOutNotifController; +import com.android.systemui.statusbar.phone.LockscreenLockIconController; +import com.android.systemui.statusbar.phone.LockscreenWallpaper; +import com.android.systemui.statusbar.phone.NavigationBarView; +import com.android.systemui.statusbar.phone.NotificationGroupManager; +import com.android.systemui.statusbar.phone.NotificationShadeWindowController; +import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy; +import com.android.systemui.statusbar.phone.ScrimController; +import com.android.systemui.statusbar.phone.ShadeController; +import com.android.systemui.statusbar.phone.StatusBar; +import com.android.systemui.statusbar.phone.StatusBarIconController; +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter; +import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager; +import com.android.systemui.statusbar.phone.dagger.StatusBarComponent; +import com.android.systemui.statusbar.policy.BatteryController; +import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.statusbar.policy.ExtensionController; +import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.statusbar.policy.NetworkController; +import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; +import com.android.systemui.statusbar.policy.UserInfoControllerImpl; +import com.android.systemui.statusbar.policy.UserSwitcherController; +import com.android.systemui.volume.VolumeComponent; + +import java.util.Optional; +import java.util.concurrent.Executor; + +import javax.inject.Provider; + +import dagger.Lazy; + +/** Unused variant of {@link StatusBar} specifically used in the automotive context. */ +public class UnusedStatusBar extends StatusBar { + + public UnusedStatusBar(Context context, + NotificationsController notificationsController, + LightBarController lightBarController, + AutoHideController autoHideController, + KeyguardUpdateMonitor keyguardUpdateMonitor, + StatusBarIconController statusBarIconController, + PulseExpansionHandler pulseExpansionHandler, + NotificationWakeUpCoordinator notificationWakeUpCoordinator, + KeyguardBypassController keyguardBypassController, + KeyguardStateController keyguardStateController, + HeadsUpManagerPhone headsUpManagerPhone, + DynamicPrivacyController dynamicPrivacyController, + BypassHeadsUpNotifier bypassHeadsUpNotifier, + FalsingManager falsingManager, + BroadcastDispatcher broadcastDispatcher, + RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler, + NotificationGutsManager notificationGutsManager, + NotificationLogger notificationLogger, + NotificationInterruptStateProvider notificationInterruptStateProvider, + NotificationViewHierarchyManager notificationViewHierarchyManager, + KeyguardViewMediator keyguardViewMediator, + DisplayMetrics displayMetrics, + MetricsLogger metricsLogger, + Executor uiBgExecutor, + NotificationMediaManager notificationMediaManager, + NotificationLockscreenUserManager lockScreenUserManager, + NotificationRemoteInputManager remoteInputManager, + UserSwitcherController userSwitcherController, + NetworkController networkController, + BatteryController batteryController, + SysuiColorExtractor colorExtractor, + ScreenLifecycle screenLifecycle, + WakefulnessLifecycle wakefulnessLifecycle, + SysuiStatusBarStateController statusBarStateController, + VibratorHelper vibratorHelper, + BubbleController bubbleController, + NotificationGroupManager groupManager, + VisualStabilityManager visualStabilityManager, + DeviceProvisionedController deviceProvisionedController, + NavigationBarController navigationBarController, + Lazy assistManagerLazy, + ConfigurationController configurationController, + NotificationShadeWindowController notificationShadeWindowController, + LockscreenLockIconController lockscreenLockIconController, + DozeParameters dozeParameters, + ScrimController scrimController, + KeyguardLiftController keyguardLiftController, + Lazy lockscreenWallpaperLazy, + Lazy biometricUnlockControllerLazy, + DozeServiceHost dozeServiceHost, + PowerManager powerManager, + ScreenPinningRequest screenPinningRequest, + DozeScrimController dozeScrimController, + VolumeComponent volumeComponent, + CommandQueue commandQueue, + Optional recentsOptional, + Provider statusBarComponentBuilder, + PluginManager pluginManager, + Optional dividerOptional, + LightsOutNotifController lightsOutNotifController, + StatusBarNotificationActivityStarter.Builder statusBarNotifActivityStarterBuilder, + ShadeController shadeController, + SuperStatusBarViewFactory superStatusBarViewFactory, + StatusBarKeyguardViewManager statusBarKeyguardViewManager, + ViewMediatorCallback viewMediatorCallback, + InitController initController, + DarkIconDispatcher darkIconDispatcher, + Handler timeTickHandler, + PluginDependencyProvider pluginDependencyProvider, + KeyguardDismissUtil keyguardDismissUtil, + ExtensionController extensionController, + UserInfoControllerImpl userInfoControllerImpl, + PhoneStatusBarPolicy phoneStatusBarPolicy, + KeyguardIndicationController keyguardIndicationController, + DismissCallbackRegistry dismissCallbackRegistry, + Lazy notificationShadeDepthControllerLazy, + StatusBarTouchableRegionManager statusBarTouchableRegionManager) { + super(context, notificationsController, lightBarController, autoHideController, + keyguardUpdateMonitor, statusBarIconController, pulseExpansionHandler, + notificationWakeUpCoordinator, keyguardBypassController, keyguardStateController, + headsUpManagerPhone, dynamicPrivacyController, bypassHeadsUpNotifier, + falsingManager, + broadcastDispatcher, remoteInputQuickSettingsDisabler, notificationGutsManager, + notificationLogger, notificationInterruptStateProvider, + notificationViewHierarchyManager, keyguardViewMediator, displayMetrics, + metricsLogger, + uiBgExecutor, notificationMediaManager, lockScreenUserManager, remoteInputManager, + userSwitcherController, networkController, batteryController, colorExtractor, + screenLifecycle, wakefulnessLifecycle, statusBarStateController, vibratorHelper, + bubbleController, groupManager, visualStabilityManager, deviceProvisionedController, + navigationBarController, assistManagerLazy, configurationController, + notificationShadeWindowController, lockscreenLockIconController, dozeParameters, + scrimController, keyguardLiftController, lockscreenWallpaperLazy, + biometricUnlockControllerLazy, dozeServiceHost, powerManager, screenPinningRequest, + dozeScrimController, volumeComponent, commandQueue, recentsOptional, + statusBarComponentBuilder, pluginManager, dividerOptional, lightsOutNotifController, + statusBarNotifActivityStarterBuilder, shadeController, superStatusBarViewFactory, + statusBarKeyguardViewManager, viewMediatorCallback, initController, + darkIconDispatcher, + timeTickHandler, pluginDependencyProvider, keyguardDismissUtil, extensionController, + userInfoControllerImpl, phoneStatusBarPolicy, keyguardIndicationController, + dismissCallbackRegistry, notificationShadeDepthControllerLazy, + statusBarTouchableRegionManager); + } + + @Override + public void notifyBiometricAuthModeChanged() { + // No-op for Automotive devices. + } + + @Override + public NavigationBarView getNavigationBarView() { + // Return null for Automotive devices. + return null; + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBarModule.java new file mode 100644 index 000000000000..2c86e4db3b82 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/UnusedStatusBarModule.java @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2020 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.car.statusbar; + +import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME; + +import android.content.Context; +import android.os.Handler; +import android.os.PowerManager; +import android.util.DisplayMetrics; + +import androidx.annotation.Nullable; + +import com.android.internal.logging.MetricsLogger; +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.ViewMediatorCallback; +import com.android.systemui.InitController; +import com.android.systemui.assist.AssistManager; +import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.bubbles.BubbleController; +import com.android.systemui.colorextraction.SysuiColorExtractor; +import com.android.systemui.dagger.qualifiers.UiBackground; +import com.android.systemui.keyguard.DismissCallbackRegistry; +import com.android.systemui.keyguard.KeyguardViewMediator; +import com.android.systemui.keyguard.ScreenLifecycle; +import com.android.systemui.keyguard.WakefulnessLifecycle; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.plugins.PluginDependencyProvider; +import com.android.systemui.recents.Recents; +import com.android.systemui.recents.ScreenPinningRequest; +import com.android.systemui.shared.plugins.PluginManager; +import com.android.systemui.stackdivider.Divider; +import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.KeyguardIndicationController; +import com.android.systemui.statusbar.NavigationBarController; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.NotificationMediaManager; +import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.NotificationShadeDepthController; +import com.android.systemui.statusbar.NotificationViewHierarchyManager; +import com.android.systemui.statusbar.PulseExpansionHandler; +import com.android.systemui.statusbar.SuperStatusBarViewFactory; +import com.android.systemui.statusbar.SysuiStatusBarStateController; +import com.android.systemui.statusbar.VibratorHelper; +import com.android.systemui.statusbar.dagger.StatusBarDependenciesModule; +import com.android.systemui.statusbar.notification.DynamicPrivacyController; +import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; +import com.android.systemui.statusbar.notification.VisualStabilityManager; +import com.android.systemui.statusbar.notification.init.NotificationsController; +import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier; +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; +import com.android.systemui.statusbar.notification.logging.NotificationLogger; +import com.android.systemui.statusbar.notification.row.NotificationGutsManager; +import com.android.systemui.statusbar.notification.row.NotificationRowModule; +import com.android.systemui.statusbar.phone.AutoHideController; +import com.android.systemui.statusbar.phone.BiometricUnlockController; +import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.statusbar.phone.DozeScrimController; +import com.android.systemui.statusbar.phone.DozeServiceHost; +import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; +import com.android.systemui.statusbar.phone.KeyguardBypassController; +import com.android.systemui.statusbar.phone.KeyguardDismissUtil; +import com.android.systemui.statusbar.phone.KeyguardLiftController; +import com.android.systemui.statusbar.phone.LightBarController; +import com.android.systemui.statusbar.phone.LightsOutNotifController; +import com.android.systemui.statusbar.phone.LockscreenLockIconController; +import com.android.systemui.statusbar.phone.LockscreenWallpaper; +import com.android.systemui.statusbar.phone.NotificationGroupManager; +import com.android.systemui.statusbar.phone.NotificationShadeWindowController; +import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy; +import com.android.systemui.statusbar.phone.ScrimController; +import com.android.systemui.statusbar.phone.ShadeController; +import com.android.systemui.statusbar.phone.StatusBarIconController; +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter; +import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager; +import com.android.systemui.statusbar.phone.dagger.StatusBarComponent; +import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneDependenciesModule; +import com.android.systemui.statusbar.policy.BatteryController; +import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.statusbar.policy.ExtensionController; +import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.statusbar.policy.NetworkController; +import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; +import com.android.systemui.statusbar.policy.UserInfoControllerImpl; +import com.android.systemui.statusbar.policy.UserSwitcherController; +import com.android.systemui.volume.VolumeComponent; + +import java.util.Optional; +import java.util.concurrent.Executor; + +import javax.inject.Named; +import javax.inject.Provider; +import javax.inject.Singleton; + +import dagger.Lazy; +import dagger.Module; +import dagger.Provides; + +/** + * Dagger Module providing {@link UnusedStatusBar}. + */ +@Module(includes = {StatusBarDependenciesModule.class, StatusBarPhoneDependenciesModule.class, + NotificationRowModule.class}) +public interface UnusedStatusBarModule { + /** + * Provides our instance of StatusBar which is considered optional. + */ + @Provides + @Singleton + static UnusedStatusBar provideStatusBar( + Context context, + NotificationsController notificationsController, + LightBarController lightBarController, + AutoHideController autoHideController, + KeyguardUpdateMonitor keyguardUpdateMonitor, + StatusBarIconController statusBarIconController, + PulseExpansionHandler pulseExpansionHandler, + NotificationWakeUpCoordinator notificationWakeUpCoordinator, + KeyguardBypassController keyguardBypassController, + KeyguardStateController keyguardStateController, + HeadsUpManagerPhone headsUpManagerPhone, + DynamicPrivacyController dynamicPrivacyController, + BypassHeadsUpNotifier bypassHeadsUpNotifier, + FalsingManager falsingManager, + BroadcastDispatcher broadcastDispatcher, + RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler, + NotificationGutsManager notificationGutsManager, + NotificationLogger notificationLogger, + NotificationInterruptStateProvider notificationInterruptStateProvider, + NotificationViewHierarchyManager notificationViewHierarchyManager, + KeyguardViewMediator keyguardViewMediator, + DisplayMetrics displayMetrics, + MetricsLogger metricsLogger, + @UiBackground Executor uiBgExecutor, + NotificationMediaManager notificationMediaManager, + NotificationLockscreenUserManager lockScreenUserManager, + NotificationRemoteInputManager remoteInputManager, + UserSwitcherController userSwitcherController, + NetworkController networkController, + BatteryController batteryController, + SysuiColorExtractor colorExtractor, + ScreenLifecycle screenLifecycle, + WakefulnessLifecycle wakefulnessLifecycle, + SysuiStatusBarStateController statusBarStateController, + VibratorHelper vibratorHelper, + BubbleController bubbleController, + NotificationGroupManager groupManager, + VisualStabilityManager visualStabilityManager, + DeviceProvisionedController deviceProvisionedController, + NavigationBarController navigationBarController, + Lazy assistManagerLazy, + ConfigurationController configurationController, + NotificationShadeWindowController notificationShadeWindowController, + LockscreenLockIconController lockscreenLockIconController, + DozeParameters dozeParameters, + ScrimController scrimController, + @Nullable KeyguardLiftController keyguardLiftController, + Lazy lockscreenWallpaperLazy, + Lazy biometricUnlockControllerLazy, + DozeServiceHost dozeServiceHost, + PowerManager powerManager, + ScreenPinningRequest screenPinningRequest, + DozeScrimController dozeScrimController, + VolumeComponent volumeComponent, + CommandQueue commandQueue, + Optional recentsOptional, + Provider statusBarComponentBuilder, + PluginManager pluginManager, + Optional dividerOptional, + LightsOutNotifController lightsOutNotifController, + StatusBarNotificationActivityStarter.Builder + statusBarNotificationActivityStarterBuilder, + ShadeController shadeController, + SuperStatusBarViewFactory superStatusBarViewFactory, + StatusBarKeyguardViewManager statusBarKeyguardViewManager, + ViewMediatorCallback viewMediatorCallback, + InitController initController, + DarkIconDispatcher darkIconDispatcher, + @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler, + PluginDependencyProvider pluginDependencyProvider, + KeyguardDismissUtil keyguardDismissUtil, + ExtensionController extensionController, + UserInfoControllerImpl userInfoControllerImpl, + PhoneStatusBarPolicy phoneStatusBarPolicy, + KeyguardIndicationController keyguardIndicationController, + Lazy notificationShadeDepthController, + DismissCallbackRegistry dismissCallbackRegistry, + StatusBarTouchableRegionManager statusBarTouchableRegionManager) { + return new UnusedStatusBar( + context, + notificationsController, + lightBarController, + autoHideController, + keyguardUpdateMonitor, + statusBarIconController, + pulseExpansionHandler, + notificationWakeUpCoordinator, + keyguardBypassController, + keyguardStateController, + headsUpManagerPhone, + dynamicPrivacyController, + bypassHeadsUpNotifier, + falsingManager, + broadcastDispatcher, + remoteInputQuickSettingsDisabler, + notificationGutsManager, + notificationLogger, + notificationInterruptStateProvider, + notificationViewHierarchyManager, + keyguardViewMediator, + displayMetrics, + metricsLogger, + uiBgExecutor, + notificationMediaManager, + lockScreenUserManager, + remoteInputManager, + userSwitcherController, + networkController, + batteryController, + colorExtractor, + screenLifecycle, + wakefulnessLifecycle, + statusBarStateController, + vibratorHelper, + bubbleController, + groupManager, + visualStabilityManager, + deviceProvisionedController, + navigationBarController, + assistManagerLazy, + configurationController, + notificationShadeWindowController, + lockscreenLockIconController, + dozeParameters, + scrimController, + keyguardLiftController, + lockscreenWallpaperLazy, + biometricUnlockControllerLazy, + dozeServiceHost, + powerManager, + screenPinningRequest, + dozeScrimController, + volumeComponent, + commandQueue, + recentsOptional, + statusBarComponentBuilder, + pluginManager, + dividerOptional, + lightsOutNotifController, + statusBarNotificationActivityStarterBuilder, + shadeController, + superStatusBarViewFactory, + statusBarKeyguardViewManager, + viewMediatorCallback, + initController, + darkIconDispatcher, + timeTickHandler, + pluginDependencyProvider, + keyguardDismissUtil, + extensionController, + userInfoControllerImpl, + phoneStatusBarPolicy, + keyguardIndicationController, + dismissCallbackRegistry, + notificationShadeDepthController, + statusBarTouchableRegionManager); + } +} -- GitLab From e085352bd8e581d42a4cbe3c1fc0f879d2eb80d2 Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Mon, 24 Aug 2020 15:57:45 -0700 Subject: [PATCH 290/536] DO NOT MERGE: Update location icon on changes Ensure that appops monitoring is updated whenever the high power state of a locaiton request could possibly have changed. Bug: 161941573 Test: manual + presubmit Change-Id: I5d30d2ca109d6808511b68a56f790ef0826ef562 --- .../java/com/android/server/location/LocationManagerService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index bfcbe465a271..9adde24a99e0 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -1586,6 +1586,7 @@ public class LocationManagerService extends ILocationManager.Stub { } record.mRequest = locationRequest; + record.mReceiver.updateMonitoring(true); requests.add(locationRequest); if (!locationRequest.isLowPowerMode()) { providerRequest.setLowPowerMode(false); -- GitLab From 324aa1e5d43fee59707fe78722344a8f83961bc8 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 25 Aug 2020 04:34:50 -0700 Subject: [PATCH 291/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ie51906c818a7f850d6ee4baf600c24de4e6a35b5 --- packages/SettingsLib/res/values-in/arrays.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml index 37cf189f26c0..3ab50cc948eb 100644 --- a/packages/SettingsLib/res/values-in/arrays.xml +++ b/packages/SettingsLib/res/values-in/arrays.xml @@ -31,7 +31,7 @@ "Memutus sambungan..." "Sambungan terputus" "Gagal" - "Dicekal" + "Diblokir" "Menghindari sambungan buruk untuk sementara" -- GitLab From 17ed4e74ec786f15432b09fe435fbec7fbc6f441 Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Tue, 25 Aug 2020 09:16:27 -0400 Subject: [PATCH 292/536] Add log for dismissal when new screenshot is taken Currently, we log when the screenshot UI is dismissed due to timeout, tapping the 'X' button, tapping the preview, or tapping any of the action buttons. However, there is an additional way to cause the UI to be dismissed, which is to take a new screenshot while the UI is up (in which case we dismiss the old UI immediately). We should log this to get a better picture of how people use/interact with the screenshot UI. This change adds the log (previously registered using the uievent cli) and logs when a new screenshot is taken, if there's UI on the screen and we aren't already dismissing for some other reason (to avoid duplicate logs). Bug: 166249049 Test: manual Change-Id: I4a1d7cf8c1309a3198593eef004a2b18f94f809f --- .../com/android/systemui/screenshot/GlobalScreenshot.java | 7 ++++++- .../com/android/systemui/screenshot/ScreenshotEvent.java | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index c53523032353..853897fc54ae 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -565,7 +565,12 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset private void saveScreenshot(Bitmap screenshot, Consumer finisher, Rect screenRect, Insets screenInsets, boolean showFlash) { - dismissScreenshot("new screenshot requested", true); + if (mScreenshotLayout.isAttachedToWindow()) { + if (!mDismissAnimation.isRunning()) { // if we didn't already dismiss for another reason + mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_REENTERED); + } + dismissScreenshot("new screenshot requested", true); + } mScreenBitmap = screenshot; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java index 20fa991dcc1f..8535d5708a67 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java @@ -56,7 +56,9 @@ public enum ScreenshotEvent implements UiEventLogger.UiEventEnum { @UiEvent(doc = "screenshot interaction timed out") SCREENSHOT_INTERACTION_TIMEOUT(310), @UiEvent(doc = "screenshot explicitly dismissed") - SCREENSHOT_EXPLICIT_DISMISSAL(311); + SCREENSHOT_EXPLICIT_DISMISSAL(311), + @UiEvent(doc = "screenshot reentered for new screenshot") + SCREENSHOT_REENTERED(640); private final int mId; -- GitLab From bb6d38615ef43ab4cb985293005165a43f7ab45f Mon Sep 17 00:00:00 2001 From: Jin Seok Park Date: Mon, 27 Jul 2020 11:23:14 +0900 Subject: [PATCH 293/536] DO NOT MERGE: Rename temp file to use a valid image file extension MediaProvider added a restriction in R for apps targeting SDK 30 to not allow .tmp files in image file directories such as "Pictures" and "DCIM". This CL renames the temp file to avoid this restriction. Also added test to check for writing to FileDescriptor instances. Bug: 160874777 Test: atest CtsMediaTestCases:android.media.cts.ExifInterfaceTest Also tested with an image file inside /Pictures Change-Id: Iedb548651c0048b0aecc4b34e9c94f778cf5d1e0 (cherry picked from commit 5abacddfc3355905a3d15a3561d321f5ea62dcc2) --- media/java/android/media/ExifInterface.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index ed566a50ec58..533f6950fb89 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -68,6 +68,7 @@ import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TimeZone; +import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.CRC32; @@ -2079,7 +2080,10 @@ public class ExifInterface { try { // Move the original file to temporary file. if (mFilename != null) { - tempFile = new File(mFilename + ".tmp"); + String parent = originalFile.getParent(); + String name = originalFile.getName(); + String tempPrefix = UUID.randomUUID().toString() + "_"; + tempFile = new File(parent, tempPrefix + name); if (!originalFile.renameTo(tempFile)) { throw new IOException("Couldn't rename to " + tempFile.getAbsolutePath()); } -- GitLab From b2444cbef5236845a26e15bdfc95efac17b299f8 Mon Sep 17 00:00:00 2001 From: Charles Chen Date: Mon, 24 Aug 2020 09:56:57 +0800 Subject: [PATCH 294/536] [RESTRICT AUTOMERGE] Make a context dervied from an UI context as an UI context fixes: 165833103 Test: atest StrictModeTest ContextAccessTest Test: atest InputMethodServiceTest InputMethodServiceStrictModeTest Merged-In: Ia97e1a0cc290be516d2618148600238b3273c54c Change-Id: Ia97e1a0cc290be516d2618148600238b3273c54c --- core/java/android/app/ContextImpl.java | 7 +++- .../src/android/content/ContextTest.java | 38 ++++++++++++++----- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 3a18b870d7f6..c51a84649a07 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -2389,7 +2389,6 @@ class ContextImpl extends Context { context.setResources(createResources(mToken, mPackageInfo, mSplitName, displayId, overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo(), mResources.getLoaders())); - context.mIsUiContext = isSelfOrOuterUiContext(); return context; } @@ -2409,6 +2408,11 @@ class ContextImpl extends Context { mResources.getLoaders())); context.mDisplay = display; context.mIsAssociatedWithDisplay = true; + // Note that even if a display context is derived from an UI context, it should not be + // treated as UI context because it does not handle configuration changes from the server + // side. If the context does need to handle configuration changes, please use + // Context#createWindowContext(int, Bundle). + context.mIsUiContext = false; return context; } @@ -2770,6 +2774,7 @@ class ContextImpl extends Context { mDisplay = container.mDisplay; mIsAssociatedWithDisplay = container.mIsAssociatedWithDisplay; mIsSystemOrSystemUiContext = container.mIsSystemOrSystemUiContext; + mIsUiContext = container.isSelfOrOuterUiContext(); } else { mBasePackageName = packageInfo.mPackageName; ApplicationInfo ainfo = packageInfo.getApplicationInfo(); diff --git a/core/tests/coretests/src/android/content/ContextTest.java b/core/tests/coretests/src/android/content/ContextTest.java index 777f4a3e03a8..de81ff4d0ca5 100644 --- a/core/tests/coretests/src/android/content/ContextTest.java +++ b/core/tests/coretests/src/android/content/ContextTest.java @@ -19,6 +19,7 @@ package android.content; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static com.google.common.truth.Truth.assertThat; @@ -188,19 +189,38 @@ public class ContextTest { assertFalse(wrapper.isUiContext()); - wrapper = new ContextWrapper(new TestUiContext()); + wrapper = new ContextWrapper(getUiContext()); assertTrue(wrapper.isUiContext()); } - private static class TestUiContext extends ContextWrapper { - TestUiContext() { - super(null /* base */); - } + @Test + public void testIsUiContext_UiContextDerivedContext() { + final Context uiContext = getUiContext(); + Context context = uiContext.createAttributionContext(null /* attributionTag */); - @Override - public boolean isUiContext() { - return true; - } + assertTrue(context.isUiContext()); + + context = uiContext.createConfigurationContext(new Configuration()); + + assertTrue(context.isUiContext()); + } + + @Test + public void testIsUiContext_UiContextDerivedDisplayContext() { + final Context uiContext = getUiContext(); + final Display secondaryDisplay = + getSecondaryDisplay(uiContext.getSystemService(DisplayManager.class)); + final Context context = uiContext.createDisplayContext(secondaryDisplay); + + assertFalse(context.isUiContext()); + } + + private Context getUiContext() { + final Context appContext = ApplicationProvider.getApplicationContext(); + final DisplayManager displayManager = appContext.getSystemService(DisplayManager.class); + final Display display = displayManager.getDisplay(DEFAULT_DISPLAY); + return appContext.createDisplayContext(display) + .createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */); } } -- GitLab From bfdd44fa937eef47f8d855c269e14e6557707294 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 25 Aug 2020 23:13:10 -0700 Subject: [PATCH 295/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I9e99c9eb029b7266bca37be93499021da434e0e0 --- core/res/res/values-cs/strings.xml | 6 +++--- core/res/res/values-da/strings.xml | 2 +- core/res/res/values-eu/strings.xml | 4 ++-- core/res/res/values-in/strings.xml | 2 +- core/res/res/values-ne/strings.xml | 16 ++++++++-------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 7e5d6f227de0..e16c8c28c270 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1258,7 +1258,7 @@ "Hlasitost vyzvánění" "Hlasitost médií" "Přehrávání pomocí rozhraní Bluetooth" - "Je nastaven tichý vyzváněcí tón" + "Je nastaven tichý vyzvánění" "Hlasitost hovoru" "Hlasitost příchozích hovorů při připojení Bluetooth" "Hlasitost budíku" @@ -1269,10 +1269,10 @@ "Hlasitost hovoru" "Hlasitost médií" "Hlasitost oznámení" - "Výchozí vyzváněcí tón" + "Výchozí vyzvánění" "Výchozí (%1$s)" "Žádný" - "Vyzváněcí tóny" + "Vyzvánění" "Zvuky budíku" "Zvuky upozornění" "Neznámé" diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index f428b1da4a9f..09e2ea20cd92 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -654,7 +654,7 @@ "observer netværksforhold" "Tillader, at en applikation observerer netværksforhold. Bør aldrig være nødvendigt for almindelige apps." "skift kalibrering for inputenheden" - "Tillader, at appen ændrer kalibreringsparametrene for berøringsskærmen. Dette bør aldrig være nødvendigt for almindelige apps." + "Tillader, at appen ændrer kalibreringsparametrene for touchskærmen. Dette bør aldrig være nødvendigt for almindelige apps." "få adgang til DRM-certifikater" "Tillader, at en applikation provisionerer og anvender DRM-certifikater. Dette bør aldrig være nødvendigt for almindelige apps." "modtag status for Android Beam-overførsler" diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index cd3e6f77db5a..c0ec8e039de7 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -482,8 +482,8 @@ "Telefonoaren ordu-zona aldatzeko baimena ematen die aplikazioei." "bilatu gailuko kontuak" "Tabletak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Instalatuta dauzkazun aplikazioek sortutako kontuak har daitezke barnean." - "Android TV gailuak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Kontu horien artean, instalatuta dituzun aplikazioek sortutako kontuak egon litezke." - "Telefonoak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Instalatuta dituzun aplikazioek sortutako kontuak har daitezke barnean." + "Android TV gailuak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Kontu horien artean, instalatuta dauzkazun aplikazioek sortutako kontuak egon litezke." + "Telefonoak ezagutzen dituen kontuen zerrenda lortzeko baimena ematen die aplikazioei. Instalatuta dauzkazun aplikazioek sortutako kontuak har daitezke barnean." "ikusi sareko konexioak" "Sareko konexioei buruzko informazioa ikusteko baimena ematen die aplikazioei; adibidez, zer sare dauden eta zeintzuk dauden konektatuta." "izan sarerako sarbide osoa" diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index cac9168e2a2c..b9e7f4f8c955 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -2034,7 +2034,7 @@ "Aplikasi ini tidak diberi izin merekam, tetapi dapat merekam audio melalui perangkat USB ini." "Beranda" "Kembali" - "Aplikasi yang Baru Dipakai" + "Aplikasi Terbaru" "Notifikasi" "Setelan Cepat" "Dialog Daya" diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 317092aaedad..520f97321e8c 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -302,13 +302,13 @@ "SMS" "SMS सन्देशहरू पठाउनुहोस् र हेर्नुहोस्" "फाइल र मिडिया" - "तपाईंको यन्त्रमा तस्बिर, मिडिया, र फाइलहरूमाथि पहुँच गर्नुहोस्" + "तपाईंको यन्त्रमा फोटो, मिडिया, र फाइलहरूमाथि पहुँच गर्नुहोस्" "माइक्रोफोन" "अडियो रेकर्ड गर्नुहोस्" "शारीरिक क्रियाकलाप" "आफ्नो शारीरिक क्रियाकलापको डेटामाथि पहुँच राख्नु" "क्यामेरा" - "तस्बिर खिच्नुका साथै भिडियो रेकर्ड गर्नुहोस्" + "फोटो खिच्नुका साथै भिडियो रेकर्ड गर्नुहोस्" "कलका लगहरू" "फोन कलको लग पढ्नुहोस् र लेख्नुहोस्" "फोन" @@ -435,10 +435,10 @@ "SIM लाई आदेश पठाउन एपलाई अनुमति दिन्छ। यो निकै खतरनाक हुन्छ।" "शारीरिक गतिविधि पहिचान गर्नुहोस्‌" "यो अनुप्रयोगले तपाईंको शारीरिक गतिविधिको पहिचान गर्न सक्छ।" - "तस्बिरहरू र भिडियोहरू लिनुहोस्।" - "यस अनुप्रयोगले जुनसुकै समय क्यामेराको प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ।" - "एप वा सेवालाई तस्बिर र भिडियो खिच्न प्रणालीका क्यामेराहरूमाथि पहुँच राख्न दिनुहोस्" - "प्रणालीको यस विशेषाधिकार प्राप्त अनुप्रयोगले जुनसुकै बेला प्रणालीको क्यामेरा प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ। अनुप्रयोगसँग पनि android.permission.CAMERA प्रयोग गर्ने अनुमति हुनु पर्छ" + "फोटोहरू र भिडियोहरू लिनुहोस्।" + "यस अनुप्रयोगले जुनसुकै समय क्यामेराको प्रयोग गरी फोटो खिच्न र भिडियो रेकर्ड गर्न सक्छ।" + "एप वा सेवालाई फोटो र भिडियो खिच्न प्रणालीका क्यामेराहरूमाथि पहुँच राख्न दिनुहोस्" + "प्रणालीको यस विशेषाधिकार प्राप्त अनुप्रयोगले जुनसुकै बेला प्रणालीको क्यामेरा प्रयोग गरी फोटो खिच्न र भिडियो रेकर्ड गर्न सक्छ। अनुप्रयोगसँग पनि android.permission.CAMERA प्रयोग गर्ने अनुमति हुनु पर्छ" "कुनै एप वा सेवालाई खोलिँदै वा बन्द गरिँदै गरेका क्यामेरा यन्त्रहरूका बारेमा कलब्याक प्राप्त गर्ने अनुमति दिनुहोस्।" "कुनै क्यामेरा यन्त्र खोलिँदा (कुन अनुप्रयोगले खोलेको भन्ने बारेमा) वा बन्द गरिँदा यो अनुप्रयोगले कलब्याक प्राप्त गर्न सक्छ।" "कम्पन नियन्त्रण गर्नुहोस्" @@ -1344,7 +1344,7 @@ "%s ले काम गरिरहेको छैन" "सेटअप गर्न ट्याप गर्नुहोस्" "तपाईंले यो यन्त्र पुनः फर्म्याट गर्नु पर्ने हुन सक्छ। यो यन्त्र हटाउन ट्याप गर्नुहोस्।" - "तस्बिरहरू र मिडिया स्थानान्तरणका लागि" + "फोटोहरू र मिडिया स्थानान्तरणका लागि" "%s मा समस्या देखियो" "%s ले काम गरिरहेको छैन" "समस्या समाधान गर्न ट्याप गर्नुहोस्" @@ -1914,7 +1914,7 @@ "खेलहरू" "सङ्गीत तथा अडियो" "चलचित्र तथा भिडियो" - "तस्बिर तथा छविहरू" + "फोटो तथा छविहरू" "सामाजिक तथा सञ्चार" "समाचार तथा पत्रिकाहरू" "नक्सा तथा नेभिगेसन" -- GitLab From 5afa7645579a01b77005b8a60f3713ca3e653fba Mon Sep 17 00:00:00 2001 From: Ivan Chiang Date: Mon, 10 Aug 2020 16:43:33 +0800 Subject: [PATCH 296/536] Revoke the uri permission when the file is deleted When the file is deleted, renamed or moved, revoke all uri permissions with the file Bug: 157474195 Test: manual test with DocumentsUI Test: atest DocumentsTest#testAfterMoveDocumentInStorage_revokeUriPermission Change-Id: I4ffb183630aadb2d87b0965e8cecf88af15f4534 Merged-In: I4ffb183630aadb2d87b0965e8cecf88af15f4534 (cherry picked from commit 9efd606f43abe36f9fcf7f0d1ab0d059c51be514) --- .../android/internal/content/FileSystemProvider.java | 11 +++++++++++ .../externalstorage/ExternalStorageProvider.java | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java index a50a52219c74..3b5fecfc600a 100644 --- a/core/java/com/android/internal/content/FileSystemProvider.java +++ b/core/java/com/android/internal/content/FileSystemProvider.java @@ -113,6 +113,14 @@ public abstract class FileSystemProvider extends DocumentsProvider { // Default is no-op } + /** + * Callback indicating that the given document has been deleted or moved. This gives + * the provider a hook to revoke the uri permissions. + */ + protected void onDocIdDeleted(String docId) { + // Default is no-op + } + @Override public boolean onCreate() { throw new UnsupportedOperationException( @@ -283,6 +291,7 @@ public abstract class FileSystemProvider extends DocumentsProvider { final String afterDocId = getDocIdForFile(after); onDocIdChanged(docId); + onDocIdDeleted(docId); onDocIdChanged(afterDocId); final File afterVisibleFile = getFileForDocId(afterDocId, true); @@ -312,6 +321,7 @@ public abstract class FileSystemProvider extends DocumentsProvider { final String docId = getDocIdForFile(after); onDocIdChanged(sourceDocumentId); + onDocIdDeleted(sourceDocumentId); onDocIdChanged(docId); moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true)); @@ -343,6 +353,7 @@ public abstract class FileSystemProvider extends DocumentsProvider { } onDocIdChanged(docId); + onDocIdDeleted(docId); removeFromMediaStore(visibleFile); } diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java index f42bf1982b36..11d1b0a9ef2a 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java @@ -482,6 +482,13 @@ public class ExternalStorageProvider extends FileSystemProvider { } } + @Override + protected void onDocIdDeleted(String docId) { + Uri uri = DocumentsContract.buildDocumentUri(AUTHORITY, docId); + getContext().revokeUriPermission(uri, ~0); + } + + @Override public Cursor queryRoots(String[] projection) throws FileNotFoundException { final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection)); -- GitLab From a8c84525bc43c685574b2f1c2a27582bb1be7b44 Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Wed, 1 Jul 2020 16:22:24 +0800 Subject: [PATCH 297/536] Use sf animation handler in PIP PhysicsAnimator To reduce jank caused by vsync app, replace whole animation handler in PhysicsAnimator used by PIP to sf animation handler. Bug: 159313747 Test: Launch PIP app and drag it around Merged-In: Iebee75d071fecc2d98d4871d47d83a4b4143b94e Change-Id: Iebee75d071fecc2d98d4871d47d83a4b4143b94e (cherry picked from commit 7016e97d6ee94ac2bddc4953886ebcaea3d0aad7) --- .../systemui/pip/phone/PipMotionHelper.java | 22 +++++---- .../util/animation/PhysicsAnimator.kt | 48 ++++++++++++++++--- 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java index 8a2e4ae11878..9f0b1de21b52 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java @@ -26,9 +26,10 @@ import android.os.Debug; import android.util.Log; import android.view.Choreographer; +import androidx.dynamicanimation.animation.AnimationHandler; +import androidx.dynamicanimation.animation.AnimationHandler.FrameCallbackScheduler; import androidx.dynamicanimation.animation.SpringForce; -import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.systemui.pip.PipSnapAlgorithm; import com.android.systemui.pip.PipTaskOrganizer; import com.android.systemui.util.FloatingContentCoordinator; @@ -74,9 +75,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, /** The region that all of PIP must stay within. */ private final Rect mFloatingAllowedArea = new Rect(); - private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider = - new SfVsyncFrameCallbackProvider(); - /** * Temporary bounds used when PIP is being dragged or animated. These bounds are applied to PIP * using {@link PipTaskOrganizer#scheduleUserResizePip}, so that we can animate shrinking into @@ -94,8 +92,13 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, /** Coordinator instance for resolving conflicts with other floating content. */ private FloatingContentCoordinator mFloatingContentCoordinator; - /** Callback that re-sizes PIP to the animated bounds. */ - private final Choreographer.FrameCallback mResizePipVsyncCallback; + private ThreadLocal mSfAnimationHandlerThreadLocal = + ThreadLocal.withInitial(() -> { + FrameCallbackScheduler scheduler = runnable -> + Choreographer.getSfInstance().postFrameCallback(t -> runnable.run()); + AnimationHandler handler = new AnimationHandler(scheduler); + return handler; + }); /** * PhysicsAnimator instance for animating {@link #mTemporaryBounds} using physics animations. @@ -171,16 +174,15 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, mSnapAlgorithm = snapAlgorithm; mFloatingContentCoordinator = floatingContentCoordinator; mPipTaskOrganizer.registerPipTransitionCallback(mPipTransitionCallback); + mTemporaryBoundsPhysicsAnimator.setCustomAnimationHandler( + mSfAnimationHandlerThreadLocal.get()); - mResizePipVsyncCallback = l -> { + mResizePipUpdateListener = (target, values) -> { if (!mTemporaryBounds.isEmpty()) { mPipTaskOrganizer.scheduleUserResizePip( mBounds, mTemporaryBounds, null); } }; - - mResizePipUpdateListener = (target, values) -> - mSfVsyncFrameProvider.postFrameCallback(mResizePipVsyncCallback); } @NonNull diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt b/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt index 016f4de724b6..2a5424ce4ef7 100644 --- a/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt +++ b/packages/SystemUI/src/com/android/systemui/util/animation/PhysicsAnimator.kt @@ -20,6 +20,7 @@ import android.os.Looper import android.util.ArrayMap import android.util.Log import android.view.View +import androidx.dynamicanimation.animation.AnimationHandler import androidx.dynamicanimation.animation.DynamicAnimation import androidx.dynamicanimation.animation.FlingAnimation import androidx.dynamicanimation.animation.FloatPropertyCompat @@ -123,6 +124,12 @@ class PhysicsAnimator private constructor (target: T) { /** FlingConfig to use by default for properties whose fling configs were not provided. */ private var defaultFling: FlingConfig = globalDefaultFling + /** + * AnimationHandler to use if it need custom AnimationHandler, if this is null, it will use + * the default AnimationHandler in the DynamicAnimation. + */ + private var customAnimationHandler: AnimationHandler? = null + /** * Internal listeners that respond to DynamicAnimations updating and ending, and dispatch to * the listeners provided via [addUpdateListener] and [addEndListener]. This allows us to add @@ -447,6 +454,14 @@ class PhysicsAnimator private constructor (target: T) { this.defaultFling = defaultFling } + /** + * Set the custom AnimationHandler for all aniatmion in this animator. Set this with null for + * restoring to default AnimationHandler. + */ + fun setCustomAnimationHandler(handler: AnimationHandler) { + this.customAnimationHandler = handler + } + /** Starts the animations! */ fun start() { startAction() @@ -501,10 +516,13 @@ class PhysicsAnimator private constructor (target: T) { // springs) on this property before flinging. cancel(animatedProperty) + // Apply the custom animation handler if it not null + val flingAnim = getFlingAnimation(animatedProperty, target) + flingAnim.animationHandler = + customAnimationHandler ?: flingAnim.animationHandler + // Apply the configuration and start the animation. - getFlingAnimation(animatedProperty, target) - .also { flingConfig.applyToAnimation(it) } - .start() + flingAnim.also { flingConfig.applyToAnimation(it) }.start() } } @@ -516,6 +534,21 @@ class PhysicsAnimator private constructor (target: T) { if (flingConfig == null) { // Apply the configuration and start the animation. val springAnim = getSpringAnimation(animatedProperty, target) + + // If customAnimationHander is exist and has not been set to the animation, + // it should set here. + if (customAnimationHandler != null && + springAnim.animationHandler != customAnimationHandler) { + // Cancel the animation before set animation handler + if (springAnim.isRunning) { + cancel(animatedProperty) + } + // Apply the custom animation handler if it not null + springAnim.animationHandler = + customAnimationHandler ?: springAnim.animationHandler + } + + // Apply the configuration and start the animation. springConfig.applyToAnimation(springAnim) animationStartActions.add(springAnim::start) } else { @@ -570,10 +603,13 @@ class PhysicsAnimator private constructor (target: T) { } } + // Apply the custom animation handler if it not null + val springAnim = getSpringAnimation(animatedProperty, target) + springAnim.animationHandler = + customAnimationHandler ?: springAnim.animationHandler + // Apply the configuration and start the spring animation. - getSpringAnimation(animatedProperty, target) - .also { springConfig.applyToAnimation(it) } - .start() + springAnim.also { springConfig.applyToAnimation(it) }.start() } } }) -- GitLab From 031f3d18e18aa2a48862ed8630296caaa257b39d Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Sun, 23 Aug 2020 19:19:03 -0700 Subject: [PATCH 298/536] [SysUI] Add Low Quality QS indication Add Low Quality QS indication to WiFi when it is still connected and validated but is not the default network (most likely an indication that it has a low score). Bug: 163627176 Test: visual (using `adb shell cmd wifi set-connected-score 49` to simulate a low score) Test: atest NetworkControllerWifiTest Change-Id: Ib0d0194b20b8cb824faebea1af5461c553be859e --- .../src/com/android/settingslib/wifi/WifiStatusTracker.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java index e77d1a2ccea1..44c920c7c0a7 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java @@ -13,6 +13,7 @@ package com.android.settingslib.wifi; import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import android.content.Context; import android.content.Intent; @@ -247,6 +248,10 @@ public class WifiStatusTracker { statusLabel = mContext.getString(R.string.wifi_status_no_internet); } return; + } else if (!isDefaultNetwork && mDefaultNetworkCapabilities != null + && mDefaultNetworkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { + statusLabel = mContext.getString(R.string.wifi_connected_low_quality); + return; } } -- GitLab From d683a79c5db981ad70d878611ff98c9a2cc906f7 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 26 Aug 2020 06:25:51 -0700 Subject: [PATCH 299/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I06dd371ccde08b2b626bc0ea2142785adee33ff0 --- packages/PrintSpooler/res/values-as/strings.xml | 2 +- packages/PrintSpooler/res/values-bn/strings.xml | 2 +- packages/PrintSpooler/res/values-fa/strings.xml | 2 +- packages/PrintSpooler/res/values-kn/strings.xml | 2 +- packages/PrintSpooler/res/values-ml/strings.xml | 2 +- packages/PrintSpooler/res/values-mr/strings.xml | 2 +- packages/PrintSpooler/res/values-or/strings.xml | 2 +- packages/PrintSpooler/res/values-te/strings.xml | 2 +- packages/PrintSpooler/res/values-uz/strings.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/PrintSpooler/res/values-as/strings.xml b/packages/PrintSpooler/res/values-as/strings.xml index a93fceb87959..b6b287ff66aa 100644 --- a/packages/PrintSpooler/res/values-as/strings.xml +++ b/packages/PrintSpooler/res/values-as/strings.xml @@ -47,7 +47,7 @@ "PDFৰ জৰিয়তে ছেভ কৰক" "প্ৰিণ্ট বিকল্পসমূহ বিস্তাৰ কৰা হ’ল" "প্ৰিণ্ট বিকল্পসমূহ সংকুচিত কৰা হ’ল" - "সন্ধান কৰক" + "Search" "সকলো প্ৰিণ্টাৰ" "সেৱা যোগ কৰক" "সন্ধান বাকচটো দেখুওৱা হ’ল" diff --git a/packages/PrintSpooler/res/values-bn/strings.xml b/packages/PrintSpooler/res/values-bn/strings.xml index 637becbe23f0..b2e1eed85f0c 100644 --- a/packages/PrintSpooler/res/values-bn/strings.xml +++ b/packages/PrintSpooler/res/values-bn/strings.xml @@ -47,7 +47,7 @@ "পিডিএফ হিসাবে সেভ করুন" "প্রিন্ট বিকল্প প্রসারিত হয়েছে" "প্রিন্ট বিকল্প সংকুচিত হয়েছে" - "খুঁজুন" + "সার্চ" "সমস্ত প্রিন্টার" "পরিষেবা যোগ করুন" "সার্চ বাক্স দেখানো হচ্ছে" diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml index 596947dfb6dc..719fc9219450 100644 --- a/packages/PrintSpooler/res/values-fa/strings.xml +++ b/packages/PrintSpooler/res/values-fa/strings.xml @@ -31,7 +31,7 @@ "همه %1$s صفحه" "محدوده %1$s صفحه" "‏‏‎مثلاً ۱—۵،‏۹،۷—۱۰" - "پیش‌نمایش چاپ" + "پیش‌نمای چاپ" "‏نصب نمایشگر PDF برای پیش‌نمایش" "برنامه چاپ خراب شد" "در حال ایجاد کار چاپ" diff --git a/packages/PrintSpooler/res/values-kn/strings.xml b/packages/PrintSpooler/res/values-kn/strings.xml index 150ede4f8e62..261fe4b0de9a 100644 --- a/packages/PrintSpooler/res/values-kn/strings.xml +++ b/packages/PrintSpooler/res/values-kn/strings.xml @@ -47,7 +47,7 @@ "PDF ಗೆ ಉಳಿಸು" "ಪ್ರಿಂಟ್ ಆಯ್ಕೆಗಳನ್ನು ವಿಸ್ತರಿಸಲಾಗಿದೆ" "ಪ್ರಿಂಟ್ ಆಯ್ಕೆಗಳನ್ನು ಮುಚ್ಚಲಾಗಿದೆ" - "ಹುಡುಕಿ" + "Search" "ಎಲ್ಲಾ ಪ್ರಿಂಟರ್‌ಗಳು" "ಸೇವೆಯನ್ನು ಸೇರಿಸು" "ಹುಡುಕಾಟ ಪೆಟ್ಟಿಗೆಯನ್ನು ತೋರಿಸಲಾಗಿದೆ" diff --git a/packages/PrintSpooler/res/values-ml/strings.xml b/packages/PrintSpooler/res/values-ml/strings.xml index dbcd34b1360d..73af95d2e117 100644 --- a/packages/PrintSpooler/res/values-ml/strings.xml +++ b/packages/PrintSpooler/res/values-ml/strings.xml @@ -47,7 +47,7 @@ "PDF-ൽ സംരക്ഷിക്കുക" "പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്‌ഷനുകൾ വിപുലീകരിച്ചു" "പ്രിന്റ് ചെയ്യാനുള്ള ഓപ്‌ഷനുകൾ ചുരുക്കി" - "തിരയൽ" + "Search" "എല്ലാ പ്രിന്ററുകളും" "സേവനം ചേർക്കുക" "തിരയൽ ബോക്‌സ് ദൃശ്യമാക്കിയിരിക്കുന്നു" diff --git a/packages/PrintSpooler/res/values-mr/strings.xml b/packages/PrintSpooler/res/values-mr/strings.xml index 44456b4cae05..4d7e919ad125 100644 --- a/packages/PrintSpooler/res/values-mr/strings.xml +++ b/packages/PrintSpooler/res/values-mr/strings.xml @@ -47,7 +47,7 @@ "पीडीएफ वर सेव्ह करा" "प्रिंट पर्याय विस्तृत झाले" "प्रिंट पर्याय संक्षिप्त झाले" - "शोध" + "Search" "सर्व प्रिंटर" "सेवा जोडा" "शोध बॉक्स दर्शविला" diff --git a/packages/PrintSpooler/res/values-or/strings.xml b/packages/PrintSpooler/res/values-or/strings.xml index a1675fa7ca76..7000b95b35d6 100644 --- a/packages/PrintSpooler/res/values-or/strings.xml +++ b/packages/PrintSpooler/res/values-or/strings.xml @@ -47,7 +47,7 @@ "PDFରେ ସେଭ୍‍ କରନ୍ତୁ" "ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ବଡ଼ କରାଯାଇଛି" "ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ଛୋଟ କରାଯାଇଛି" - "ସର୍ଚ୍ଚ କରନ୍ତୁ" + "Search" "ସମସ୍ତ ପ୍ରିଣ୍ଟର୍‌" "ସେବା ଯୋଗ କରନ୍ତୁ" "ସର୍ଚ୍ଚ ବକ୍ସ ଦେଖାଯାଇଛି" diff --git a/packages/PrintSpooler/res/values-te/strings.xml b/packages/PrintSpooler/res/values-te/strings.xml index b01b50a60f6b..79944bb9994c 100644 --- a/packages/PrintSpooler/res/values-te/strings.xml +++ b/packages/PrintSpooler/res/values-te/strings.xml @@ -47,7 +47,7 @@ "PDF వలె సేవ్ చేయి" "ముద్రణ ఎంపికలు విస్తరించబడ్డాయి" "ముద్రణ ఎంపికలు కుదించబడ్డాయి" - "వెతుకు" + "సెర్చ్" "అన్ని ప్రింటర్‌లు" "సేవను జోడించు" "శోధన పెట్టె చూపబడింది" diff --git a/packages/PrintSpooler/res/values-uz/strings.xml b/packages/PrintSpooler/res/values-uz/strings.xml index d17bce7ae54e..ea0a6ea2f7b8 100644 --- a/packages/PrintSpooler/res/values-uz/strings.xml +++ b/packages/PrintSpooler/res/values-uz/strings.xml @@ -100,7 +100,7 @@ "Tik holat" - "Eniga" + "Yotiq" "Faylga yozib bo‘lmadi" "Xatolik yuz berdi. Qaytadan urining." -- GitLab From df13bb984bf0a66b5563522fb62a3280f0329128 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 26 Aug 2020 07:20:16 -0700 Subject: [PATCH 300/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I571d39cf61dc7a6ac968659e296b60f25b96f7b1 --- packages/SoundPicker/res/values-ar/strings.xml | 2 +- packages/SoundPicker/res/values-cs/strings.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/SoundPicker/res/values-ar/strings.xml b/packages/SoundPicker/res/values-ar/strings.xml index a91795545269..f8844e94815f 100644 --- a/packages/SoundPicker/res/values-ar/strings.xml +++ b/packages/SoundPicker/res/values-ar/strings.xml @@ -25,5 +25,5 @@ "حذف" "يتعذر إضافة نغمة رنين مخصصة" "يتعذر حذف نغمة الرنين المخصصة" - "Sounds" + "الأصوات" diff --git a/packages/SoundPicker/res/values-cs/strings.xml b/packages/SoundPicker/res/values-cs/strings.xml index e8fc97e44174..dc67c960cca9 100644 --- a/packages/SoundPicker/res/values-cs/strings.xml +++ b/packages/SoundPicker/res/values-cs/strings.xml @@ -16,14 +16,14 @@ - "Výchozí vyzváněcí tón" + "Výchozí vyzvánění" "Výchozí zvuk oznámení" "Výchozí zvuk budíku" - "Přidat vyzváněcí tón" + "Přidat vyzvánění" "Přidat budík" "Přidat oznámení" "Smazat" - "Vlastní vyzváněcí tón se nepodařilo přidat" - "Vlastní vyzváněcí tón se nepodařilo smazat" + "Vlastní vyzvánění se nepodařilo přidat" + "Vlastní vyzvánění se nepodařilo smazat" "Zvuky" -- GitLab From fb00462317ed3b5b50458d939629722624e3edd5 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 26 Aug 2020 07:47:47 -0700 Subject: [PATCH 301/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ie37bc4d2eaf2013f1a0b0cdb81e0521dc4633cd9 --- packages/Shell/res/values-bn/strings.xml | 47 ++++++++++++++++++++++++ packages/Shell/res/values-eu/strings.xml | 47 ++++++++++++++++++++++++ packages/Shell/res/values-gl/strings.xml | 47 ++++++++++++++++++++++++ packages/Shell/res/values-is/strings.xml | 47 ++++++++++++++++++++++++ packages/Shell/res/values-ky/strings.xml | 47 ++++++++++++++++++++++++ packages/Shell/res/values-mk/strings.xml | 47 ++++++++++++++++++++++++ packages/Shell/res/values-ml/strings.xml | 47 ++++++++++++++++++++++++ packages/Shell/res/values-mr/strings.xml | 47 ++++++++++++++++++++++++ packages/Shell/res/values-my/strings.xml | 47 ++++++++++++++++++++++++ packages/Shell/res/values-ta/strings.xml | 47 ++++++++++++++++++++++++ 10 files changed, 470 insertions(+) create mode 100644 packages/Shell/res/values-bn/strings.xml create mode 100644 packages/Shell/res/values-eu/strings.xml create mode 100644 packages/Shell/res/values-gl/strings.xml create mode 100644 packages/Shell/res/values-is/strings.xml create mode 100644 packages/Shell/res/values-ky/strings.xml create mode 100644 packages/Shell/res/values-mk/strings.xml create mode 100644 packages/Shell/res/values-ml/strings.xml create mode 100644 packages/Shell/res/values-mr/strings.xml create mode 100644 packages/Shell/res/values-my/strings.xml create mode 100644 packages/Shell/res/values-ta/strings.xml diff --git a/packages/Shell/res/values-bn/strings.xml b/packages/Shell/res/values-bn/strings.xml new file mode 100644 index 000000000000..ede125bce935 --- /dev/null +++ b/packages/Shell/res/values-bn/strings.xml @@ -0,0 +1,47 @@ + + + + + "শেল" + "ত্রুটির প্রতিবেদন" + "ত্রুটির প্রতিবেদন #%d তৈরি করা হচ্ছে" + "ত্রুটির প্রতিবেদন #%d ক্যাপচার করা হয়েছে" + "ত্রুটির প্রতিবেদনে বিশদ বিবরণ যোগ করা হচ্ছে" + "অনুগ্রহ করে অপেক্ষা করুন..." + "ফোনে শীঘ্রই ত্রুটির প্রতিবেদন দেখা যাবে" + "ত্রুটির প্রতিবেদনটি শেয়ার করতে এটি বেছে নিন" + "আপনার ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন" + "কোনো স্ক্রিনশট ছাড়াই ত্রুটির প্রতিবেদনটি শেয়ার করতে এটি বেছে নিন, বা স্ক্রিনশটের জন্য অপেক্ষা করুন" + "কোনও স্ক্রিনশট ছাড়াই ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন বা সম্পন্ন করতে স্ক্রিনশটের জন্য অপেক্ষা করুন" + "কোনও স্ক্রিনশট ছাড়াই ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন বা সম্পন্ন করতে স্ক্রিনশটের জন্য অপেক্ষা করুন" + "ত্রুটির প্রতিবেদনগুলিতে থাকা ডেটা, সিস্টেমের বিভিন্ন লগ ফাইলগুলি থেকে আসে, যাতে আপনার বিবেচনা অনুযায়ী সংবেদনশীল ডেটা (যেমন, অ্যাপ্লিকেশানের ব্যবহার এবং লোকেশন ডেটা) থাকতে পারে৷ আপনি বিশ্বাস করেন শুধুমাত্র এমন অ্যাপ্লিকেশান এবং ব্যক্তিদের সাথেই ত্রুটির প্রতিবেদনগুলিকে শেয়ার করুন৷" + "আর দেখাবেন না" + "ত্রুটির প্রতিবেদনগুলি" + "ত্রুটির প্রতিবেদনের ফাইলটি পড়া যায়নি" + "জিপ ফাইলে ত্রুটি প্রতিবেদনের বিশদ বিবরণ যোগ করা যায়নি" + "নামবিহীন" + "বিশদ বিবরণ" + "স্ক্রিনশট নিন" + "স্ক্রিনশট সফলভাবে নেওয়া হয়েছে৷" + "স্ক্রিনশট নেওয়া যায়নি৷" + "ত্রুটির প্রতিবেদন #%d এর বিশদ বিবরণ" + "ফাইলের নাম" + "ত্রুটির শীর্ষক" + "ত্রুটির সারাংশ" + "সেভ করুন" + "ত্রুটির প্রতিবেদন শেয়ার করুন" + diff --git a/packages/Shell/res/values-eu/strings.xml b/packages/Shell/res/values-eu/strings.xml new file mode 100644 index 000000000000..5d32cabd4ba5 --- /dev/null +++ b/packages/Shell/res/values-eu/strings.xml @@ -0,0 +1,47 @@ + + + + + "Shell" + "Akatsen txostenak" + "Akatsen #%d txostena egiten ari gara" + "Akatsen #%d txostena egin da" + "Akatsen txostenean xehetasunak gehitzen" + "Itxaron, mesedez…" + "Akatsen txostena telefonoan agertuko da laster" + "Hautatu hau akatsen txostena partekatzeko" + "Sakatu akatsen txostena partekatzeko" + "Hautatu hau akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte" + "Sakatu akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte" + "Sakatu akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte" + "Errore-txostenek sistemaren erregistro-fitxategietako datuak dauzkate, eta, haietan, kontuzkotzat jotzen duzun informazioa ager daiteke (adibidez, aplikazioen erabilera eta kokapen-datuak). Errore-txostenak partekatzen badituzu, partekatu soilik pertsona eta aplikazio fidagarriekin." + "Ez erakutsi berriro" + "Akatsen txostenak" + "Ezin izan da irakurri akatsen txostena" + "Ezin izan dira gehitu akatsen txostenaren xehetasunak ZIP fitxategian" + "izengabea" + "Xehetasunak" + "Pantaila-argazkia" + "Atera da pantaila-argazkia." + "Ezin izan da atera pantaila-argazkia." + "Akatsen #%d txostenaren xehetasunak" + "Fitxategi-izena" + "Akatsaren izena" + "Akatsaren laburpena" + "Gorde" + "Partekatu akatsen txostena" + diff --git a/packages/Shell/res/values-gl/strings.xml b/packages/Shell/res/values-gl/strings.xml new file mode 100644 index 000000000000..912dc85e15e4 --- /dev/null +++ b/packages/Shell/res/values-gl/strings.xml @@ -0,0 +1,47 @@ + + + + + "Shell" + "Informes de erros" + "Estase xerando o informe de erros #%d" + "Rexistrouse o informe de erros #%d" + "Engadindo detalles ao informe de erro" + "Agarda..." + "O informe de erros aparecerá no teléfono en breve" + "Selecciona para compartir o teu informe de erros" + "Toca para compartir o teu informe de erros" + "Selecciona para compartir o informe de erros sen captura de pantalla ou agarda a que acabe a captura" + "Toca para compartir o informe de erros sen captura de pantalla ou agarda a que finalice a captura" + "Toca para compartir o informe de erros sen captura de pantalla ou agarda a que finalice a captura" + "Os informes de erros conteñen datos dos distintos ficheiros de rexistro do sistema, os cales poden incluír datos que consideres confidenciais (coma o uso de aplicacións e os datos de localización). Comparte os informes de erros só coas persoas e aplicacións nas que confíes." + "Non mostrar outra vez" + "Informes de erros" + "Non se puido ler o ficheiro de informe de erros" + "Non se puideron engadir os detalles do informe de erro ao ficheiro zip" + "sen nome" + "Detalles" + "Captura de pantalla" + "A captura de pantalla realizouse correctamente." + "Non se puido realizar a captura de pantalla." + "Detalles do informe de erros #%d" + "Nome do ficheiro" + "Título do informe de erros" + "Resumo do informe de erros" + "Gardar" + "Compartir informe de erros" + diff --git a/packages/Shell/res/values-is/strings.xml b/packages/Shell/res/values-is/strings.xml new file mode 100644 index 000000000000..4989e8763b4d --- /dev/null +++ b/packages/Shell/res/values-is/strings.xml @@ -0,0 +1,47 @@ + + + + + "Skipanalína" + "Villutilkynningar" + "Verið er að búa til villutilkynningu #%d" + "Villutilkynning #%d búin til" + "Bætir upplýsingum við villutilkynningu" + "Augnablik..." + "Villuskýrslan birtist brátt í símanum" + "Veldu að deila villutilkynningunni" + "Ýttu til að deila villutilkynningunni" + "Veldu að deila villutilkynningunni án skjámyndar eða hinkraðu þangað til skjámyndin er tilbúin" + "Ýttu til að deila villutilkynningunni án skjámyndar eða hinkraðu þangað til skjámyndin er tilbúin" + "Ýttu til að deila villutilkynningunni án skjámyndar eða hinkraðu þangað til skjámyndin er tilbúin" + "Villutilkynningar innihalda gögn úr ýmsum annálaskrám kerfisins sem gætu innihaldið upplýsingar sem þú telur viðkvæmar (til dæmis notkun forrita og staðsetningarupplýsingar). Deildu villutilkynningum bara með fólki og forritum sem þú treystir." + "Ekki sýna þetta aftur" + "Villutilkynningar" + "Ekki var hægt að lesa úr villuskýrslunni" + "Ekki tókst að bæta upplýsingum um villutilkynningu við ZIP-skrá" + "án heitis" + "Nánar" + "Skjámynd" + "Skjámynd tekin." + "Ekki tókst að taka skjámynd." + "Upplýsingar villutilkynningar #%d" + "Skráarheiti" + "Heiti villu" + "Villusamantekt" + "Vista" + "Deila villutilkynningu" + diff --git a/packages/Shell/res/values-ky/strings.xml b/packages/Shell/res/values-ky/strings.xml new file mode 100644 index 000000000000..3567ac276e63 --- /dev/null +++ b/packages/Shell/res/values-ky/strings.xml @@ -0,0 +1,47 @@ + + + + + "Кабык" + "Мүчүлүштүк тууралуу кабар берүүлөр" + "Мүчүлүштүк тууралуу билдирүү #%d түзүлүүдө" + "Мүчүлүштүк тууралуу билдирүү #%d жаздырылды" + "Мүчүлүштүк жөнүндө кабардын чоо-жайы кошулууда" + "Күтө туруңуз…" + "Мүчүлүштүктөр жөнүндө кабар жакында телефонго чыгат" + "Мүчүлүштүк тууралуу кабарды жөнөтүү үчүн таптап коюңуз" + "Мүчүлүштүк тууралуу билдирүүңүздү бөлүшүү үчүн таптап коюңуз" + "Мүчүлүштүк тууралуу кабарды скриншотсуз жөнөтүү үчүн солго серпиңиз же скриншот даяр болгуча күтүңүз" + "Мүчүлүштүк тууралуу билдирүүңүздү скриншотсуз бөлүшүү үчүн таптап коюңуз же скриншот даяр болгуча күтө туруңуз" + "Мүчүлүштүк тууралуу билдирүүңүздү скриншотсуз бөлүшүү үчүн таптап коюңуз же скриншот даяр болгуча күтө туруңуз" + "Мүчүлүштүктөр тууралуу билдирүүлөрдө тутумдун ар кандай таржымалдарынан алынган дайындар, ошондой эле купуя маалымат камтылышы мүмкүн (мисалы, жайгашкан жер сыяктуу). Мындай билдирүүлөрдү бир гана ишеничтүү адамдар жана колдонмолор менен бөлүшүңүз." + "Экинчи көрүнбөсүн" + "Мүчүлүштүктөрдү кабарлоо" + "Мүчүлүштүк тууралуу кабарлаган файл окулбай койду" + "Мүчүлүштүктөр жөнүндө кабардын чоо-жайы zip файлына кошулбай койду" + "аталышы жок" + "Чоо-жайы" + "Скриншот" + "Скриншот ийгиликтүү тартылды." + "Скриншот тартылбай койду." + "Мүчүлүштүк тууралуу билдирүүнүн #%d чоо-жайы" + "Файлдын аталышы" + "Мүчүлүштүктүн аталышы" + "Мүчүлүштүк корутундусу" + "Сактоо" + "Мүчүлүштүк тууралуу кабарлоо" + diff --git a/packages/Shell/res/values-mk/strings.xml b/packages/Shell/res/values-mk/strings.xml new file mode 100644 index 000000000000..3d18d30715c2 --- /dev/null +++ b/packages/Shell/res/values-mk/strings.xml @@ -0,0 +1,47 @@ + + + + + "Shell" + "Извештаи за грешки" + "Се генерира извештајот за грешки #%d" + "Извештајот за грешки #%d е снимен" + "Се додаваат детали на извештајот за грешка" + "Почекајте..." + "Извештајот за грешки наскоро ќе се појави на телефонот" + "Изберете да го споделите извештајот за грешки" + "Допрете за да го споделите извештајот за грешки" + "Изберете да го спод. извештајот за грешки без слика од екранот или почекајте да се подготви сликата" + "Допрете за споделување извештај за грешки без слика од екранот или почекајте да се подготви сликата" + "Допрете за споделување извештај за грешки без слика од екранот или почекајте да се подготви сликата" + "Извештаите за грешка содржат податоци од разни датотеки за евиденција на системот, вклучувајќи и податоци што можеби ги сметате за чувствителни (како што се користење на апликациите и податоци за локацијата). Извештаите за грешки споделувајте ги само со апликации и луѓе во кои имате доверба." + "Не покажувај повторно" + "Извештаи за грешки" + "Датотеката со извештај за грешка не можеше да се прочита" + "Не можевме да ги додадеме деталите на извештајот за грешки во zip-датотеката" + "неименувани" + "Детали" + "Слика од екранот" + "Успешно е направена слика од екранот." + "Не може да се направи слика од екранот." + "Детали за извештајот за грешки #%d" + "Име на датотека" + "Наслов на грешката" + "Преглед на грешката" + "Зачувај" + "Споделете извештај за грешки" + diff --git a/packages/Shell/res/values-ml/strings.xml b/packages/Shell/res/values-ml/strings.xml new file mode 100644 index 000000000000..78b43bbe3d7b --- /dev/null +++ b/packages/Shell/res/values-ml/strings.xml @@ -0,0 +1,47 @@ + + + + + "ഷെൽ" + "ബഗ് റിപ്പോർട്ടുകൾ" + "ബഗ് റിപ്പോർട്ട് #%d സൃഷ്ടിക്കുന്നു" + "ബഗ് റിപ്പോർട്ട് #%d ക്യാപ്ചർ ചെയ്തു" + "ബഗ് റിപ്പോർട്ടിലേക്ക് വിശദാംശങ്ങൾ ചേർക്കുന്നു" + "കാത്തിരിക്കുക..." + "ബഗ് റിപ്പോർട്ട് താമസിയാതെ ഫോണിൽ ദൃശ്യമാകും" + "നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടുന്നതിന് തിരഞ്ഞെടുക്കുക" + "നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക" + "സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ ബഗ് റിപ്പോർട്ട് പങ്കിടുക" + "സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക" + "സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക" + "ബഗ് റിപ്പോർട്ടുകളിൽ സിസ്റ്റത്തിന്റെ നിരവധി ലോഗ് ഫയലുകളിൽ നിന്നുള്ള വിവരങ്ങൾ അടങ്ങിയിരിക്കുന്നു, ഇതിൽ നിങ്ങൾ രഹസ്യ സ്വഭാവമുള്ളവയായി പരിഗണിക്കുന്ന വിവരങ്ങളും (ആപ്പ് ഉപയോഗ വിവരങ്ങൾ, ലൊക്കേഷൻ വിവരങ്ങൾ എന്നിവ പോലെ) ഉൾപ്പെടാം. നിങ്ങൾ വിശ്വസിക്കുന്ന ആപ്പുകൾക്കും ആളുകൾക്കും മാത്രം ബഗ് റിപ്പോർട്ടുകൾ പങ്കിടുക." + "വീണ്ടും കാണിക്കരുത്" + "ബഗ് റിപ്പോർട്ടുകൾ" + "ബഗ് റിപ്പോർട്ട് ഫയൽ വായിക്കാനായില്ല" + "സിപ്പ് ഫയലിലേക്ക് ബഗ് റിപ്പോർട്ട് വിശദാംശങ്ങൾ ചേർക്കാൻ കഴിഞ്ഞില്ല" + "പേരില്ലാത്തവർ" + "വിശദാംശങ്ങൾ" + "സ്‌ക്രീൻഷോട്ട്" + "സ്ക്രീൻഷോട്ട് എടുത്തു." + "സ്ക്രീൻഷോട്ട് എടുക്കാൻ കഴിഞ്ഞില്ല." + "ബഗ് റിപ്പോർട്ട് #%d വിശദാംശങ്ങൾ" + "ഫയല്‍നാമം" + "ബഗിന്റെ പേര്" + "ബഗ് സംഗ്രഹം" + "സംരക്ഷിക്കുക" + "ബഗ് റിപ്പോർട്ട് പങ്കിടുക" + diff --git a/packages/Shell/res/values-mr/strings.xml b/packages/Shell/res/values-mr/strings.xml new file mode 100644 index 000000000000..9595e28eb6e2 --- /dev/null +++ b/packages/Shell/res/values-mr/strings.xml @@ -0,0 +1,47 @@ + + + + + "शेल" + "बग रीपोर्ट" + "बग रीपोर्ट #%d तयार केला जात आहे" + "बग रीपोर्ट #%d कॅप्चर केला" + "दोष अहवालामध्‍ये तपशील जोडत आहे" + "कृपया प्रतीक्षा करा..." + "फोनवर बग रीपोर्ट लवकरच दिसेल" + "तुमचा बग रीपोर्ट शेअर करण्यासाठी निवडा" + "तुमचा बग रीपोर्ट शेअर करण्यासाठी टॅप करा" + "तुमचा बग रीपोर्ट स्क्रीनशॉटशिवाय शेअर करण्यासाठी टॅप करा किंवा स्क्रीनशॉट पूर्ण होण्याची प्रतीक्षा करा" + "स्क्रीनशॉट शिवाय तुमचा बग रीपोर्ट शेअर करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा" + "स्क्रीनशॉट शिवाय तुमचा बग रीपोर्ट शेअर करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा" + "बग रीपोर्टांमध्ये तुम्ही संवेदनशील (अ‍ॅप-वापर आणि स्थान डेटा यासारखा) डेटा म्हणून विचार करता त्या डेटाच्या समावेशासह सिस्टीमच्या विविध लॉग फायलींमधील डेटा असतो. ज्या लोकांवर आणि अ‍ॅपवर तुमचा विश्वास आहे केवळ त्यांच्यासह हा बग रीपोर्ट शेअर करा." + "पुन्हा दर्शवू नका" + "बग रीपोर्ट" + "बग रीपोर्ट फाईल वाचणे शक्य झाले नाही" + "झिप फाईल मध्ये बग रीपोर्ट तपशील जोडणे शक्य झाले नाही" + "अनामित" + "तपशील" + "स्क्रीनशॉट" + "स्क्रीनशॉट यशस्वीरित्या घेतला." + "स्क्रीनशॉट घेणे शक्य झाले नाही." + "बग रीपोर्ट #%d तपशील" + "फाईलनाव" + "दोष शीर्षक" + "दोष सारांश" + "सेव्ह करा" + "बग रीपोर्ट शेअर करा" + diff --git a/packages/Shell/res/values-my/strings.xml b/packages/Shell/res/values-my/strings.xml new file mode 100644 index 000000000000..2376ffd2b2cf --- /dev/null +++ b/packages/Shell/res/values-my/strings.xml @@ -0,0 +1,47 @@ + + + + + "အခွံ" + "ချွတ်ယွင်းမှု အစီရင်ခံစာများ" + "ချွတ်ယွင်းမှုအစီရင်ခံချက် #%d ကိုထုတ်နေပါသည်" + "ချွတ်ယွင်းမှုအစီရင်ခံချက် #%d ကိုရယူထားပြီးပါပြီ" + "ချွတ်ယွင်းချက်အစီရင်ခံချက်သို့ အသေးစိတ်များပေါင်းထည့်ရန်" + "ခေတ္တစောင့်ပါ..." + "ချွတ်ယွင်းချက်အစီရင်ခံစာကို မကြာခင် ဖုန်းထဲတွင် မြင်တွေ့ရပါလိမ့်မည်" + "ချွတ်ယွင်းချက်အစီရင်ခံစာကို မျှဝေရန် ရွေးချယ်ပါ" + "သင့်ချွတ်ယွင်းမှုအစီရင်ခံချက်ကို မျှဝေရန် တို့ပါ" + "ချွတ်ယွင်းမှုအစီရင်ခံစာကို ဖန်သားပြင်ပုံ မပါဘဲမျှဝေပါ (သို့) ဖန်သားပြင်ပုံ ရိုက်ပြီးသည်အထိ စောင့်ပါ" + "ချွတ်ယွင်းချက်အစီရင်ခံစာကို ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းမပါဘဲ မျှဝေရန် တို့ပါ သို့မဟုတ် ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ" + "ချွတ်ယွင်းချက်အစီရင်ခံစာကို ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းမပါဘဲ မျှဝေရန် တို့ပါ သို့မဟုတ် ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ" + "ချွတ်ယွင်းချက်အစီရင်ခံစာများတွင် သင့်အတွက် အရေးကြီးသည့် ဒေတာများ (အက်ပ်အသုံးပြုမှုနှင့် တည်နေရာအချက်အလက် ကဲ့သို့) ပါဝင်သည့် စနစ်၏မှတ်တမ်းဖိုင်မျိုးစုံပါဝင်ပါသည်။ ချွတ်ယွင်းချက်အစီရင်ခံစာများကို သင်ယုံကြည်စိတ်ချရသည့်လူများ၊ အက်ပ်များနှင့်သာ မျှဝေပါ။" + "နောက်ထပ်မပြပါနှင့်" + "ချွတ်ယွင်းမှု အစီရင်ခံစာများ" + "ချွတ်ယွင်းချက် အစီရင်ခံစာကို ဖတ်၍မရပါ" + "ဇစ်ဖိုင်သို့ ချွတ်ယွင်းချက် အစီရင်ခံစာအသေးစိတ် အချက်အလက်များကို ထည့်၍မရပါ" + "အမည်မဲ့" + "အသေးစိတ်များ" + "မျက်နှာပြင် လျှပ်တစ်ပြက်ပုံ" + "ဖန်သားပြင်ဓာတ်ပုံ အောင်မြင်စွာရိုက်ပြီးပါပြီ။" + "မျက်နှာပြင် လျှပ်တစ်ပြက်ပုံ မရိုက်နိုင်ပါ" + "ချွတ်ယွင်းမှုအစီရင်ခံချက် #%d အသေးစိတ်များ" + "ဖိုင်အမည်" + "ချွတ်ယွင်းချက် ခေါင်းစဉ်" + "ချွတ်ယွင်းချက် အကျဉ်းချုပ်" + "သိမ်းရန်" + "ချွတ်ယွင်းချက်မှတ်တမ်း မျှဝေပါ" + diff --git a/packages/Shell/res/values-ta/strings.xml b/packages/Shell/res/values-ta/strings.xml new file mode 100644 index 000000000000..a906abede3fd --- /dev/null +++ b/packages/Shell/res/values-ta/strings.xml @@ -0,0 +1,47 @@ + + + + + "ஷெல்" + "பிழை அறிக்கைகள்" + "பிழை அறிக்கை #%d உருவாக்கப்படுகிறது" + "பிழை அறிக்கை #%d எடுக்கப்பட்டது" + "பிழை அறிக்கையில் விவரங்களைச் சேர்க்கிறது" + "காத்திருக்கவும்…" + "பிழை அறிக்கை சிறிது நேரத்தில் மொபைலில் தோன்றும்" + "பிழை அறிக்கையைப் பகிர, தேர்ந்தெடுக்கவும்" + "பிழை அறிக்கையைப் பகிர, தட்டவும்" + "ஸ்கிரீன்ஷாட் இன்றி பிழை அறிக்கையை பகிர தேர்ந்தெடுக்கவும்/ஸ்கிரீன்ஷாட் முடியும்வரை காத்திருக்கவும்" + "ஸ்கிரீன்ஷாட் இல்லாமல் பிழை அறிக்கையைப் பகிர, தட்டவும் அல்லது ஸ்கிரீன்ஷாட் முடியும்வரை காத்திருக்கவும்" + "ஸ்கிரீன்ஷாட் இல்லாமல் பிழை அறிக்கையைப் பகிர, தட்டவும் அல்லது ஸ்கிரீன்ஷாட் முடியும்வரை காத்திருக்கவும்" + "பிழை அறிக்கைகளில் முறைமையின் பல்வேறு பதிவுக் கோப்புகளின் தரவு (இதில் முக்கியமானவை என நீங்கள் கருதும் பயன்பாடின் உபயோகம், இருப்பிடத் தரவு போன்றவை அடங்கும்) இருக்கும். நீங்கள் நம்பும் நபர்கள் மற்றும் பயன்பாடுகளுடன் மட்டும் பிழை அறிக்கைகளைப் பகிரவும்." + "மீண்டும் காட்டாதே" + "பிழை அறிக்கைகள்" + "பிழை அறிக்கையைப் படிக்க முடியவில்லை" + "பிழை அறிக்கை விவரங்களை ஜிப் கோப்பில் சேர்க்க முடியவில்லை" + "பெயரிடப்படாதது" + "விவரங்கள்" + "ஸ்கிரீன்ஷாட்" + "ஸ்கிரீன்ஷாட் எடுக்கப்பட்டது." + "ஸ்கிரீன் ஷாட்டை எடுக்க முடியவில்லை." + "பிழை அறிக்கை #%d இன் விவரங்கள்" + "கோப்புப்பெயர்" + "பிழை தலைப்பு" + "பிழை குறித்த சுருக்க விவரம்" + "சேமி" + "பிழை அறிக்கையைப் பகிர்" + -- GitLab From b3beae79aea336eb6f9587118a5eee8f77d41522 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Thu, 13 Aug 2020 11:52:50 -0700 Subject: [PATCH 302/536] audio: additional speakerphone and audio mode fixes - Do not re-evaluate speakerphone state when audio mode owner changes but the new mode is RINGTONE. - Do not log IN_COMMUNICATION mode timeout in case of playback or capture inactivity by mode owner if the owner has MODIFY_PHONE_STATE permission: in this case it is the telephony framework or the app in Dialer role managing the call on behalf of another app. Bug: 161564483 Test: manual regression test with cell and VoIP calls. Change-Id: I86b6d31a164461e143cc5cfc1369884ed14cc95a (cherry picked from commit 1536fc19e57c7ae5a03dd579db831b8e7b9b63c5) --- .../server/audio/AudioDeviceBroker.java | 8 +++-- .../android/server/audio/AudioService.java | 29 ++++++++++++------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index 45f95fd3f663..22b0aebca6c4 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -476,8 +476,8 @@ import java.util.concurrent.atomic.AtomicBoolean; sendIIMsgNoDelay(MSG_II_SET_HEARING_AID_VOLUME, SENDMSG_REPLACE, index, streamType); } - /*package*/ void postSetModeOwnerPid(int pid) { - sendIMsgNoDelay(MSG_I_SET_MODE_OWNER_PID, SENDMSG_REPLACE, pid); + /*package*/ void postSetModeOwnerPid(int pid, int mode) { + sendIIMsgNoDelay(MSG_I_SET_MODE_OWNER_PID, SENDMSG_REPLACE, pid, mode); } /*package*/ void postBluetoothA2dpDeviceConfigChange(@NonNull BluetoothDevice device) { @@ -949,7 +949,9 @@ import java.util.concurrent.atomic.AtomicBoolean; synchronized (mDeviceStateLock) { if (mModeOwnerPid != msg.arg1) { mModeOwnerPid = msg.arg1; - updateSpeakerphoneOn("setNewModeOwner"); + if (msg.arg2 != AudioSystem.MODE_RINGTONE) { + updateSpeakerphoneOn("setNewModeOwner"); + } if (mModeOwnerPid != 0) { mBtHelper.disconnectBluetoothSco(mModeOwnerPid); } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index c4eca605206d..e78638894914 100755 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3680,13 +3680,15 @@ public class AudioService extends IAudioService.Stub private final IBinder mCb; // To be notified of client's death private final int mPid; private final int mUid; - private String mPackage; + private final boolean mIsPrivileged; + private final String mPackage; private int mMode = AudioSystem.MODE_NORMAL; // Current mode set by this client - SetModeDeathHandler(IBinder cb, int pid, int uid, String caller) { + SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller) { mCb = cb; mPid = pid; mUid = uid; + mIsPrivileged = isPrivileged; mPackage = caller; } @@ -3698,12 +3700,13 @@ public class AudioService extends IAudioService.Stub if (index < 0) { Log.w(TAG, "unregistered setMode() client died"); } else { - newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid, mUid, TAG); + newModeOwnerPid = setModeInt( + AudioSystem.MODE_NORMAL, mCb, mPid, mUid, mIsPrivileged, TAG); } } // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all // SCO connections not started by the application changing the mode when pid changes - mDeviceBroker.postSetModeOwnerPid(newModeOwnerPid); + mDeviceBroker.postSetModeOwnerPid(newModeOwnerPid, AudioService.this.getMode()); } public int getPid() { @@ -3729,6 +3732,10 @@ public class AudioService extends IAudioService.Stub public String getPackage() { return mPackage; } + + public boolean isPrivileged() { + return mIsPrivileged; + } } /** @see AudioManager#setMode(int) */ @@ -3780,18 +3787,19 @@ public class AudioService extends IAudioService.Stub + " without permission or being mode owner"); return; } - newModeOwnerPid = setModeInt( - mode, cb, callingPid, Binder.getCallingUid(), callingPackage); + newModeOwnerPid = setModeInt(mode, cb, callingPid, Binder.getCallingUid(), + hasModifyPhoneStatePermission, callingPackage); } // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all // SCO connections not started by the application changing the mode when pid changes - mDeviceBroker.postSetModeOwnerPid(newModeOwnerPid); + mDeviceBroker.postSetModeOwnerPid(newModeOwnerPid, getMode()); } // setModeInt() returns a valid PID if the audio mode was successfully set to // any mode other than NORMAL. @GuardedBy("mDeviceBroker.mSetModeLock") - private int setModeInt(int mode, IBinder cb, int pid, int uid, String caller) { + private int setModeInt( + int mode, IBinder cb, int pid, int uid, boolean isPrivileged, String caller) { if (DEBUG_MODE) { Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid + ", uid=" + uid + ", caller=" + caller + ")"); @@ -3843,7 +3851,7 @@ public class AudioService extends IAudioService.Stub } } else { if (hdlr == null) { - hdlr = new SetModeDeathHandler(cb, pid, uid, caller); + hdlr = new SetModeDeathHandler(cb, pid, uid, isPrivileged, caller); } // Register for client death notification try { @@ -3902,7 +3910,8 @@ public class AudioService extends IAudioService.Stub // change of mode may require volume to be re-applied on some devices updateAbsVolumeMultiModeDevices(oldMode, actualMode); - if (actualMode == AudioSystem.MODE_IN_COMMUNICATION) { + if (actualMode == AudioSystem.MODE_IN_COMMUNICATION + && !hdlr.isPrivileged()) { sendMsg(mAudioHandler, MSG_CHECK_MODE_FOR_UID, SENDMSG_QUEUE, -- GitLab From 4bd9165371c93dc55d497ef0b66365f2f1f76693 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Tue, 25 Aug 2020 17:49:15 -0700 Subject: [PATCH 303/536] audio service: add watchdog for audio mode Add a watchdog to remove an application from the audio mode owner stack if it has requested mode IN_COMMUNICATION and has not been playing or capturing audio for more than 3 seconds. This will prevent volume, routing and recording issues when misbehaving apps do not properly reset the audio mode at the end of a call. Bug: 161564483 Test: Manual regression tests for VoIP use cases Change-Id: I7c6f57a2c9a6c31d107a1bba2d7dfac6e3f275bd (cherry picked from commit 852cd7d7d4734081162ea7be8650bbbcfd3a862b) --- services/core/java/com/android/server/audio/AudioService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index e78638894914..fe619690ae34 100755 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -6428,8 +6428,8 @@ public class AudioService extends IAudioService.Stub CHECK_MODE_FOR_UID_PERIOD_MS); break; } - // For now just log the fact that an app is hogging the audio mode. - // TODO(b/160260850): remove abusive app from audio mode stack. + setModeInt(AudioSystem.MODE_NORMAL, h.getBinder(), h.getPid(), h.getUid(), + h.isPrivileged(), "MSG_CHECK_MODE_FOR_UID"); mModeLogger.log(new PhoneStateEvent(h.getPackage(), h.getPid())); } break; -- GitLab From 1706bc0e663a496c4e1bb8699e4e921ac7af6dc6 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 26 Aug 2020 08:15:26 -0700 Subject: [PATCH 304/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I680e11f9104681ffc733c3faaef1f6c67406551c --- packages/SystemUI/res/values-az/strings.xml | 2 +- packages/SystemUI/res/values-cs/strings.xml | 2 +- packages/SystemUI/res/values-eu/strings.xml | 2 +- packages/SystemUI/res/values-ms/strings.xml | 2 +- packages/SystemUI/res/values-ne/strings.xml | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 32c2e9c2d45e..933bb044b5dc 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -403,7 +403,7 @@ %d cihaz "Bildirişlər" - "İşartı" + "Fənər" "Kamera istifadə olunur" "Mobil data" "Data istifadəsi" diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 4b1e733751ff..9d661badd48e 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -95,7 +95,7 @@ "Při nahrávání může systém Android zaznamenávat citlivé údaje, které jsou viditelné na obrazovce nebo které jsou přehrávány na zařízení. Týká se to hesel, údajů o platbě, fotek, zpráv a zvuků." "Nahrát zvuk" "Zvuk zařízení" - "Zvuk ze zařízení, například hudba, hovory a vyzváněcí tóny" + "Zvuk ze zařízení, například hudba, hovory a vyzvánění" "Mikrofon" "Zvuk a mikrofon zařízení" "Spustit" diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index e4b63c8dfd87..9598ddddb8f7 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -552,7 +552,7 @@ "%1$s aplikaziora konektatuta zaude eta hark sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne." "%1$s eta %2$s aplikazioetara konektatuta zaude, eta haiek sareko jarduerak gainbegira ditzakete, mezu elektronikoak, aplikazioak eta webguneak barne." "%1$s aplikaziora dago konektatuta laneko profila, eta aplikazio horrek sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne." - "%1$s aplikaziora konektatuta duzu profil pertsonala, eta aplikazio horrek sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne." + "%1$s aplikaziora konektatuta daukazu profil pertsonala, eta aplikazio horrek sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne." "%1$s aplikazioak kudeatzen du gailu hau." "%1$s erakundeak %2$s erabiltzen du gailua kudeatzeko." "Gailuko ezarpenak, enpresa-sarbidea, aplikazioak eta datuak gainbegira eta kudea ditzake administratzaileak, baita gailuaren kokapen-informazioa ere." diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 789525450c23..b16427624cc6 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -403,7 +403,7 @@ %d peranti "Pemberitahuan" - "Lampu suluh" + "Lampu Suluh" "Kamera sedang digunakan" "Data mudah alih" "Penggunaan data" diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 7b84193632dc..f003d270549c 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -500,8 +500,8 @@ "ब्याट्री सेभर अन छ" "प्रदर्शन र पृष्ठभूमि डेटा घटाउँनुहोस्" "ब्याट्री सेभर अफ गर्नुहोस्" - "%s ले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, तस्बिर, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।" - "यो कार्य प्रदान गर्ने सेवाले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, तस्बिर, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।" + "%s ले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, फोटो, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।" + "यो कार्य प्रदान गर्ने सेवाले तपाईंको स्क्रिनमा देख्न सकिने सबै जानकारी अथवा रेकर्ड वा cast गर्दा तपाईंको यन्त्रबाट प्ले गरिएका कुरामाथि पहुँच राख्न सक्ने छ। यसअन्तर्गत पासवर्ड, भुक्तानीका विवरण, फोटो, सन्देश र तपाईंले प्ले गर्ने अडियो जस्ता जानकारी समावेश हुन्छन्।" "रेकर्ड गर्न वा cast गर्न थाल्ने हो?" "%s मार्फत रेकर्ड गर्न वा cast गर्न थाल्ने हो?" "फेरि नदेखाउनुहोस्" @@ -714,7 +714,7 @@ "फोनको सेटिङका आधारमा घन्टी बज्न वा कम्पन हुन सक्छ" "फोनको सेटिङका आधारमा घन्टी बज्न वा कम्पन हुन सक्छ। %1$s का वार्तालापहरू पूर्वनिर्धारित रूपमा बबलमा देखाइन्छन्।" "फ्लोटिङ सर्टकटमार्फत यो सामग्रीतर्फ तपाईंको ध्यान आकर्षित गर्दछ।" - "वार्तालाप खण्डको सिरानमा देखा पर्छ, तैरने बबलका रूपमा देखा पर्छ, लक स्क्रिनमा प्रोफाइल तस्बिर देखाइन्छ" + "वार्तालाप खण्डको सिरानमा देखा पर्छ, तैरने बबलका रूपमा देखा पर्छ, लक स्क्रिनमा प्रोफाइल फोटो देखाइन्छ" "सेटिङ" "प्राथमिकता" "%1$s मा वार्तालापसम्बन्धी सुविधा प्रयोग गर्न मिल्दैन" @@ -1024,7 +1024,7 @@ "वार्तालापको प्राथमिकता निर्धारण गरी \"महत्त्वपूर्ण\" बनाइयो" "महत्वपूर्ण वार्तालापहरू:" "वार्तालाप खण्डको सिरानमा देखिने छन्" - "लक स्क्रिनमा प्रोफाइल तस्बिर देखाउने छन्" + "लक स्क्रिनमा प्रोफाइल फोटो देखाउने छन्" "एपहरूमाथि तैरिने बबलका रूपमा देखाइयोस्" "बाधा नपुऱ्याउनुहोस् मोडलाई बेवास्ता गरियोस्" "बुझेँ" -- GitLab From 80951fa9a8f77685d3845c14c2e0de364787b2cc Mon Sep 17 00:00:00 2001 From: arthurhung Date: Tue, 11 Aug 2020 23:07:00 +0800 Subject: [PATCH 305/536] Introduce INPUT_CONSUMER permission for InputConsumer Add the permission protect to createInputConsumer/destoryInputConsumer in WindowManagerService to prevent it is possible for an app to consume all the touch events and deny them from even reaching System UI. Also fix the wallpaper inputconsumer should only show when we found a visible wallpaper window. Also limit 'createInputConsumer' to the defined types. Test: atest PermissionPolicyTest Test: ceate/destory an inputconsumer and test input Fix: 162324374 Merged-In: I7a4c2c4cba7ea670873ab2ac49b9880d9a65cd86 Change-Id: I7a4c2c4cba7ea670873ab2ac49b9880d9a65cd86 (cherry picked from commit 0d0ad1b60b3d9ed08b1df0b3a903af332568cd04) --- core/res/AndroidManifest.xml | 4 ++++ packages/SystemUI/AndroidManifest.xml | 1 + .../java/com/android/server/wm/InputMonitor.java | 13 ++++++++++--- .../com/android/server/wm/WindowManagerService.java | 11 +++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index d0ca0a86efb0..6a92a83c9899 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -5036,6 +5036,10 @@ + + + diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 7b8aba451e27..c4cf45fd273e 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -113,6 +113,7 @@ + diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 0216db471843..3663ee14ea99 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -219,6 +219,11 @@ final class InputMonitor { WindowManagerPolicy.InputConsumer createInputConsumer(Looper looper, String name, InputEventReceiver.Factory inputEventReceiverFactory) { + if (!name.contentEquals(INPUT_CONSUMER_NAVIGATION)) { + throw new IllegalArgumentException("Illegal input consumer : " + name + + ", display: " + mDisplayId); + } + if (mInputConsumers.containsKey(name)) { throw new IllegalStateException("Existing input consumer found with name: " + name + ", display: " + mDisplayId); @@ -248,6 +253,11 @@ final class InputMonitor { // stack, and we need FLAG_NOT_TOUCH_MODAL to ensure other events fall through consumer.mWindowHandle.layoutParamsFlags |= FLAG_NOT_TOUCH_MODAL; break; + case INPUT_CONSUMER_RECENTS_ANIMATION: + break; + default: + throw new IllegalArgumentException("Illegal input consumer : " + name + + ", display: " + mDisplayId); } addInputConsumer(name, consumer); } @@ -459,9 +469,6 @@ final class InputMonitor { mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */); - if (mAddWallpaperInputConsumerHandle) { - mWallpaperInputConsumer.show(mInputTransaction, 0); - } if (!mUpdateInputWindowsImmediately) { mDisplayContent.getPendingTransaction().merge(mInputTransaction); mDisplayContent.scheduleAnimation(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index b7ac54f3470e..ea71ed12b81e 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; +import static android.Manifest.permission.INPUT_CONSUMER; import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.MANAGE_APP_TOKENS; @@ -5869,6 +5870,11 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void createInputConsumer(IBinder token, String name, int displayId, InputChannel inputChannel) { + if (!mAtmInternal.isCallerRecents(Binder.getCallingUid()) + && mContext.checkCallingOrSelfPermission(INPUT_CONSUMER) != PERMISSION_GRANTED) { + throw new SecurityException("createInputConsumer requires INPUT_CONSUMER permission"); + } + synchronized (mGlobalLock) { DisplayContent display = mRoot.getDisplayContent(displayId); if (display != null) { @@ -5880,6 +5886,11 @@ public class WindowManagerService extends IWindowManager.Stub @Override public boolean destroyInputConsumer(String name, int displayId) { + if (!mAtmInternal.isCallerRecents(Binder.getCallingUid()) + && mContext.checkCallingOrSelfPermission(INPUT_CONSUMER) != PERMISSION_GRANTED) { + throw new SecurityException("destroyInputConsumer requires INPUT_CONSUMER permission"); + } + synchronized (mGlobalLock) { DisplayContent display = mRoot.getDisplayContent(displayId); if (display != null) { -- GitLab From 54602827931c88662c42a3df795b9c68e24616d4 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Wed, 26 Aug 2020 09:41:34 -0700 Subject: [PATCH 306/536] Remove entry from mLastReportedWindowingMode on destroy Bug: 166456665 Test: atest ActivityLifecyclePipTests \ ActivityLifecycleSplitScreenTests \ ActivityLifecycleTopResumedStateTests \ PinnedStackTests\ SplitScreenTests \ ActivityLifecycleKeyguardTests Change-Id: If2cf664bdb62ac3082c02d2c6c1ad74b10761f62 --- core/java/android/app/ActivityThread.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 812ca4aefb9b..8d64661ef8a6 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -5112,6 +5112,7 @@ public final class ActivityThread extends ClientTransactionHandler { } } r.setState(ON_DESTROY); + mLastReportedWindowingMode.remove(r.activity.getActivityToken()); } schedulePurgeIdler(); // updatePendingActivityConfiguration() reads from mActivities to update -- GitLab From eb7103fd56cbc25154134f9472b824961a9f0267 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 26 Aug 2020 10:32:17 -0700 Subject: [PATCH 307/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I46e0ee47b7807145bbba442e324f1443ce784a02 --- packages/SystemUI/res-product/values-in/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/res-product/values-in/strings.xml b/packages/SystemUI/res-product/values-in/strings.xml index 2e0580f568f9..1451e2c063c9 100644 --- a/packages/SystemUI/res-product/values-in/strings.xml +++ b/packages/SystemUI/res-product/values-in/strings.xml @@ -26,10 +26,10 @@ "Tidak ada kartu SIM dalam tablet." "Tidak ada kartu SIM dalam ponsel." "Kode PIN tidak cocok" - "Anda telah %1$d kali berupaya membuka kunci tablet dengan tidak benar. Setelah %2$d lagi upaya yang tidak berhasil, tablet ini akan disetel ulang, sehingga semua datanya akan dihapus." - "Anda telah %1$d kali berupaya membuka kunci ponsel dengan tidak benar. Setelah %2$d lagi upaya yang tidak berhasil, ponsel ini akan disetel ulang, sehingga semua datanya akan dihapus." - "Anda telah %d kali berupaya membuka kunci tablet dengan tidak benar. Tablet ini akan disetel ulang, sehingga semua datanya akan dihapus." - "Anda telah %d kali berupaya membuka kunci ponsel dengan tidak benar. Ponsel ini akan disetel ulang, sehingga semua datanya akan dihapus." + "Anda telah %1$d kali berupaya membuka kunci tablet dengan tidak benar. Setelah %2$d lagi upaya yang tidak berhasil, tablet ini akan direset, sehingga semua datanya akan dihapus." + "Anda telah %1$d kali berupaya membuka kunci ponsel dengan tidak benar. Setelah %2$d lagi upaya yang tidak berhasil, ponsel ini akan direset, sehingga semua datanya akan dihapus." + "Anda telah %d kali berupaya membuka kunci tablet dengan tidak benar. Tablet ini akan direset, sehingga semua datanya akan dihapus." + "Anda telah %d kali berupaya membuka kunci ponsel dengan tidak benar. Ponsel ini akan direset, sehingga semua datanya akan dihapus." "Anda telah %1$d kali berupaya membuka kunci tablet dengan tidak benar. Setelah %2$d lagi upaya yang tidak berhasil, pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus." "Anda telah %1$d kali berupaya membuka kunci ponsel dengan tidak benar. Setelah %2$d lagi upaya yang tidak berhasil, pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus." "Anda telah %d kali berupaya membuka kunci tablet dengan tidak benar. Pengguna ini akan dihapus, sehingga semua data pengguna akan dihapus." -- GitLab From 86bd39db3595842bae77abe7e768226e412591c8 Mon Sep 17 00:00:00 2001 From: Hui Yu Date: Thu, 6 Aug 2020 16:55:19 -0700 Subject: [PATCH 308/536] RESTRICT AUTOMERGE: Set mAllowWhileInUsePermissionInFgs correctly when bindService() from background. Pass original callingPid and callingUid into shouldAllowWhileInUsePermissionInFgsLocked() after Binder.clearCallingIdentity(). Bug: 163084228 Test: atest cts/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java#testFgsLocationStartFromBGWithBind Change-Id: I7a240621267648ea54e7dc737ebc55bc665e39b6 --- .../java/com/android/server/am/ActiveServices.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 3f867f656c24..dd0e1f6458f9 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -1836,11 +1836,13 @@ public final class ActiveServices { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service + " type=" + resolvedType + " conn=" + connection.asBinder() + " flags=0x" + Integer.toHexString(flags)); + final int callingPid = Binder.getCallingPid(); + final int callingUid = Binder.getCallingUid(); final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller); if (callerApp == null) { throw new SecurityException( "Unable to find app for caller " + caller - + " (pid=" + Binder.getCallingPid() + + " (pid=" + callingPid + ") when binding service " + service); } @@ -1880,19 +1882,19 @@ public final class ActiveServices { } if ((flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0 && !isCallerSystem) { - throw new SecurityException("Non-system caller (pid=" + Binder.getCallingPid() + throw new SecurityException("Non-system caller (pid=" + callingPid + ") set BIND_SCHEDULE_LIKE_TOP_APP when binding service " + service); } if ((flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0 && !isCallerSystem) { throw new SecurityException( - "Non-system caller " + caller + " (pid=" + Binder.getCallingPid() + "Non-system caller " + caller + " (pid=" + callingPid + ") set BIND_ALLOW_WHITELIST_MANAGEMENT when binding service " + service); } if ((flags & Context.BIND_ALLOW_INSTANT) != 0 && !isCallerSystem) { throw new SecurityException( - "Non-system caller " + caller + " (pid=" + Binder.getCallingPid() + "Non-system caller " + caller + " (pid=" + callingPid + ") set BIND_ALLOW_INSTANT when binding service " + service); } @@ -1908,7 +1910,7 @@ public final class ActiveServices { ServiceLookupResult res = retrieveServiceLocked(service, instanceName, resolvedType, callingPackage, - Binder.getCallingPid(), Binder.getCallingUid(), userId, true, + callingPid, callingUid, userId, true, callerFg, isBindExternal, allowInstant); if (res == null) { return 0; @@ -2068,7 +2070,7 @@ public final class ActiveServices { if (!s.mAllowWhileInUsePermissionInFgs) { s.mAllowWhileInUsePermissionInFgs = shouldAllowWhileInUsePermissionInFgsLocked(callingPackage, - Binder.getCallingPid(), Binder.getCallingUid(), + callingPid, callingUid, service, s, false); } -- GitLab From efc2cf9c4b5a3b5a3859a8e6e3b7f9d5cbc65e81 Mon Sep 17 00:00:00 2001 From: kwaky Date: Tue, 18 Aug 2020 17:06:36 -0700 Subject: [PATCH 309/536] Fix NotificationPanel animation jank. Bug: 162599873 Bug: 161172460 Test: Manual -- To repro the bug, swipe on the Notification cards in the closing direction. This should not in fact close the Notification Panel since the user's intent is to scroll the Notification cards, not to close the Notification panel. This also results in the animation jank. This behavior is no longer observed after this fix. Change-Id: I6144c064faf151a091ec66df4616036bf765e9fb --- .../NotificationPanelViewController.java | 9 +++-- .../window/OverlayPanelViewController.java | 35 +++++++++++++++++-- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java index 8d5843635e5f..8b4f69fcfa39 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java @@ -299,10 +299,10 @@ public class NotificationPanelViewController extends OverlayPanelViewController // The glass pane is used to view touch events before passed to the notification list. // This allows us to initialize gesture listeners and detect when to close the notifications glassPane.setOnTouchListener((v, event) -> { - if (event.getActionMasked() == MotionEvent.ACTION_UP) { + if (isClosingAction(event)) { mNotificationListAtEndAtTimeOfTouch = false; } - if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { + if (isOpeningAction(event)) { mFirstTouchDownOnGlassPane = event.getRawX(); mNotificationListAtEndAtTimeOfTouch = mNotificationListAtEnd; // Reset the tracker when there is a touch down on the glass pane. @@ -355,8 +355,7 @@ public class NotificationPanelViewController extends OverlayPanelViewController if (rect != null) { clippedHeight = rect.bottom; } - if (!handled && event.getActionMasked() == MotionEvent.ACTION_UP - && mIsSwipingVerticallyToClose) { + if (!handled && isClosingAction(event) && mIsSwipingVerticallyToClose) { if (getSettleClosePercentage() < getPercentageFromEndingEdge() && isTracking) { animatePanel(DEFAULT_FLING_VELOCITY, false); } else if (clippedHeight != getLayout().getHeight() && isTracking) { @@ -369,7 +368,7 @@ public class NotificationPanelViewController extends OverlayPanelViewController // Updating the mNotificationListAtEndAtTimeOfTouch state has to be done after // the event has been passed to the closeGestureDetector above, such that the // closeGestureDetector sees the up event before the state has changed. - if (event.getActionMasked() == MotionEvent.ACTION_UP) { + if (isClosingAction(event)) { mNotificationListAtEndAtTimeOfTouch = false; } return handled || isTracking; diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java index 45808a8a0b3e..bde31f18d8fd 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java @@ -191,6 +191,38 @@ public abstract class OverlayPanelViewController extends OverlayViewController { } } + /** Checks if a {@link MotionEvent} is an action to open the panel. + * @param e {@link MotionEvent} to check. + * @return true only if opening action. + */ + protected boolean isOpeningAction(MotionEvent e) { + if (mAnimateDirection == POSITIVE_DIRECTION) { + return e.getActionMasked() == MotionEvent.ACTION_DOWN; + } + + if (mAnimateDirection == NEGATIVE_DIRECTION) { + return e.getActionMasked() == MotionEvent.ACTION_UP; + } + + return false; + } + + /** Checks if a {@link MotionEvent} is an action to close the panel. + * @param e {@link MotionEvent} to check. + * @return true only if closing action. + */ + protected boolean isClosingAction(MotionEvent e) { + if (mAnimateDirection == POSITIVE_DIRECTION) { + return e.getActionMasked() == MotionEvent.ACTION_UP; + } + + if (mAnimateDirection == NEGATIVE_DIRECTION) { + return e.getActionMasked() == MotionEvent.ACTION_DOWN; + } + + return false; + } + /* ***************************************************************************************** * * Panel Animation * ***************************************************************************************** */ @@ -243,8 +275,7 @@ public abstract class OverlayPanelViewController extends OverlayViewController { * Depending on certain conditions, determines whether to fully expand or collapse the panel. */ protected void maybeCompleteAnimation(MotionEvent event) { - if (event.getActionMasked() == MotionEvent.ACTION_UP - && isPanelVisible()) { + if (isClosingAction(event) && isPanelVisible()) { if (mSettleClosePercentage < mPercentageFromEndingEdge) { animatePanel(DEFAULT_FLING_VELOCITY, false); } else { -- GitLab From ea9d40e140b34fc71502b3e656ac83274dfc6cf4 Mon Sep 17 00:00:00 2001 From: Sarah Chin Date: Wed, 12 Aug 2020 19:38:02 -0700 Subject: [PATCH 310/536] Add minimum bandwidth config for showing LTE+ data icon Only show the LTE+ icon if the combined channel bandwidth is greater than the valued defined. By default, the value is 20 MHz, and if there is no limit then the value should be 0. Test: atest NetworkTypeControllerTest Bug: 160873305 Change-Id: I4068860c5798f921fc198c095ba9b8f84ae5663b --- .../java/android/telephony/CarrierConfigManager.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 52f1e37e69f4..5d79775f686e 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1641,6 +1641,15 @@ public class CarrierConfigManager { public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL = "hide_lte_plus_data_icon_bool"; + /** + * The combined channel bandwidth threshold (non-inclusive) in KHz required to display the + * LTE+ data icon. It is 20000 by default, meaning the LTE+ icon will be shown if the device is + * using carrier aggregation and the combined channel bandwidth is strictly greater than 20 MHz. + * @hide + */ + public static final String KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT = + "lte_plus_threshold_bandwidth_khz_int"; + /** * The string is used to filter redundant string from PLMN Network Name that's supplied by * specific carrier. @@ -4211,6 +4220,7 @@ public class CarrierConfigManager { sDefaults.putString(KEY_OPERATOR_NAME_FILTER_PATTERN_STRING, ""); sDefaults.putString(KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING, ""); sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true); + sDefaults.putInt(KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT, 20000); sDefaults.putBoolean(KEY_NR_ENABLED_BOOL, true); sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true); sDefaults.putBoolean(KEY_SUPPORT_TDSCDMA_BOOL, false); -- GitLab From d6f2f7fc1192133b8b1e7204272cc181f8fe53ad Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Wed, 26 Aug 2020 11:24:31 -0700 Subject: [PATCH 311/536] Fix some notifications animation issues Fix notif animation to not repeat when the panel is fully open Fix notif animation when swiping the panel to close and it gets stuck Bug: 158306816 Test: manual Change-Id: Ia5ed0d9dca4e8366bd3f1526a3295464e3d06be4 --- .../NotificationPanelViewController.java | 9 ++++---- .../window/OverlayPanelViewController.java | 22 +++++++++++++------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java index 8d5843635e5f..2bcde9814b2e 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java @@ -91,7 +91,6 @@ public class NotificationPanelViewController extends OverlayPanelViewController private RecyclerView mNotificationList; private NotificationViewController mNotificationViewController; - private boolean mIsTracking; private boolean mNotificationListAtEnd; private float mFirstTouchDownOnGlassPane; private boolean mNotificationListAtEndAtTimeOfTouch; @@ -306,7 +305,7 @@ public class NotificationPanelViewController extends OverlayPanelViewController mFirstTouchDownOnGlassPane = event.getRawX(); mNotificationListAtEndAtTimeOfTouch = mNotificationListAtEnd; // Reset the tracker when there is a touch down on the glass pane. - mIsTracking = false; + setIsTracking(false); // Pass the down event to gesture detector so that it knows where the touch event // started. closeGestureDetector.onTouchEvent(event); @@ -341,15 +340,15 @@ public class NotificationPanelViewController extends OverlayPanelViewController // If the card is swiping we should not allow the notification shade to close. // Hence setting mNotificationListAtEndAtTimeOfTouch to false will stop that - // for us. We are also checking for mIsTracking because while swiping the + // for us. We are also checking for isTracking() because while swiping the // notification shade to close if the user goes a bit horizontal while swiping // upwards then also this should close. - if (mIsNotificationCardSwiping && !mIsTracking) { + if (mIsNotificationCardSwiping && !isTracking()) { mNotificationListAtEndAtTimeOfTouch = false; } boolean handled = closeGestureDetector.onTouchEvent(event); - boolean isTracking = mIsTracking; + boolean isTracking = isTracking(); Rect rect = getLayout().getClipBounds(); float clippedHeight = 0; if (rect != null) { diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java index 45808a8a0b3e..97890927a886 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java @@ -266,14 +266,17 @@ public abstract class OverlayPanelViewController extends OverlayViewController { float from = getCurrentStartPosition(rect); if (from != to) { animate(from, to, velocity, isClosing); - return; } + + // If we swipe down the notification panel all the way to the bottom of the screen + // (i.e. from == to), then we have finished animating the panel. + return; } // We will only be here if the shade is being opened programmatically or via button when // height of the layout was not calculated. - ViewTreeObserver notificationTreeObserver = getLayout().getViewTreeObserver(); - notificationTreeObserver.addOnGlobalLayoutListener( + ViewTreeObserver panelTreeObserver = getLayout().getViewTreeObserver(); + panelTreeObserver.addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { @@ -476,6 +479,11 @@ public abstract class OverlayPanelViewController extends OverlayViewController { return mIsTracking; } + /** Sets whether the panel is currently tracking or not. */ + protected final void setIsTracking(boolean isTracking) { + mIsTracking = isTracking; + } + /** Returns {@code true} if the panel is currently animating. */ protected final boolean isAnimating() { return mIsAnimating; @@ -514,7 +522,7 @@ public abstract class OverlayPanelViewController extends OverlayViewController { } setPanelVisible(true); - // clips the view for the notification shade when the user scrolls to open. + // clips the view for the panel when the user scrolls to open. setViewClipBounds((int) event2.getRawY()); // Initially the scroll starts with height being zero. This checks protects from divide @@ -569,11 +577,11 @@ public abstract class OverlayPanelViewController extends OverlayViewController { boolean isInClosingDirection = mAnimateDirection * distanceY > 0; // This check is to figure out if onScroll was called while swiping the card at - // bottom of the list. At that time we should not allow notification shade to + // bottom of the panel. At that time we should not allow panel to // close. We are also checking for the upwards swipe gesture here because it is - // possible if a user is closing the notification shade and while swiping starts + // possible if a user is closing the panel and while swiping starts // to open again but does not fling. At that time we should allow the - // notification shade to close fully or else it would stuck in between. + // panel to close fully or else it would stuck in between. if (Math.abs(getLayout().getHeight() - y) > SWIPE_DOWN_MIN_DISTANCE && isInClosingDirection) { setViewClipBounds((int) y); -- GitLab From a2673cdfd40db7e2f0f587df66502fdfa29333e3 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Tue, 25 Aug 2020 18:03:18 -0700 Subject: [PATCH 312/536] [DO NOT MERGE] Sync app requested orientation on PiP exit When exiting PiP to fullscreen, SysUI compares the initial rotation with the screen rotation and skips the animation if they are different, with the intention that the app should get back to its state prior to PiP. This generally works well except that app may request setRequestedOrientation after entering PiP and the initial rotation SysUI gets in onTaskAppeared would be obsoleted. This is fixed in this CL by - Adding a requestedOrientation field in TaskInfo to pass this information to SysUI, in both onTaskAppeared and onTaskInfoChanged callbacks - Sync with the requested orientation as well as display rotation on PiP exit. Moves also the information we need into PipWindowConfigurationCompact Video: http://rcll/aaaaaabFQoRHlzixHdtY/gOPXfx5KO9krmzeor49DgG Bug: 163218295 Test: See video Change-Id: Idd0b9412dfdfd6fd293a800cded7c7a6b94cafde --- core/java/android/app/TaskInfo.java | 12 ++- .../systemui/pip/PipTaskOrganizer.java | 27 ++++--- .../pip/PipWindowConfigurationCompact.java | 80 +++++++++++++++++++ .../core/java/com/android/server/wm/Task.java | 3 + .../server/wm/TaskOrganizerController.java | 3 +- 5 files changed, 112 insertions(+), 13 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/pip/PipWindowConfigurationCompact.java diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java index f3f00e50715b..f99d4e937f92 100644 --- a/core/java/android/app/TaskInfo.java +++ b/core/java/android/app/TaskInfo.java @@ -176,6 +176,13 @@ public class TaskInfo { */ public boolean isResizeable; + /** + * Screen orientation set by {@link #baseActivity} via + * {@link Activity#setRequestedOrientation(int)}. + * @hide + */ + public @ActivityInfo.ScreenOrientation int requestedOrientation; + TaskInfo() { // Do nothing } @@ -247,6 +254,7 @@ public class TaskInfo { ? ActivityInfo.CREATOR.createFromParcel(source) : null; isResizeable = source.readBoolean(); + requestedOrientation = source.readInt(); } /** @@ -297,6 +305,7 @@ public class TaskInfo { topActivityInfo.writeToParcel(dest, flags); } dest.writeBoolean(isResizeable); + dest.writeInt(requestedOrientation); } @Override @@ -315,6 +324,7 @@ public class TaskInfo { + " token=" + token + " topActivityType=" + topActivityType + " pictureInPictureParams=" + pictureInPictureParams - + " topActivityInfo=" + topActivityInfo; + + " topActivityInfo=" + topActivityInfo + + " requestedOrientation=" + requestedOrientation; } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index d19fc013bd8d..8d4ca5e46fae 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -40,7 +40,6 @@ import android.app.PictureInPictureParams; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; -import android.content.res.Configuration; import android.graphics.Rect; import android.os.Handler; import android.os.IBinder; @@ -104,7 +103,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements private final Rect mLastReportedBounds = new Rect(); private final int mEnterExitAnimationDuration; private final PipSurfaceTransactionHelper mSurfaceTransactionHelper; - private final Map mInitialState = new HashMap<>(); + private final Map mCompactState = new HashMap<>(); private final Divider mSplitDivider; // These callbacks are called on the update thread @@ -202,6 +201,8 @@ public class PipTaskOrganizer extends TaskOrganizer implements */ private boolean mShouldDeferEnteringPip; + private @ActivityInfo.ScreenOrientation int mRequestedOrientation; + @Inject public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler, @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper, @@ -281,11 +282,13 @@ public class PipTaskOrganizer extends TaskOrganizer implements mPipUiEventLoggerLogger.log( PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN); - final Configuration initialConfig = mInitialState.remove(mToken.asBinder()); - final boolean orientationDiffers = initialConfig.windowConfiguration.getRotation() + final PipWindowConfigurationCompact config = mCompactState.remove(mToken.asBinder()); + config.syncWithScreenOrientation(mRequestedOrientation, + mPipBoundsHandler.getDisplayRotation()); + final boolean orientationDiffers = config.getRotation() != mPipBoundsHandler.getDisplayRotation(); final WindowContainerTransaction wct = new WindowContainerTransaction(); - final Rect destinationBounds = initialConfig.windowConfiguration.getBounds(); + final Rect destinationBounds = config.getBounds(); final int direction = syncWithSplitScreenBounds(destinationBounds) ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN : TRANSITION_DIRECTION_TO_FULLSCREEN; @@ -351,7 +354,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements .setPipAnimationCallback(mPipAnimationCallback) .setDuration(mEnterExitAnimationDuration) .start()); - mInitialState.remove(mToken.asBinder()); + mCompactState.remove(mToken.asBinder()); mExitingPip = true; } @@ -377,8 +380,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements mInPip = true; mExitingPip = false; mLeash = leash; - mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration)); + mCompactState.put(mToken.asBinder(), + new PipWindowConfigurationCompact(mTaskInfo.configuration.windowConfiguration)); mPictureInPictureParams = mTaskInfo.pictureInPictureParams; + mRequestedOrientation = info.requestedOrientation; mPipUiEventLoggerLogger.setTaskInfo(mTaskInfo); mPipUiEventLoggerLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER); @@ -521,6 +526,8 @@ public class PipTaskOrganizer extends TaskOrganizer implements @Override public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) { Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken"); + mRequestedOrientation = info.requestedOrientation; + // check PictureInPictureParams for aspect ratio change. final PictureInPictureParams newParams = info.pictureInPictureParams; if (newParams == null || !applyPictureInPictureParams(newParams)) { Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams); @@ -558,8 +565,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements } /** - * TODO(b/152809058): consolidate the display info handling logic in SysUI - * * @param destinationBoundsOut the current destination bounds will be populated to this param */ @SuppressWarnings("unchecked") @@ -963,9 +968,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams); pw.println(innerPrefix + "mLastReportedBounds=" + mLastReportedBounds); pw.println(innerPrefix + "mInitialState:"); - for (Map.Entry e : mInitialState.entrySet()) { + for (Map.Entry e : mCompactState.entrySet()) { pw.println(innerPrefix + " binder=" + e.getKey() - + " winConfig=" + e.getValue().windowConfiguration); + + " config=" + e.getValue()); } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipWindowConfigurationCompact.java b/packages/SystemUI/src/com/android/systemui/pip/PipWindowConfigurationCompact.java new file mode 100644 index 000000000000..ba104d676cd2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/pip/PipWindowConfigurationCompact.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 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.pip; + +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; +import static android.view.Surface.ROTATION_0; +import static android.view.Surface.ROTATION_180; +import static android.view.Surface.ROTATION_270; +import static android.view.Surface.ROTATION_90; + +import android.app.WindowConfiguration; +import android.content.pm.ActivityInfo; +import android.graphics.Rect; +import android.view.Surface; + +/** + * Compact {@link WindowConfiguration} for PiP usage and supports operations such as rotate. + */ +class PipWindowConfigurationCompact { + private @Surface.Rotation int mRotation; + private Rect mBounds; + + PipWindowConfigurationCompact(WindowConfiguration windowConfiguration) { + mRotation = windowConfiguration.getRotation(); + mBounds = windowConfiguration.getBounds(); + } + + @Surface.Rotation int getRotation() { + return mRotation; + } + + Rect getBounds() { + return mBounds; + } + + void syncWithScreenOrientation(@ActivityInfo.ScreenOrientation int screenOrientation, + @Surface.Rotation int displayRotation) { + if (mBounds.top != 0 || mBounds.left != 0) { + // Supports fullscreen bounds like (0, 0, width, height) only now. + return; + } + boolean rotateNeeded = false; + if (ActivityInfo.isFixedOrientationPortrait(screenOrientation) + && (mRotation == ROTATION_90 || mRotation == ROTATION_270)) { + mRotation = ROTATION_0; + rotateNeeded = true; + } else if (ActivityInfo.isFixedOrientationLandscape(screenOrientation) + && (mRotation == ROTATION_0 || mRotation == ROTATION_180)) { + mRotation = ROTATION_90; + rotateNeeded = true; + } else if (screenOrientation == SCREEN_ORIENTATION_UNSPECIFIED + && mRotation != displayRotation) { + mRotation = displayRotation; + rotateNeeded = true; + } + if (rotateNeeded) { + mBounds.set(0, 0, mBounds.height(), mBounds.width()); + } + } + + @Override + public String toString() { + return "PipWindowConfigurationCompact(rotation=" + mRotation + + " bounds=" + mBounds + ")"; + } +} diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 76927e277412..954b7a026bf5 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -3627,6 +3627,9 @@ class Task extends WindowContainer { info.topActivityInfo = mReuseActivitiesReport.top != null ? mReuseActivitiesReport.top.info : null; + info.requestedOrientation = mReuseActivitiesReport.base != null + ? mReuseActivitiesReport.base.getRequestedOrientation() + : SCREEN_ORIENTATION_UNSET; } /** diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index f70bf18cdea5..e153befde8ad 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -458,7 +458,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { || mTmpTaskInfo.topActivityType != lastInfo.topActivityType || mTmpTaskInfo.isResizeable != lastInfo.isResizeable || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams - || !TaskDescription.equals(mTmpTaskInfo.taskDescription, lastInfo.taskDescription); + || !TaskDescription.equals(mTmpTaskInfo.taskDescription, lastInfo.taskDescription) + || mTmpTaskInfo.requestedOrientation != lastInfo.requestedOrientation; if (!changed) { int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration); final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0 -- GitLab From 10cb450ff57118457bb7467aea7e62f472b2e031 Mon Sep 17 00:00:00 2001 From: Jeongsik Mun Date: Mon, 10 Aug 2020 17:58:10 +0900 Subject: [PATCH 313/536] Fix usage of the wrong lock in PackageManager (mLock instead of mSettings) Bug: 162757028 Bug: 166537195 Test: compile & verify basic functions working Change-Id: Ie822d8f2267dcb8ce382e91ab5de365a4e0ce19f Merged-In: Ie822d8f2267dcb8ce382e91ab5de365a4e0ce19f (cherry picked from commit 1690689bc44d82d57e9ea12d44ef32d18dcb1326) --- .../core/java/com/android/server/pm/PackageManagerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index eefad1c8eed2..0cec95d2fa89 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -14501,7 +14501,7 @@ public class PackageManagerService extends IPackageManager.Stub final PackageSetting ps; int appId = -1; long ceDataInode = -1; - synchronized (mSettings) { + synchronized (mLock) { ps = mSettings.getPackageLPr(packageName); if (ps != null) { appId = ps.appId; -- GitLab From 44591227f20f9f1f806838b413c3403cfae480ec Mon Sep 17 00:00:00 2001 From: Jeongeun Song Date: Tue, 11 Aug 2020 10:31:43 +0900 Subject: [PATCH 314/536] Add missing synchronized(mLock) blocks into PackageManagerService The methods whose suffixes are Lpr, LPw, and Locked should be called within synchronized block, but it was missing. Hence, add missing synchronized(mLock) blocks into PackageManagerService. Bug: 162756879 Bug: 166537195 Test: compile & verify basic functions working Change-Id: Icefabfc9bb8c028edca6f5550524ea7dc1b6ffd9 Merged-In: Icefabfc9bb8c028edca6f5550524ea7dc1b6ffd9 (cherry picked from commit 648b2c0eb115cb855322f46b36049f688c583940) --- .../server/pm/PackageManagerService.java | 68 ++++++++++++------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index eefad1c8eed2..cefa128696aa 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -2376,9 +2376,12 @@ public class PackageManagerService extends IPackageManager.Stub final int callingUserId = UserHandle.getUserId(callingUid); for (String packageName : packages) { - PackageSetting setting = mSettings.mPackages.get(packageName); - if (setting != null - && !shouldFilterApplicationLocked(setting, callingUid, callingUserId)) { + final boolean filterApp; + synchronized (mLock) { + final PackageSetting ps = mSettings.getPackageLPr(packageName); + filterApp = shouldFilterApplicationLocked(ps, callingUid, callingUserId); + } + if (!filterApp) { notifyInstallObserver(packageName); } } @@ -8914,10 +8917,10 @@ public class PackageManagerService extends IPackageManager.Stub if (providerInfo == null) { return null; } - if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) { - return null; - } synchronized (mLock) { + if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) { + return null; + } final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName); final ComponentName component = new ComponentName(providerInfo.packageName, providerInfo.name); @@ -9004,9 +9007,11 @@ public class PackageManagerService extends IPackageManager.Stub String targetPackage, int flags) { final int callingUid = Binder.getCallingUid(); final int callingUserId = UserHandle.getUserId(callingUid); - final PackageSetting ps = mSettings.mPackages.get(targetPackage); - if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) { - return ParceledListSlice.emptyList(); + synchronized (mLock) { + final PackageSetting ps = mSettings.getPackageLPr(targetPackage); + if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) { + return ParceledListSlice.emptyList(); + } } return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags, callingUserId)); @@ -19356,9 +19361,11 @@ public class PackageManagerService extends IPackageManager.Stub mPermissionManager.enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */, false /* checkShell */, "clear application data"); - final PackageSetting ps = mSettings.getPackageLPr(packageName); - final boolean filterApp = - (ps != null && shouldFilterApplicationLocked(ps, callingUid, userId)); + final boolean filterApp; + synchronized (mLock) { + final PackageSetting ps = mSettings.getPackageLPr(packageName); + filterApp = shouldFilterApplicationLocked(ps, callingUid, userId); + } if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) { throw new SecurityException("Cannot clear data for a protected package: " + packageName); @@ -19638,11 +19645,13 @@ public class PackageManagerService extends IPackageManager.Stub if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS) != PackageManager.PERMISSION_GRANTED) { - if (getUidTargetSdkVersionLockedLPr(callingUid) - < Build.VERSION_CODES.FROYO) { - Slog.w(TAG, "Ignoring addPreferredActivity() from uid " - + callingUid); - return; + synchronized (mLock) { + if (getUidTargetSdkVersionLockedLPr(callingUid) + < Build.VERSION_CODES.FROYO) { + Slog.w(TAG, "Ignoring addPreferredActivity() from uid " + + callingUid); + return; + } } mContext.enforceCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); @@ -19814,8 +19823,9 @@ public class PackageManagerService extends IPackageManager.Stub /** This method takes a specific user id as well as UserHandle.USER_ALL. */ private void clearPackagePreferredActivities(String packageName, int userId) { final SparseBooleanArray changedUsers = new SparseBooleanArray(); - - clearPackagePreferredActivitiesLPw(packageName, changedUsers, userId); + synchronized (mLock) { + clearPackagePreferredActivitiesLPw(packageName, changedUsers, userId); + } if (changedUsers.size() > 0) { updateDefaultHomeNotLocked(changedUsers); postPreferredActivityChangedBroadcast(userId); @@ -19937,7 +19947,9 @@ public class PackageManagerService extends IPackageManager.Stub // writer try { final SparseBooleanArray changedUsers = new SparseBooleanArray(); - clearPackagePreferredActivitiesLPw(null, changedUsers, userId); + synchronized (mLock) { + clearPackagePreferredActivitiesLPw(null, changedUsers, userId); + } if (changedUsers.size() > 0) { postPreferredActivityChangedBroadcast(userId); } @@ -20942,15 +20954,19 @@ public class PackageManagerService extends IPackageManager.Stub // Limit who can change which apps if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) { // Don't allow apps that don't have permission to modify other apps - if (!allowedByPermission - || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) { + final boolean filterApp; + synchronized (mLock) { + filterApp = (!allowedByPermission + || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)); + } + if (filterApp) { throw new SecurityException( "Attempt to change component state; " - + "pid=" + Binder.getCallingPid() - + ", uid=" + callingUid - + (className == null + + "pid=" + Binder.getCallingPid() + + ", uid=" + callingUid + + (className == null ? ", package=" + packageName - : ", component=" + packageName + "/" + className)); + : ", component=" + packageName + "/" + className)); } // Don't allow changing protected packages. if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { -- GitLab From 88c92c70fee29654cb3603115cf1add892cf4382 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Thu, 27 Aug 2020 15:53:56 +0800 Subject: [PATCH 315/536] Fix BEHAVIOR_SHOW_BARS_BY_TOUCH If navigation is hidden while the behavior is SHOW_BARS_BY_TOUCH, both system bars should be shown by touch, not just navigation bar. Fix: 160587946 Test: atest DisplayPolicyTests Change-Id: I3f2e80a24b3184707a9fa0d65a4f44fc308c30ca --- services/core/java/com/android/server/wm/DisplayPolicy.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 5c5ec358d004..4eb14baaff90 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -1538,7 +1538,7 @@ public class DisplayPolicy { if (mInputConsumer == null) { return; } - showNavigationBar(); + showSystemBars(); // Any user activity always causes us to show the // navigation controls, if they had been hidden. // We also clear the low profile and only content @@ -1573,13 +1573,13 @@ public class DisplayPolicy { } } - private void showNavigationBar() { + private void showSystemBars() { final InsetsSourceProvider provider = mDisplayContent.getInsetsStateController() .peekSourceProvider(ITYPE_NAVIGATION_BAR); final InsetsControlTarget target = provider != null ? provider.getControlTarget() : null; if (target != null) { - target.showInsets(Type.navigationBars(), false /* fromIme */); + target.showInsets(Type.systemBars(), false /* fromIme */); } } } -- GitLab From 5a5734bbbaa96e4c2647eaed655ffac128ea3d5f Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Sat, 25 Jul 2020 00:37:48 +0800 Subject: [PATCH 316/536] Finish fixed rotation after recents moved to top While the task transition is running, its activity is the animation source. If recents animation is triggered and finished before the transition is done, the animation source will be notified that the transition is finished. At this timing, the rotated activity is still the top activity. Since it is moving to back, the display orientation is unnecessary to be updated for the intermediate state. That avoids flickering by not committing visibility due to configuration change. Fixes: 160239226 Test: atest RecentsAnimationControllerTest# \ testKeepFixedRotationWhenMovingRecentsToTop Change-Id: I5c5c12338b9bc0cd8a99655a843a33d8729f8892 Merged-In: I5c5c12338b9bc0cd8a99655a843a33d8729f8892 --- .../com/android/server/wm/DisplayContent.java | 21 ++++++++++++-- .../server/wm/RecentsAnimationController.java | 8 +++-- .../server/wm/DisplayContentTests.java | 2 +- .../wm/RecentsAnimationControllerTest.java | 29 +++++++++++++++++-- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index fcbc7564cabb..ed1f221576d9 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5642,6 +5642,9 @@ class DisplayContent extends WindowContainer= 0; i--) { final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i); if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) { @@ -742,8 +747,7 @@ public class RecentsAnimationController implements DeathRecipient { mTargetActivityRecord.token); } } - mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation( - reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION /* moveRecentsToBack */); + mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(); // Notify that the animation has ended if (mStatusBar != null) { diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index cbccfb3725e9..dc838f1bb288 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1282,7 +1282,7 @@ public class DisplayContentTests extends WindowTestsBase { assertFalse(displayRotation.updateRotationUnchecked(false)); // Rotation can be updated if the recents animation is finished. - mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(false); + mDisplayContent.mFixedRotationTransitionListener.onFinishRecentsAnimation(); assertTrue(displayRotation.updateRotationUnchecked(false)); // Rotation can be updated if the recents animation is animating but it is not on top, e.g. 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 8e85e7b96d1f..f2771175b523 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -363,12 +363,14 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertFalse(homeActivity.hasFixedRotationTransform()); } - @Test - public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() { + private ActivityRecord prepareFixedRotationLaunchingAppWithRecentsAnim() { final ActivityRecord homeActivity = createHomeActivity(); homeActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); final ActivityRecord activity = createActivityRecord(mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + // Add a window so it can be animated by the recents. + final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win"); + activity.addWindow(win); // Assume an activity is launching to different rotation. mDefaultDisplay.setFixedRotationLaunchingApp(activity, (mDefaultDisplay.getRotation() + 1) % 4); @@ -379,6 +381,14 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { // Before the transition is done, the recents animation is triggered. initializeRecentsAnimationController(mController, homeActivity); assertFalse(homeActivity.hasFixedRotationTransform()); + assertTrue(mController.isAnimatingTask(activity.getTask())); + + return activity; + } + + @Test + public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() { + final ActivityRecord activity = prepareFixedRotationLaunchingAppWithRecentsAnim(); // Simulate giving up the swipe up gesture to keep the original activity as top. mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); @@ -387,6 +397,21 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertFalse(mDefaultDisplay.hasTopFixedRotationLaunchingApp()); } + @Test + public void testKeepFixedRotationWhenMovingRecentsToTop() { + final ActivityRecord activity = prepareFixedRotationLaunchingAppWithRecentsAnim(); + // Assume a transition animation has started running before recents animation. Then the + // activity will receive onAnimationFinished that notifies app transition finished when + // removing the recents animation of task. + activity.getTask().getAnimationSources().add(activity); + + // Simulate swiping to home/recents before the transition is done. + mController.cleanupAnimation(REORDER_MOVE_TO_TOP); + // The rotation transform should be preserved. In real case, it will be cleared by the next + // move-to-top transition. + assertTrue(activity.hasFixedRotationTransform()); + } + @Test public void testWallpaperHasFixedRotationApplied() { mWm.setRecentsAnimationController(mController); -- GitLab From 1f27ebfa55605dcdbda2e511d5829bdb6f686924 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Sat, 25 Jul 2020 01:44:51 +0800 Subject: [PATCH 317/536] Allow to replace fixed rotation state Assume there are 2 activities with different fixed rotation states A and B. And wallpaper was associated with A. When the wallpaper target is changed to B, wallpaper should be able to change the association to B so their rotation transform can be updated at the same time. This also avoids that if the previous associated token is somehow inactive, wallpaper won't in a dangling rotated state. Also add a check of updating rotated launching app for the case: launching a portrait app from a landscape app and trigger recents animation immediately before the animation of portrait app is done. And then finish recents animation by keeping the portrait app as the top activity. The expected result should be that the display is rotated from landscape to portrait seamlessly. But if the recents activity is set to the rotated launching app, the display rotation will be unable to update because when receiving animation done of the portrait app, the recents animation is still active that skips the rotation change. Then the portrait app will be updated to landscape temporally. Fixes: 161056612 Test: atest WindowTokenTests#testFinishFixedRotationTransform Change-Id: Ic134c4326db836e35385f290f996f0d841da693d Merged-In: Ic134c4326db836e35385f290f996f0d841da693d --- .../com/android/server/wm/DisplayContent.java | 7 ++++++- .../com/android/server/wm/WindowToken.java | 20 ++++++++++++------- .../android/server/wm/WindowTokenTests.java | 18 ++++++++++++++--- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index ed1f221576d9..0363ea0e7512 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1573,7 +1573,12 @@ class DisplayContent extends WindowContainer { void applyFixedRotationTransform(DisplayInfo info, DisplayFrames displayFrames, Configuration config) { if (mFixedRotationTransformState != null) { - return; + cleanUpFixedRotationTransformState(true /* replacing */); } mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames, new Configuration(config), mDisplayContent.getRotation()); @@ -548,13 +548,13 @@ class WindowToken extends WindowContainer { * one. This takes the same effect as {@link #applyFixedRotationTransform}. */ void linkFixedRotationTransform(WindowToken other) { - if (mFixedRotationTransformState != null) { - return; - } final FixedRotationTransformState fixedRotationState = other.mFixedRotationTransformState; - if (fixedRotationState == null) { + if (fixedRotationState == null || mFixedRotationTransformState == fixedRotationState) { return; } + if (mFixedRotationTransformState != null) { + cleanUpFixedRotationTransformState(true /* replacing */); + } mFixedRotationTransformState = fixedRotationState; fixedRotationState.mAssociatedTokens.add(this); onConfigurationChanged(getParent().getConfiguration()); @@ -609,11 +609,17 @@ class WindowToken extends WindowContainer { // The state is cleared at the end, because it is used to indicate that other windows can // use seamless rotation when applying rotation to display. for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) { - state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState(); + state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState( + false /* replacing */); } } - private void cleanUpFixedRotationTransformState() { + private void cleanUpFixedRotationTransformState(boolean replacing) { + if (replacing && mFixedRotationTransformState.mAssociatedTokens.size() > 1) { + // The state is not only used by self. Make sure to leave the influence by others. + mFixedRotationTransformState.mAssociatedTokens.remove(this); + mFixedRotationTransformState.mRotatedContainers.remove(this); + } mFixedRotationTransformState = null; notifyFixedRotationTransform(false /* enabled */); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java index 23a097eb0c7c..0896db4b5532 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java @@ -24,6 +24,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -139,6 +140,8 @@ public class WindowTokenTests extends WindowTestsBase { public void testFinishFixedRotationTransform() { final WindowToken appToken = mAppWindow.mToken; final WindowToken wallpaperToken = mWallpaperWindow.mToken; + final WindowToken testToken = + WindowTestUtils.createTestWindowToken(TYPE_APPLICATION_OVERLAY, mDisplayContent); final Configuration config = new Configuration(mDisplayContent.getConfiguration()); final int originalRotation = config.windowConfiguration.getRotation(); final int targetRotation = (originalRotation + 1) % 4; @@ -151,11 +154,20 @@ public class WindowTokenTests extends WindowTestsBase { assertEquals(targetRotation, appToken.getWindowConfiguration().getRotation()); assertEquals(targetRotation, wallpaperToken.getWindowConfiguration().getRotation()); - // The display doesn't rotate, the transformation will be canceled. - mAppWindow.mToken.finishFixedRotationTransform(); + testToken.applyFixedRotationTransform(mDisplayInfo, mDisplayContent.mDisplayFrames, config); + // The wallpaperToken was linked to appToken, this should make it link to testToken. + wallpaperToken.linkFixedRotationTransform(testToken); - // The window tokens should restore to the original rotation. + // Assume the display doesn't rotate, the transformation will be canceled. + appToken.finishFixedRotationTransform(); + + // The appToken should restore to the original rotation. assertEquals(originalRotation, appToken.getWindowConfiguration().getRotation()); + // The wallpaperToken is linked to testToken, it should keep the target rotation. + assertNotEquals(originalRotation, wallpaperToken.getWindowConfiguration().getRotation()); + + testToken.finishFixedRotationTransform(); + // The rotation of wallpaperToken should be restored because its linked state is finished. assertEquals(originalRotation, wallpaperToken.getWindowConfiguration().getRotation()); } -- GitLab From c1942afbff65a606d2adb7f8df8491b73c373ad6 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Mon, 29 Jun 2020 16:54:21 -0700 Subject: [PATCH 318/536] Correctly expose EGL_ANDROID_native_fence_sync to hwui When we moved off of gui/SyncFeatures for retrieving this extension, we accidentally didn't include the eglQueryStringImplementationANDROID path for retrieving extensions. Fortunately this extension is only used for TextureView synchronization, but we should still use the extension when available. Bug: 159921224 Test: Manually inject log statements to verify the extension is correctly visible. Change-Id: Idaa872778afc13e86bdea918da8631b4747fe9c1 (cherry picked from commit 49d87e5c077fed85c48341be65e9eaff98654bef) Merged-In: Idaa872778afc13e86bdea918da8631b4747fe9c1 --- libs/hwui/renderthread/EglManager.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 5e0471c08d67..7982ab664c1b 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -208,8 +208,12 @@ EGLConfig EglManager::loadFP16Config(EGLDisplay display, SwapBehavior swapBehavi return config; } +extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); + void EglManager::initExtensions() { auto extensions = StringUtils::split(eglQueryString(mEglDisplay, EGL_EXTENSIONS)); + auto extensionsAndroid = + StringUtils::split(eglQueryStringImplementationANDROID(mEglDisplay, EGL_EXTENSIONS)); // For our purposes we don't care if EGL_BUFFER_AGE is a result of // EGL_EXT_buffer_age or EGL_KHR_partial_update as our usage is covered @@ -228,9 +232,12 @@ void EglManager::initExtensions() { EglExtensions.displayP3 = extensions.has("EGL_EXT_gl_colorspace_display_p3_passthrough"); EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority"); EglExtensions.surfacelessContext = extensions.has("EGL_KHR_surfaceless_context"); - EglExtensions.nativeFenceSync = extensions.has("EGL_ANDROID_native_fence_sync"); EglExtensions.fenceSync = extensions.has("EGL_KHR_fence_sync"); EglExtensions.waitSync = extensions.has("EGL_KHR_wait_sync"); + + // EGL_ANDROID_native_fence_sync is not exposed to applications, so access + // this through the private Android-specific query instead. + EglExtensions.nativeFenceSync = extensionsAndroid.has("EGL_ANDROID_native_fence_sync"); } bool EglManager::hasEglContext() { -- GitLab From 6ca459dc17605f94af451d0b038a12f64a4563f6 Mon Sep 17 00:00:00 2001 From: Marco Ballesio Date: Mon, 1 Jun 2020 11:12:54 -0700 Subject: [PATCH 319/536] freezer: switch to cgroup v2 freezer cgroup v2 freezer has a single hierarchy and is mounted under /sys/fs/cgroup. Proper v2 freezer support in a system can be checked by verifying that the file "cgroup.freeze" is present in a freezer subgroup. Bug: 154548692 Test: manually verified that processes are frozen and unfrozen Change-Id: Ib966a957490ec986eb14aba6492832c96e147896 Merged-In: Ib966a957490ec986eb14aba6492832c96e147896 --- core/java/android/os/Process.java | 2 +- core/jni/android_util_Process.cpp | 4 ++-- .../android/server/am/CachedAppOptimizer.java | 18 +++++++++++------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index a4077fbee892..efea9537c4cf 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -947,7 +947,7 @@ public class Process { /** * Enable or disable the freezer. When enable == false all frozen processes are unfrozen, - * but aren't removed from the freezer. Processes can still be added or removed + * but aren't removed from the freezer. While in this state, processes can be added or removed * by using setProcessFrozen, but they won't actually be frozen until the freezer is enabled * again. If enable == true the freezer is enabled again, and all processes * in the freezer (including the ones added while the freezer was disabled) are frozen. diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 7c32ca653114..3486a8574ba0 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -352,9 +352,9 @@ void android_os_Process_enableFreezer( bool success = true; if (enable) { - success = SetTaskProfiles(0, {"FreezerFrozen"}, true); + success = SetTaskProfiles(0, {"FreezerEnabled"}, true); } else { - success = SetTaskProfiles(0, {"FreezerThawed"}, true); + success = SetTaskProfiles(0, {"FreezerDisabled"}, true); } if (!success) { diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index d9fde0f6728a..ce7c73a5d8a3 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -420,25 +420,25 @@ public final class CachedAppOptimizer { } /** - * Determines whether the freezer is correctly supported by this system + * Determines whether the freezer is supported by this system */ public static boolean isFreezerSupported() { boolean supported = false; FileReader fr = null; try { - fr = new FileReader("/dev/freezer/frozen/freezer.killable"); - int i = fr.read(); + fr = new FileReader("/sys/fs/cgroup/freezer/cgroup.freeze"); + char state = (char) fr.read(); - if ((char) i == '1') { + if (state == '1' || state == '0') { supported = true; } else { - Slog.w(TAG_AM, "Freezer killability is turned off, disabling freezer"); + Slog.e(TAG_AM, "unexpected value in cgroup.freeze"); } } catch (java.io.FileNotFoundException e) { - Slog.d(TAG_AM, "Freezer.killable not present, disabling freezer"); + Slog.d(TAG_AM, "cgroup.freeze not present"); } catch (Exception e) { - Slog.d(TAG_AM, "Unable to read freezer.killable, disabling freezer: " + e.toString()); + Slog.d(TAG_AM, "unable to read cgroup.freeze: " + e.toString()); } if (fr != null) { @@ -471,6 +471,8 @@ public final class CachedAppOptimizer { if (mUseFreezer && mFreezeHandler == null) { Slog.d(TAG_AM, "Freezer enabled"); + Process.enableFreezer(true); + if (!mCachedAppOptimizerThread.isAlive()) { mCachedAppOptimizerThread.start(); } @@ -479,6 +481,8 @@ public final class CachedAppOptimizer { Process.setThreadGroupAndCpuset(mCachedAppOptimizerThread.getThreadId(), Process.THREAD_GROUP_SYSTEM); + } else { + Process.enableFreezer(false); } } -- GitLab From 12f3e8d6d4d5858bed9f8dd4b0106573151450d3 Mon Sep 17 00:00:00 2001 From: Marco Ballesio Date: Wed, 3 Jun 2020 08:56:46 -0700 Subject: [PATCH 320/536] freezer: reentrant enable/disable method the app freezer state can be toggled in multiple situations when a debugging tool like heapdump is invoked, or when system_server dumps its binder connections. All these uses are potentially concurrent and a robust method to handle reentrancy is necessary to avoid leaving the freezer in a state incompatible with a specific operation. This patch moves freezer enable and disable operations from Process to CachedAppOptimizer (ActivityManager), introduces a new ActivityManager API to centralize all freezer state changes to ActivityManager and modifies client code accordingly. Bug: 151225245 Test: manually verified that no regression are introduced on freezer behavior, verified that concurrent behavior is handled properly Change-Id: I7d588cc6e0499012dce64ed4e42ff2adb336062d Merged-In: I7d588cc6e0499012dce64ed4e42ff2adb336062d --- core/java/android/app/IActivityManager.aidl | 10 +++ core/java/android/os/BinderProxy.java | 14 ++++- core/jni/android_util_Process.cpp | 17 ----- .../server/am/ActivityManagerService.java | 48 +++++++------- .../android/server/am/CachedAppOptimizer.java | 63 ++++++++++++++++++- services/core/jni/Android.bp | 1 + ...m_android_server_am_CachedAppOptimizer.cpp | 18 ++++++ 7 files changed, 124 insertions(+), 47 deletions(-) diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 2abe9cf9fce5..f98e26338063 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -684,4 +684,14 @@ interface IActivityManager { * Kills uid with the reason of permission change. */ void killUidForPermissionChange(int appId, int userId, String reason); + + /** + * Control the app freezer state. Returns true in case of success, false if the operation + * didn't succeed (for example, when the app freezer isn't supported). + * Handling the freezer state via this method is reentrant, that is it can be + * disabled and re-enabled multiple times in parallel. As long as there's a 1:1 disable to + * enable match, the freezer is re-enabled at last enable only. + * @param enable set it to true to enable the app freezer, false to disable it. + */ + boolean enableAppFreezer(in boolean enable); } diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java index 683993f762c0..0185ba444ca4 100644 --- a/core/java/android/os/BinderProxy.java +++ b/core/java/android/os/BinderProxy.java @@ -18,6 +18,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityManager; import android.app.AppOpsManager; import android.util.Log; import android.util.SparseIntArray; @@ -255,7 +256,12 @@ public final class BinderProxy implements IBinder { // out of system_server to all processes hosting binder objects it holds a reference to; // since some of those processes might be frozen, we don't want to block here // forever. Disable the freezer. - Process.enableFreezer(false); + try { + ActivityManager.getService().enableAppFreezer(false); + } catch (RemoteException e) { + Log.e(Binder.TAG, "RemoteException while disabling app freezer"); + } + for (WeakReference weakRef : proxiesToQuery) { BinderProxy bp = weakRef.get(); String key; @@ -278,7 +284,11 @@ public final class BinderProxy implements IBinder { counts.put(key, i + 1); } } - Process.enableFreezer(true); + try { + ActivityManager.getService().enableAppFreezer(true); + } catch (RemoteException e) { + Log.e(Binder.TAG, "RemoteException while re-enabling app freezer"); + } Map.Entry[] sorted = counts.entrySet().toArray( new Map.Entry[counts.size()]); diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 3486a8574ba0..6becb07d02a4 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -346,22 +346,6 @@ void android_os_Process_setProcessFrozen( } } -void android_os_Process_enableFreezer( - JNIEnv *env, jobject clazz, jboolean enable) -{ - bool success = true; - - if (enable) { - success = SetTaskProfiles(0, {"FreezerEnabled"}, true); - } else { - success = SetTaskProfiles(0, {"FreezerDisabled"}, true); - } - - if (!success) { - jniThrowException(env, "java/lang/RuntimeException", "Unknown error"); - } -} - jint android_os_Process_getProcessGroup(JNIEnv* env, jobject clazz, jint pid) { SchedPolicy sp; @@ -1360,7 +1344,6 @@ static const JNINativeMethod methods[] = { {"sendSignal", "(II)V", (void*)android_os_Process_sendSignal}, {"sendSignalQuiet", "(II)V", (void*)android_os_Process_sendSignalQuiet}, {"setProcessFrozen", "(IIZ)V", (void*)android_os_Process_setProcessFrozen}, - {"enableFreezer", "(Z)V", (void*)android_os_Process_enableFreezer}, {"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory}, {"getTotalMemory", "()J", (void*)android_os_Process_getTotalMemory}, {"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V", diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 44e3bbf91565..491579a5a294 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2218,17 +2218,13 @@ public class ActivityManagerService extends IActivityManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { - if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { - Process.enableFreezer(false); - } + mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false); if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "meminfo", pw)) return; PriorityDump.dump(mPriorityDumper, fd, pw, args); } finally { - if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { - Process.enableFreezer(true); - } + mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true); } } } @@ -2242,17 +2238,13 @@ public class ActivityManagerService extends IActivityManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { - if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { - Process.enableFreezer(false); - } + mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false); if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "gfxinfo", pw)) return; mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); } finally { - if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { - Process.enableFreezer(true); - } + mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true); } } } @@ -2266,17 +2258,13 @@ public class ActivityManagerService extends IActivityManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { - if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { - Process.enableFreezer(false); - } + mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false); if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "dbinfo", pw)) return; mActivityManagerService.dumpDbInfo(fd, pw, args); } finally { - if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { - Process.enableFreezer(true); - } + mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true); } } } @@ -2322,9 +2310,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { try { - if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { - Process.enableFreezer(false); - } + mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(false); if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, "cacheinfo", pw)) { @@ -2333,9 +2319,7 @@ public class ActivityManagerService extends IActivityManager.Stub mActivityManagerService.dumpBinderCacheContents(fd, pw, args); } finally { - if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) { - Process.enableFreezer(true); - } + mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.enableFreezer(true); } } } @@ -18630,14 +18614,14 @@ public class ActivityManagerService extends IActivityManager.Stub } } - Process.enableFreezer(false); + mOomAdjuster.mCachedAppOptimizer.enableFreezer(false); final RemoteCallback intermediateCallback = new RemoteCallback( new RemoteCallback.OnResultListener() { @Override public void onResult(Bundle result) { finishCallback.sendResult(result); - Process.enableFreezer(true); + mOomAdjuster.mCachedAppOptimizer.enableFreezer(true); } }, null); @@ -20399,4 +20383,16 @@ public class ActivityManagerService extends IActivityManager.Stub Binder.restoreCallingIdentity(token); } } + + @Override + public boolean enableAppFreezer(boolean enable) { + int callerUid = Binder.getCallingUid(); + + // Only system can toggle the freezer state + if (callerUid == SYSTEM_UID) { + return mOomAdjuster.mCachedAppOptimizer.enableFreezer(enable); + } else { + throw new SecurityException("Caller uid " + callerUid + " cannot set freezer state "); + } + } } diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index ce7c73a5d8a3..c5047e5eed03 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -208,6 +208,8 @@ public final class CachedAppOptimizer { @GuardedBy("mPhenotypeFlagLock") private volatile boolean mUseCompaction = DEFAULT_USE_COMPACTION; private volatile boolean mUseFreezer = DEFAULT_USE_FREEZER; + @GuardedBy("this") + private int mFreezerDisableCount = 1; // Freezer is initially disabled, until enabled private final Random mRandom = new Random(); @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting volatile float mCompactStatsdSampleRate = DEFAULT_STATSD_SAMPLE_RATE; @@ -419,6 +421,63 @@ public final class CachedAppOptimizer { } } + /** + * Enables or disabled the app freezer. + * @param enable Enables the freezer if true, disables it if false. + * @return true if the operation completed successfully, false otherwise. + */ + public synchronized boolean enableFreezer(boolean enable) { + if (!mUseFreezer) { + return false; + } + + if (enable) { + mFreezerDisableCount--; + + if (mFreezerDisableCount > 0) { + return true; + } else if (mFreezerDisableCount < 0) { + Slog.e(TAG_AM, "unbalanced call to enableFreezer, ignoring"); + mFreezerDisableCount = 0; + return false; + } + } else { + mFreezerDisableCount++; + + if (mFreezerDisableCount > 1) { + return true; + } + } + + try { + enableFreezerInternal(enable); + return true; + } catch (java.lang.RuntimeException e) { + if (enable) { + mFreezerDisableCount = 0; + } else { + mFreezerDisableCount = 1; + } + + Slog.e(TAG_AM, "Exception handling freezer state (enable: " + enable + "): " + + e.toString()); + } + + return false; + } + + /** + * Enable or disable the freezer. When enable == false all frozen processes are unfrozen, + * but aren't removed from the freezer. While in this state, processes can be added or removed + * by using Process.setProcessFrozen(), but they wouldn't be actually frozen until the freezer + * is enabled. If enable == true all processes in the freezer are frozen. + * + * @param enable Specify whether to enable (true) or disable (false) the freezer. + * + * @hide + */ + private static native void enableFreezerInternal(boolean enable); + /** * Determines whether the freezer is supported by this system */ @@ -471,7 +530,7 @@ public final class CachedAppOptimizer { if (mUseFreezer && mFreezeHandler == null) { Slog.d(TAG_AM, "Freezer enabled"); - Process.enableFreezer(true); + enableFreezer(true); if (!mCachedAppOptimizerThread.isAlive()) { mCachedAppOptimizerThread.start(); @@ -482,7 +541,7 @@ public final class CachedAppOptimizer { Process.setThreadGroupAndCpuset(mCachedAppOptimizerThread.getThreadId(), Process.THREAD_GROUP_SYSTEM); } else { - Process.enableFreezer(false); + enableFreezer(false); } } diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 925ad0f57f19..460842e56764 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -106,6 +106,7 @@ cc_defaults { "libkeystore_binder", "libmtp", "libnativehelper", + "libprocessgroup", "libutils", "libui", "libinput", diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp index 6a6da0e2b395..7e9e11d209a6 100644 --- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp @@ -30,6 +30,7 @@ #include #include #include +#include using android::base::StringPrintf; using android::base::WriteStringToFile; @@ -74,9 +75,26 @@ static void com_android_server_am_CachedAppOptimizer_compactSystem(JNIEnv *, job } } +static void com_android_server_am_CachedAppOptimizer_enableFreezerInternal( + JNIEnv *env, jobject clazz, jboolean enable) { + bool success = true; + + if (enable) { + success = SetTaskProfiles(0, {"FreezerEnabled"}, true); + } else { + success = SetTaskProfiles(0, {"FreezerDisabled"}, true); + } + + if (!success) { + jniThrowException(env, "java/lang/RuntimeException", "Unknown error"); + } +} + static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ {"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem}, + {"enableFreezerInternal", "(Z)V", + (void*)com_android_server_am_CachedAppOptimizer_enableFreezerInternal}, }; int register_android_server_am_CachedAppOptimizer(JNIEnv* env) -- GitLab From b1d0a839f1045ba8c3cf421c668127d0231084e1 Mon Sep 17 00:00:00 2001 From: Alex Buynytskyy Date: Wed, 1 Jul 2020 12:28:47 -0700 Subject: [PATCH 321/536] Fix transfer API. Transfer API should throw security exception when transfering the session which is not installing the original installer. Moving it onto commit stage and still fail the installation. Fixes: 165775712 Test: atest InstallSessionTransferTest Test: atest -p frameworks/base/services/core/java/com/android/server/pm Change-Id: I8511d4357788e70f83bcbd366908b42a691afbcb Merged-In: I8511d4357788e70f83bcbd366908b42a691afbcb --- .../android/content/pm/PackageInstaller.java | 5 ++--- .../server/pm/PackageInstallerSession.java | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index fc4ccd072e75..191c4655c708 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1291,9 +1291,8 @@ public class PackageInstaller { * * @throws PackageManager.NameNotFoundException if the new owner could not be found. * @throws SecurityException if called after the session has been committed or abandoned. - * @throws SecurityException if the session does not update the original installer - * @throws SecurityException if streams opened through - * {@link #openWrite(String, long, long) are still open. + * @throws IllegalArgumentException if streams opened through + * {@link #openWrite(String, long, long) are still open. */ public void transfer(@NonNull String packageName) throws PackageManager.NameNotFoundException { diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 994cec2b1e59..ea53132ae409 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -267,6 +267,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { /** Uid of the creator of this session. */ private final int mOriginalInstallerUid; + /** Package name of the app that created the installation session. */ + private final String mOriginalInstallerPackageName; + /** Uid of the owner of the installer session */ @GuardedBy("mLock") private int mInstallerUid; @@ -556,6 +559,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mOriginalInstallerUid = installerUid; mInstallerUid = installerUid; mInstallSource = Objects.requireNonNull(installSource); + mOriginalInstallerPackageName = mInstallSource.installerPackageName; this.params = params; this.createdMillis = createdMillis; this.updatedMillis = createdMillis; @@ -1666,11 +1670,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new IllegalArgumentException("Package is not valid", e); } - if (!mPackageName.equals(mInstallSource.installerPackageName)) { - throw new SecurityException("Can only transfer sessions that update the original " - + "installer"); - } - mInstallerUid = newOwnerAppInfo.uid; mInstallSource = InstallSource.create(packageName, null, packageName); } @@ -2157,6 +2156,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } + if (mInstallerUid != mOriginalInstallerUid) { + // Session has been transferred, check package name. + if (TextUtils.isEmpty(mPackageName) || !mPackageName.equals( + mOriginalInstallerPackageName)) { + throw new PackageManagerException(PackageManager.INSTALL_FAILED_PACKAGE_CHANGED, + "Can only transfer sessions that update the original installer"); + } + } + if (params.mode == SessionParams.MODE_FULL_INSTALL) { // Full installs must include a base package if (!stagedSplits.contains(null)) { @@ -3182,6 +3190,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { pw.printPair("userId", userId); pw.printPair("mOriginalInstallerUid", mOriginalInstallerUid); + pw.printPair("mOriginalInstallerPackageName", mOriginalInstallerPackageName); pw.printPair("installerPackageName", mInstallSource.installerPackageName); pw.printPair("installInitiatingPackageName", mInstallSource.initiatingPackageName); pw.printPair("installOriginatingPackageName", mInstallSource.originatingPackageName); -- GitLab From afe2823fd23bb1143473258239f61a7c2a0771df Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Fri, 28 Aug 2020 13:25:31 +0100 Subject: [PATCH 322/536] AppOpsService: Add a special case for OP_RECORD_AUDIO_HOTWORD. When OP_RECORD_AUDIO_HOTWORD is used with startOp, we make sure we also check the state of OP_RECORD_AUDIO. The former is used for attribution purposes only. Test: manual. Bug: 162547999 Change-Id: I72478c82233fe796738d360ed9b7f7bb9cafb7b0 --- .../com/android/server/appop/AppOpsService.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index c5bdb9edd069..1d23e72b299a 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -39,6 +39,7 @@ import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.OP_PLAY_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO; +import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD; import static android.app.AppOpsManager.OpEventProxyInfo; import static android.app.AppOpsManager.RestrictionBypass; import static android.app.AppOpsManager.SAMPLING_STRATEGY_BOOT_TIME_SAMPLING; @@ -3400,7 +3401,19 @@ public class AppOpsService extends IAppOpsService.Stub { verifyIncomingOp(code); String resolvedPackageName = resolvePackageName(uid, packageName); if (resolvedPackageName == null) { - return AppOpsManager.MODE_IGNORED; + return AppOpsManager.MODE_IGNORED; + } + + // As a special case for OP_RECORD_AUDIO_HOTWORD, which we use only for attribution + // purposes and not as a check, also make sure that the caller is allowed to access + // the data gated by OP_RECORD_AUDIO. + // + // TODO: Revert this change before Android 12. + if (code == OP_RECORD_AUDIO_HOTWORD) { + int result = checkOperation(OP_RECORD_AUDIO, uid, packageName); + if (result != AppOpsManager.MODE_ALLOWED) { + return result; + } } RestrictionBypass bypass; -- GitLab From b0f1feb01f40d77992fa83ae43f503cf49a82f07 Mon Sep 17 00:00:00 2001 From: Patrick Baumann Date: Mon, 20 Jul 2020 11:06:47 -0700 Subject: [PATCH 323/536] Construct AppsFilter cache on background thread This change moves the initial bootstrapping of the apps filter cache off onto a secondary thread to avoid impacting the boottime critical path. Fixes: 162347084 Bug: 161250592 Test: atest AppsFilterTest AppEnumerationTests Change-Id: Iafa85e838d7f753eaf74037c85f86ee1feeb17aa (cherry picked from commit 6ab5b2975e72b75e42d7c2a5a89b31d54cfd8321) Merged-In: Iafa85e838d7f753eaf74037c85f86ee1feeb17aa Merged-In: Iac2948fb2ad66e45161627f637f039a5f4faf88c --- .../com/android/server/pm/AppsFilter.java | 179 +++++++++++------- .../server/pm/PackageManagerService.java | 4 +- .../com/android/server/pm/AppsFilterTest.java | 91 ++++++--- 3 files changed, 174 insertions(+), 100 deletions(-) diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java index c3c2e5e65103..22d6c9909edf 100644 --- a/services/core/java/com/android/server/pm/AppsFilter.java +++ b/services/core/java/com/android/server/pm/AppsFilter.java @@ -35,6 +35,9 @@ import android.content.pm.parsing.component.ParsedInstrumentation; import android.content.pm.parsing.component.ParsedIntentInfo; import android.content.pm.parsing.component.ParsedMainComponent; import android.content.pm.parsing.component.ParsedProvider; +import android.os.Handler; +import android.os.HandlerExecutor; +import android.os.HandlerThread; import android.os.Process; import android.os.Trace; import android.os.UserHandle; @@ -48,6 +51,7 @@ import android.util.SparseBooleanArray; import android.util.SparseSetArray; import com.android.internal.R; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.server.FgThread; @@ -61,6 +65,7 @@ import java.util.List; import java.util.Objects; import java.util.Set; import java.util.StringTokenizer; +import java.util.concurrent.Executor; /** * The entity responsible for filtering visibility between apps based on declarations in their @@ -95,6 +100,12 @@ public class AppsFilter { */ private final SparseSetArray mQueriesViaComponent = new SparseSetArray<>(); + /** + * Executor for running reasonably short background tasks such as building the initial + * visibility cache. + */ + private final Executor mBackgroundExecutor; + /** * Pending full recompute of mQueriesViaComponent. Occurs when a package adds a new set of * protected broadcast. This in turn invalidates all prior additions and require a very @@ -125,6 +136,8 @@ public class AppsFilter { private PackageParser.SigningDetails mSystemSigningDetails; private Set mProtectedBroadcasts = new ArraySet<>(); + private final Object mCacheLock = new Object(); + /** * This structure maps uid -> uid and indicates whether access from the first should be * filtered to the second. It's essentially a cache of the @@ -132,6 +145,7 @@ public class AppsFilter { * NOTE: It can only be relied upon after the system is ready to avoid unnecessary update on * initial scam and is null until {@link #onSystemReady()} is called. */ + @GuardedBy("mCacheLock") private volatile SparseArray mShouldFilterCache; @VisibleForTesting(visibility = PRIVATE) @@ -139,13 +153,15 @@ public class AppsFilter { FeatureConfig featureConfig, String[] forceQueryableWhitelist, boolean systemAppsQueryable, - @Nullable OverlayReferenceMapper.Provider overlayProvider) { + @Nullable OverlayReferenceMapper.Provider overlayProvider, + Executor backgroundExecutor) { mFeatureConfig = featureConfig; mForceQueryableByDevicePackageNames = forceQueryableWhitelist; mSystemAppsQueryable = systemAppsQueryable; mOverlayReferenceMapper = new OverlayReferenceMapper(true /*deferRebuild*/, overlayProvider); mStateProvider = stateProvider; + mBackgroundExecutor = backgroundExecutor; } /** @@ -337,8 +353,13 @@ public class AppsFilter { injector.getUserManagerInternal().getUserInfos()); } }; + HandlerThread appsFilterThread = new HandlerThread("appsFilter"); + appsFilterThread.start(); + Handler appsFilterHandler = new Handler(appsFilterThread.getLooper()); + Executor executor = new HandlerExecutor(appsFilterHandler); + AppsFilter appsFilter = new AppsFilter(stateProvider, featureConfig, - forcedQueryablePackageNames, forceSystemAppsQueryable, null); + forcedQueryablePackageNames, forceSystemAppsQueryable, null, executor); featureConfig.setAppsFilter(appsFilter); return appsFilter; } @@ -470,29 +491,26 @@ public class AppsFilter { if (mImplicitlyQueryable.add(recipientUid, visibleUid) && DEBUG_LOGGING) { Slog.i(TAG, "implicit access granted: " + recipientUid + " -> " + visibleUid); } - if (mShouldFilterCache != null) { - // update the cache in a one-off manner since we've got all the information we need. - SparseBooleanArray visibleUids = mShouldFilterCache.get(recipientUid); - if (visibleUids == null) { - visibleUids = new SparseBooleanArray(); - mShouldFilterCache.put(recipientUid, visibleUids); + synchronized (mCacheLock) { + if (mShouldFilterCache != null) { + // update the cache in a one-off manner since we've got all the information we + // need. + SparseBooleanArray visibleUids = mShouldFilterCache.get(recipientUid); + if (visibleUids == null) { + visibleUids = new SparseBooleanArray(); + mShouldFilterCache.put(recipientUid, visibleUids); + } + visibleUids.put(visibleUid, false); } - visibleUids.put(visibleUid, false); } } } public void onSystemReady() { - mStateProvider.runWithState(new StateProvider.CurrentStateCallback() { - @Override - public void currentState(ArrayMap settings, - UserInfo[] users) { - mShouldFilterCache = new SparseArray<>(users.length * settings.size()); - } - }); - mFeatureConfig.onSystemReady(); mOverlayReferenceMapper.rebuildIfDeferred(); - updateEntireShouldFilterCache(); + mFeatureConfig.onSystemReady(); + + updateEntireShouldFilterCacheAsync(); } /** @@ -510,10 +528,12 @@ public class AppsFilter { } mStateProvider.runWithState((settings, users) -> { addPackageInternal(newPkgSetting, settings); - if (mShouldFilterCache != null) { - updateShouldFilterCacheForPackage( - null, newPkgSetting, settings, users, settings.size()); - } // else, rebuild entire cache when system is ready + synchronized (mCacheLock) { + if (mShouldFilterCache != null) { + updateShouldFilterCacheForPackage(mShouldFilterCache, null, newPkgSetting, + settings, users, settings.size()); + } // else, rebuild entire cache when system is ready + } }); } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); @@ -607,6 +627,7 @@ public class AppsFilter { mFeatureConfig.updatePackageState(newPkgSetting, false /*removed*/); } + @GuardedBy("mCacheLock") private void removeAppIdFromVisibilityCache(int appId) { if (mShouldFilterCache == null) { return; @@ -625,33 +646,47 @@ public class AppsFilter { } } + private void updateEntireShouldFilterCacheAsync() { + mBackgroundExecutor.execute(this::updateEntireShouldFilterCache); + } + private void updateEntireShouldFilterCache() { mStateProvider.runWithState((settings, users) -> { - mShouldFilterCache.clear(); + SparseArray cache = + new SparseArray<>(users.length * settings.size()); for (int i = settings.size() - 1; i >= 0; i--) { - updateShouldFilterCacheForPackage( + updateShouldFilterCacheForPackage(cache, null /*skipPackage*/, settings.valueAt(i), settings, users, i); } + synchronized (mCacheLock) { + mShouldFilterCache = cache; + } }); } public void onUsersChanged() { - if (mShouldFilterCache != null) { - updateEntireShouldFilterCache(); + synchronized (mCacheLock) { + if (mShouldFilterCache != null) { + updateEntireShouldFilterCache(); + } } } private void updateShouldFilterCacheForPackage(String packageName) { - mStateProvider.runWithState((settings, users) -> { - updateShouldFilterCacheForPackage(null /* skipPackage */, settings.get(packageName), - settings, users, settings.size() /*maxIndex*/); - }); - + synchronized (mCacheLock) { + if (mShouldFilterCache != null) { + mStateProvider.runWithState((settings, users) -> { + updateShouldFilterCacheForPackage(mShouldFilterCache, null /* skipPackage */, + settings.get(packageName), settings, users, + settings.size() /*maxIndex*/); + }); + } + } } - private void updateShouldFilterCacheForPackage(@Nullable String skipPackageName, - PackageSetting subjectSetting, ArrayMap allSettings, - UserInfo[] allUsers, int maxIndex) { + private void updateShouldFilterCacheForPackage(SparseArray cache, + @Nullable String skipPackageName, PackageSetting subjectSetting, ArrayMap allSettings, UserInfo[] allUsers, int maxIndex) { for (int i = Math.min(maxIndex, allSettings.size() - 1); i >= 0; i--) { PackageSetting otherSetting = allSettings.valueAt(i); if (subjectSetting.appId == otherSetting.appId) { @@ -668,17 +703,17 @@ public class AppsFilter { for (int ou = 0; ou < userCount; ou++) { int otherUser = allUsers[ou].id; int subjectUid = UserHandle.getUid(subjectUser, subjectSetting.appId); - if (!mShouldFilterCache.contains(subjectUid)) { - mShouldFilterCache.put(subjectUid, new SparseBooleanArray(appxUidCount)); + if (!cache.contains(subjectUid)) { + cache.put(subjectUid, new SparseBooleanArray(appxUidCount)); } int otherUid = UserHandle.getUid(otherUser, otherSetting.appId); - if (!mShouldFilterCache.contains(otherUid)) { - mShouldFilterCache.put(otherUid, new SparseBooleanArray(appxUidCount)); + if (!cache.contains(otherUid)) { + cache.put(otherUid, new SparseBooleanArray(appxUidCount)); } - mShouldFilterCache.get(subjectUid).put(otherUid, + cache.get(subjectUid).put(otherUid, shouldFilterApplicationInternal( subjectUid, subjectSetting, otherSetting, otherUser)); - mShouldFilterCache.get(otherUid).put(subjectUid, + cache.get(otherUid).put(subjectUid, shouldFilterApplicationInternal( otherUid, otherSetting, subjectSetting, subjectUser)); } @@ -712,7 +747,8 @@ public class AppsFilter { * This method recomputes all component / intent-based visibility and is intended to match the * relevant logic of {@link #addPackageInternal(PackageSetting, ArrayMap)} */ - private void recomputeComponentVisibility(ArrayMap existingSettings) { + private void recomputeComponentVisibility( + ArrayMap existingSettings) { mQueriesViaComponent.clear(); for (int i = existingSettings.size() - 1; i >= 0; i--) { PackageSetting setting = existingSettings.valueAt(i); @@ -854,15 +890,17 @@ public class AppsFilter { } } - removeAppIdFromVisibilityCache(setting.appId); - if (mShouldFilterCache != null && setting.sharedUser != null) { - for (int i = setting.sharedUser.packages.size() - 1; i >= 0; i--) { - PackageSetting siblingSetting = setting.sharedUser.packages.valueAt(i); - if (siblingSetting == setting) { - continue; + synchronized (mCacheLock) { + removeAppIdFromVisibilityCache(setting.appId); + if (mShouldFilterCache != null && setting.sharedUser != null) { + for (int i = setting.sharedUser.packages.size() - 1; i >= 0; i--) { + PackageSetting siblingSetting = setting.sharedUser.packages.valueAt(i); + if (siblingSetting == setting) { + continue; + } + updateShouldFilterCacheForPackage(mShouldFilterCache, setting.name, + siblingSetting, settings, users, settings.size()); } - updateShouldFilterCacheForPackage( - setting.name, siblingSetting, settings, users, settings.size()); } } }); @@ -888,26 +926,29 @@ public class AppsFilter { || callingAppId == targetPkgSetting.appId) { return false; } - if (mShouldFilterCache != null) { // use cache - SparseBooleanArray shouldFilterTargets = mShouldFilterCache.get(callingUid); - final int targetUid = UserHandle.getUid(userId, targetPkgSetting.appId); - if (shouldFilterTargets == null) { - Slog.wtf(TAG, "Encountered calling uid with no cached rules: " + callingUid); - return true; - } - int indexOfTargetUid = shouldFilterTargets.indexOfKey(targetUid); - if (indexOfTargetUid < 0) { - Slog.w(TAG, "Encountered calling -> target with no cached rules: " - + callingUid + " -> " + targetUid); - return true; - } - if (!shouldFilterTargets.valueAt(indexOfTargetUid)) { - return false; - } - } else { - if (!shouldFilterApplicationInternal( - callingUid, callingSetting, targetPkgSetting, userId)) { - return false; + synchronized (mCacheLock) { + if (mShouldFilterCache != null) { // use cache + SparseBooleanArray shouldFilterTargets = mShouldFilterCache.get(callingUid); + final int targetUid = UserHandle.getUid(userId, targetPkgSetting.appId); + if (shouldFilterTargets == null) { + Slog.wtf(TAG, "Encountered calling uid with no cached rules: " + + callingUid); + return true; + } + int indexOfTargetUid = shouldFilterTargets.indexOfKey(targetUid); + if (indexOfTargetUid < 0) { + Slog.w(TAG, "Encountered calling -> target with no cached rules: " + + callingUid + " -> " + targetUid); + return true; + } + if (!shouldFilterTargets.valueAt(indexOfTargetUid)) { + return false; + } + } else { + if (!shouldFilterApplicationInternal( + callingUid, callingSetting, targetPkgSetting, userId)) { + return false; + } } } if (DEBUG_LOGGING || mFeatureConfig.isLoggingEnabled(callingAppId)) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 63c721a5da7b..4eae0da205ed 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -21413,8 +21413,6 @@ public class PackageManagerService extends IPackageManager.Stub .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL); co.onChange(true); - mAppsFilter.onSystemReady(); - // Disable any carrier apps. We do this very early in boot to prevent the apps from being // disabled after already being started. CarrierAppUtils.disableCarrierAppsUntilPrivileged( @@ -21563,6 +21561,8 @@ public class PackageManagerService extends IPackageManager.Stub mInstallerService.restoreAndApplyStagedSessionIfNeeded(); mExistingPackages = null; + + mAppsFilter.onSystemReady(); } public void waitForAppDataPrepared() { diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java index 26230949cda6..480a02de064a 100644 --- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java @@ -72,6 +72,7 @@ import java.util.Map; import java.util.Set; import java.util.function.IntFunction; import java.util.stream.Collectors; +import java.util.concurrent.Executor; @Presubmit @RunWith(JUnit4.class) @@ -91,6 +92,8 @@ public class AppsFilterTest { AppsFilter.FeatureConfig mFeatureConfigMock; @Mock AppsFilter.StateProvider mStateProvider; + @Mock + Executor mMockExecutor; private ArrayMap mExisting = new ArrayMap<>(); @@ -187,10 +190,15 @@ public class AppsFilterTest { doAnswer(invocation -> { ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0)) .currentState(mExisting, USER_INFO_LIST); - return null; + return new Object(); }).when(mStateProvider) .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class)); + doAnswer(invocation -> { + ((Runnable) invocation.getArgument(0)).run(); + return new Object(); + }).when(mMockExecutor).execute(any(Runnable.class)); + when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true); when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))).thenAnswer( (Answer) invocation -> @@ -201,7 +209,8 @@ public class AppsFilterTest { @Test public void testSystemReadyPropogates() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); appsFilter.onSystemReady(); verify(mFeatureConfigMock).onSystemReady(); } @@ -209,7 +218,8 @@ public class AppsFilterTest { @Test public void testQueriesAction_FilterMatches() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -225,7 +235,8 @@ public class AppsFilterTest { @Test public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); final Signature frameworkSignature = Mockito.mock(Signature.class); final PackageParser.SigningDetails frameworkSigningDetails = new PackageParser.SigningDetails(new Signature[]{frameworkSignature}, 1); @@ -263,7 +274,8 @@ public class AppsFilterTest { @Test public void testQueriesProvider_FilterMatches() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -280,7 +292,8 @@ public class AppsFilterTest { @Test public void testQueriesDifferentProvider_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -297,7 +310,8 @@ public class AppsFilterTest { @Test public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -315,7 +329,8 @@ public class AppsFilterTest { @Test public void testQueriesAction_NoMatchingAction_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -331,7 +346,8 @@ public class AppsFilterTest { @Test public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -351,7 +367,8 @@ public class AppsFilterTest { @Test public void testNoQueries_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -367,7 +384,8 @@ public class AppsFilterTest { @Test public void testForceQueryable_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -384,7 +402,7 @@ public class AppsFilterTest { public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception { final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"}, - false, null); + false, null, mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -402,7 +420,8 @@ public class AppsFilterTest { @Test public void testSystemSignedTarget_DoesntFilter() throws CertificateException { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); appsFilter.onSystemReady(); final Signature frameworkSignature = Mockito.mock(Signature.class); @@ -431,7 +450,7 @@ public class AppsFilterTest { public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception { final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"}, - false, null); + false, null, mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -449,7 +468,7 @@ public class AppsFilterTest { public void testSystemQueryable_DoesntFilter() throws Exception { final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, - true /* system force queryable */, null); + true /* system force queryable */, null, mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -466,7 +485,8 @@ public class AppsFilterTest { @Test public void testQueriesPackage_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -484,7 +504,8 @@ public class AppsFilterTest { when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))) .thenReturn(false); final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -500,7 +521,8 @@ public class AppsFilterTest { @Test public void testSystemUid_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -515,7 +537,8 @@ public class AppsFilterTest { @Test public void testSystemUidSecondaryUser_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -531,7 +554,8 @@ public class AppsFilterTest { @Test public void testNonSystemUid_NoCallingSetting_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -545,7 +569,8 @@ public class AppsFilterTest { @Test public void testNoTargetPackage_filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -603,7 +628,8 @@ public class AppsFilterTest { } return Collections.emptyMap(); } - }); + }, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -675,7 +701,8 @@ public class AppsFilterTest { } return Collections.emptyMap(); } - }); + }, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -700,7 +727,8 @@ public class AppsFilterTest { @Test public void testInitiatingApp_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -716,7 +744,8 @@ public class AppsFilterTest { @Test public void testUninstalledInitiatingApp_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -732,7 +761,8 @@ public class AppsFilterTest { @Test public void testOriginatingApp_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -748,7 +778,8 @@ public class AppsFilterTest { @Test public void testInstallingApp_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -764,7 +795,8 @@ public class AppsFilterTest { @Test public void testInstrumentation_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -786,7 +818,8 @@ public class AppsFilterTest { @Test public void testWhoCanSee() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); -- GitLab From 16aa67ef5e09517161fac60013bafa2d3efcba1d Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Fri, 28 Aug 2020 15:55:57 -0700 Subject: [PATCH 324/536] [BugFix][Fingerprint]fix client was canceled by service by mistake issue: After the call of client A started in the lockout state returns, after client B calls the fp service, A is dead, a death notification will be sent to the service, and the service will stop clent B. solution: Each time onAuthentication sets a flag mAlreadyDone to true. Judge this flag as true in binderDie, and keep the current fingerprint operation to avoid affecting the current user Signed-off-by: zhangyupeng1 Change-Id: I56ce99505febbb48dc13ccfc3c2d120123da4fa3 Merged-In: I56ce99505febbb48dc13ccfc3c2d120123da4fa3 --- .../com/android/server/biometrics/AuthenticationClient.java | 3 +++ .../java/com/android/server/biometrics/ClientMonitor.java | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java index edc8f15a9a03..ef1b574c29a8 100644 --- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java @@ -221,6 +221,9 @@ public abstract class AuthenticationClient extends ClientMonitor { } } result = lockoutMode != LOCKOUT_NONE; // in a lockout mode + if(result) { // locked out + mAlreadyDone = true; + } } } catch (RemoteException e) { Slog.e(getLogTag(), "Remote exception", e); diff --git a/services/core/java/com/android/server/biometrics/ClientMonitor.java b/services/core/java/com/android/server/biometrics/ClientMonitor.java index b02969524221..846beb016363 100644 --- a/services/core/java/com/android/server/biometrics/ClientMonitor.java +++ b/services/core/java/com/android/server/biometrics/ClientMonitor.java @@ -237,6 +237,10 @@ public abstract class ClientMonitor extends LoggableMonitor implements IBinder.D } void binderDiedInternal(boolean clearListener) { + if (isAlreadyDone()) { + Slog.w(getLogTag(), "Binder died but client is finished, ignoring"); + return; + } // If the current client dies we should cancel the current operation. Slog.e(getLogTag(), "Binder died, cancelling client"); stop(false /* initiatedByClient */); -- GitLab From 4e9ce69d066d29bf9af582f3760cfc668fee502d Mon Sep 17 00:00:00 2001 From: Keun young Park Date: Tue, 18 Aug 2020 17:25:19 -0700 Subject: [PATCH 325/536] Do not update nightmode from settings for car - Storing is disabled, so restoration should be disabled as well. - The old behavior is problematic in device like car as car should stay in night mode even if there is a user switching. - Add check for both mCarModeEnabled and mCar as mCarModeEnabled actually means car dock which is not enabled in car env (mCar=true) Bug: 155167849 Test: run user switching and confirm no night mode change in car Change-Id: I03a4649ef0848d14b2af3da43178c0dfe3f26a32 Merged-In: I03a4649ef0848d14b2af3da43178c0dfe3f26a32 (cherry picked from commit 1a6875361138391e09759af1b0641aa3114ad47d) --- .../java/com/android/server/UiModeManagerService.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index be080e5cce62..b5aea75d78a5 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -485,6 +485,9 @@ final class UiModeManagerService extends SystemService { * @return True if the new value is different from the old value. False otherwise. */ private boolean updateNightModeFromSettingsLocked(Context context, Resources res, int userId) { + if (mCarModeEnabled || mCar) { + return false; + } int oldNightMode = mNightMode; if (mSetupWizardComplete) { mNightMode = Secure.getIntForUser(context.getContentResolver(), @@ -1015,7 +1018,7 @@ final class UiModeManagerService extends SystemService { private void persistNightMode(int user) { // Only persist setting if not in car mode - if (mCarModeEnabled) return; + if (mCarModeEnabled || mCar) return; Secure.putIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE, mNightMode, user); Secure.putLongForUser(getContext().getContentResolver(), @@ -1028,7 +1031,7 @@ final class UiModeManagerService extends SystemService { private void persistNightModeOverrides(int user) { // Only persist setting if not in car mode - if (mCarModeEnabled) return; + if (mCarModeEnabled || mCar) return; Secure.putIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE_OVERRIDE_ON, mOverrideNightModeOn ? 1 : 0, user); Secure.putIntForUser(getContext().getContentResolver(), @@ -1079,7 +1082,7 @@ final class UiModeManagerService extends SystemService { } // Override night mode in power save mode if not in car mode - if (mPowerSave && !mCarModeEnabled) { + if (mPowerSave && !mCarModeEnabled && !mCar) { uiMode &= ~Configuration.UI_MODE_NIGHT_NO; uiMode |= Configuration.UI_MODE_NIGHT_YES; } else { -- GitLab From c3633c0dbf38b3fb57121efd4d29f88f75ab81ca Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Thu, 27 Aug 2020 17:07:15 -0700 Subject: [PATCH 326/536] Use WifiEntry#shouldShowXLevelIcon() to show X in level icon Bug: 163627176 Test: make RunSettingsLibRoboTests ROBOTEST_FILTER=WifiEntryPreferenceTest Change-Id: Icc62c6e1b8a3e13bf8e37eeb358fb8532907a65c --- .../settingslib/wifi/WifiEntryPreference.java | 7 +--- .../wifi/WifiEntryPreferenceTest.java | 40 +------------------ 2 files changed, 3 insertions(+), 44 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java index bba69f29a290..aad0d3af6626 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java @@ -35,7 +35,6 @@ import androidx.preference.PreferenceViewHolder; import com.android.settingslib.R; import com.android.settingslib.Utils; import com.android.wifitrackerlib.WifiEntry; -import com.android.wifitrackerlib.WifiEntry.ConnectedInfo; /** * Preference to display a WifiEntry in a wifi picker. @@ -138,11 +137,7 @@ public class WifiEntryPreference extends Preference implements WifiEntry.WifiEnt public void refresh() { setTitle(mWifiEntry.getTitle()); final int level = mWifiEntry.getLevel(); - final ConnectedInfo connectedInfo = mWifiEntry.getConnectedInfo(); - boolean showX = false; - if (connectedInfo != null) { - showX = !connectedInfo.isDefaultNetwork || !connectedInfo.isValidated; - } + final boolean showX = mWifiEntry.shouldShowXLevelIcon(); if (level != mLevel || showX != mShowX) { mLevel = level; mShowX = showX; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java index 40af7dc797b3..c21830b28e3a 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java @@ -17,7 +17,6 @@ package com.android.settingslib.wifi; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.Context; @@ -30,7 +29,6 @@ import androidx.preference.PreferenceViewHolder; import com.android.settingslib.R; import com.android.wifitrackerlib.WifiEntry; -import com.android.wifitrackerlib.WifiEntry.ConnectedInfo; import org.junit.Before; import org.junit.Test; @@ -179,43 +177,9 @@ public class WifiEntryPreferenceTest { } @Test - public void levelChanged_notDefaultWifiRefresh_shouldUpdateLevelIcon() { + public void levelChanged_showXWifiRefresh_shouldUpdateLevelIcon() { final List iconList = new ArrayList<>(); - final ConnectedInfo mockConnectedInfo = mock(ConnectedInfo.class); - mockConnectedInfo.isDefaultNetwork = false; - when(mMockWifiEntry.getConnectedInfo()).thenReturn(mockConnectedInfo); - final WifiEntryPreference pref = - new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector); - - when(mMockWifiEntry.getLevel()).thenReturn(0); - pref.refresh(); - iconList.add(pref.getIcon()); - when(mMockWifiEntry.getLevel()).thenReturn(1); - pref.refresh(); - iconList.add(pref.getIcon()); - when(mMockWifiEntry.getLevel()).thenReturn(2); - pref.refresh(); - iconList.add(pref.getIcon()); - when(mMockWifiEntry.getLevel()).thenReturn(3); - pref.refresh(); - iconList.add(pref.getIcon()); - when(mMockWifiEntry.getLevel()).thenReturn(4); - pref.refresh(); - iconList.add(pref.getIcon()); - when(mMockWifiEntry.getLevel()).thenReturn(-1); - pref.refresh(); - iconList.add(pref.getIcon()); - - assertThat(iconList).containsExactly(mMockShowXDrawable0, mMockShowXDrawable1, - mMockShowXDrawable2, mMockShowXDrawable3, mMockShowXDrawable4, null); - } - - @Test - public void levelChanged_notValidatedWifiRefresh_shouldUpdateLevelIcon() { - final List iconList = new ArrayList<>(); - final ConnectedInfo mockConnectedInfo = mock(ConnectedInfo.class); - mockConnectedInfo.isValidated = false; - when(mMockWifiEntry.getConnectedInfo()).thenReturn(mockConnectedInfo); + when(mMockWifiEntry.shouldShowXLevelIcon()).thenReturn(true); final WifiEntryPreference pref = new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector); -- GitLab From 697c2f94379b304826ced6caefac4597a6c2f5af Mon Sep 17 00:00:00 2001 From: Patrick Baumann Date: Fri, 28 Aug 2020 16:09:48 +0000 Subject: [PATCH 327/536] Only allow system apps to be forceQueryable This change ensures that only system apps can declare themselves forceQueryable via manifest. Fixes: 166780599 Test: atest AppEnumerationTests Change-Id: Ib217ade392500f97a7ff5a08b781cc99e60838ff Merged-In: Ib217ade392500f97a7ff5a08b781cc99e60838ff --- .../com/android/server/pm/AppsFilter.java | 4 ++-- .../com/android/server/pm/AppsFilterTest.java | 22 +++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java index c3c2e5e65103..069a00f03a1d 100644 --- a/services/core/java/com/android/server/pm/AppsFilter.java +++ b/services/core/java/com/android/server/pm/AppsFilter.java @@ -547,9 +547,9 @@ public class AppsFilter { final boolean newIsForceQueryable = mForceQueryable.contains(newPkgSetting.appId) /* shared user that is already force queryable */ - || newPkg.isForceQueryable() - || newPkgSetting.forceQueryableOverride + || newPkgSetting.forceQueryableOverride /* adb override */ || (newPkgSetting.isSystem() && (mSystemAppsQueryable + || newPkg.isForceQueryable() || ArrayUtils.contains(mForceQueryableByDevicePackageNames, newPkg.getPackageName()))); if (newIsForceQueryable diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java index 26230949cda6..37aedac8f28e 100644 --- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java @@ -365,14 +365,15 @@ public class AppsFilterTest { } @Test - public void testForceQueryable_DoesntFilter() throws Exception { + public void testForceQueryable_SystemDoesntFilter() throws Exception { final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); PackageSetting target = simulateAddPackage(appsFilter, - pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID); + pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID, + setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)); PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"), DUMMY_CALLING_APPID); @@ -380,6 +381,23 @@ public class AppsFilterTest { SYSTEM_USER)); } + + @Test + public void testForceQueryable_NonSystemFilters() throws Exception { + final AppsFilter appsFilter = + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); + simulateAddBasicAndroid(appsFilter); + appsFilter.onSystemReady(); + + PackageSetting target = simulateAddPackage(appsFilter, + pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID); + PackageSetting calling = simulateAddPackage(appsFilter, + pkg("com.some.other.package"), DUMMY_CALLING_APPID); + + assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target, + SYSTEM_USER)); + } + @Test public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception { final AppsFilter appsFilter = -- GitLab From 0c5affb4c42d1dcb41395df4ea1a8100d2033e64 Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Tue, 11 Aug 2020 09:07:20 -0400 Subject: [PATCH 328/536] Media - Add player sorting Use various criteria to maintain a sorting order of media players. Leverage TreeMap to maintain order upon player add/update. Bug: 161002989 Bug: 160242133 Merged-in: I07d0219523289fc8c5950d078bd0960bbdb1cc37 Test: manual, using various player types Change-Id: I07d0219523289fc8c5950d078bd0960bbdb1cc37 (cherry picked from commit 642eae6b2f9aca15058e3943042ada18818929bc) --- .../systemui/media/MediaCarouselController.kt | 130 ++++++++++-------- .../com/android/systemui/media/MediaData.kt | 4 + .../systemui/media/MediaDataManager.kt | 11 +- .../media/MediaDataCombineLatestTest.java | 4 +- .../systemui/media/MediaPlayerDataTest.kt | 122 ++++++++++++++++ 5 files changed, 212 insertions(+), 59 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index 15c60921cca5..865b11f7b738 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -11,6 +11,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.LinearLayout +import androidx.annotation.VisibleForTesting import com.android.systemui.R import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.ActivityStarter @@ -22,6 +23,7 @@ import com.android.systemui.util.Utils import com.android.systemui.util.animation.UniqueObjectHostView import com.android.systemui.util.animation.requiresRemeasuring import com.android.systemui.util.concurrency.DelayableExecutor +import java.util.TreeMap import javax.inject.Inject import javax.inject.Provider import javax.inject.Singleton @@ -103,9 +105,7 @@ class MediaCarouselController @Inject constructor( private val mediaCarousel: MediaScrollView private val mediaCarouselScrollHandler: MediaCarouselScrollHandler val mediaFrame: ViewGroup - val mediaPlayers: MutableMap = mutableMapOf() private lateinit var settingsButton: View - private val mediaData: MutableMap = mutableMapOf() private val mediaContent: ViewGroup private val pageIndicator: PageIndicator private val visualStabilityCallback: VisualStabilityManager.Callback @@ -123,7 +123,7 @@ class MediaCarouselController @Inject constructor( set(value) { if (field != value) { field = value - for (player in mediaPlayers.values) { + for (player in MediaPlayerData.players()) { player.setListening(field) } } @@ -168,20 +168,17 @@ class MediaCarouselController @Inject constructor( true /* persistent */) mediaManager.addListener(object : MediaDataManager.Listener { override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) { - oldKey?.let { mediaData.remove(it) } if (!data.active && !Utils.useMediaResumption(context)) { // This view is inactive, let's remove this! This happens e.g when dismissing / // timing out a view. We still have the data around because resumption could // be on, but we should save the resources and release this. onMediaDataRemoved(key) } else { - mediaData.put(key, data) addOrUpdatePlayer(key, oldKey, data) } } override fun onMediaDataRemoved(key: String) { - mediaData.remove(key) removePlayer(key) } }) @@ -224,53 +221,36 @@ class MediaCarouselController @Inject constructor( } private fun reorderAllPlayers() { - for (mediaPlayer in mediaPlayers.values) { - val view = mediaPlayer.view?.player - if (mediaPlayer.isPlaying && mediaContent.indexOfChild(view) != 0) { - mediaContent.removeView(view) - mediaContent.addView(view, 0) + mediaContent.removeAllViews() + for (mediaPlayer in MediaPlayerData.players()) { + mediaPlayer.view?.let { + mediaContent.addView(it.player) } } mediaCarouselScrollHandler.onPlayersChanged() } private fun addOrUpdatePlayer(key: String, oldKey: String?, data: MediaData) { - // If the key was changed, update entry - val oldData = mediaPlayers[oldKey] - if (oldData != null) { - val oldData = mediaPlayers.remove(oldKey) - mediaPlayers.put(key, oldData!!)?.let { - Log.wtf(TAG, "new key $key already exists when migrating from $oldKey") - } - } - var existingPlayer = mediaPlayers[key] + val existingPlayer = MediaPlayerData.getMediaPlayer(key, oldKey) if (existingPlayer == null) { - existingPlayer = mediaControlPanelFactory.get() - existingPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context), - mediaContent)) - existingPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions - mediaPlayers[key] = existingPlayer + var newPlayer = mediaControlPanelFactory.get() + newPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context), mediaContent)) + newPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions + MediaPlayerData.addMediaPlayer(key, data, newPlayer) val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) - existingPlayer.view?.player?.setLayoutParams(lp) - existingPlayer.bind(data) - existingPlayer.setListening(currentlyExpanded) - updatePlayerToState(existingPlayer, noAnimation = true) - if (existingPlayer.isPlaying) { - mediaContent.addView(existingPlayer.view?.player, 0) - } else { - mediaContent.addView(existingPlayer.view?.player) - } + newPlayer.view?.player?.setLayoutParams(lp) + newPlayer.bind(data) + newPlayer.setListening(currentlyExpanded) + updatePlayerToState(newPlayer, noAnimation = true) + reorderAllPlayers() } else { existingPlayer.bind(data) - if (existingPlayer.isPlaying && - mediaContent.indexOfChild(existingPlayer.view?.player) != 0) { - if (visualStabilityManager.isReorderingAllowed) { - mediaContent.removeView(existingPlayer.view?.player) - mediaContent.addView(existingPlayer.view?.player, 0) - } else { - needsReordering = true - } + MediaPlayerData.addMediaPlayer(key, data, existingPlayer) + if (visualStabilityManager.isReorderingAllowed) { + reorderAllPlayers() + } else { + needsReordering = true } } updatePageIndicator() @@ -278,13 +258,13 @@ class MediaCarouselController @Inject constructor( mediaCarousel.requiresRemeasuring = true // Check postcondition: mediaContent should have the same number of children as there are // elements in mediaPlayers. - if (mediaPlayers.size != mediaContent.childCount) { + if (MediaPlayerData.players().size != mediaContent.childCount) { Log.wtf(TAG, "Size of players list and number of views in carousel are out of sync") } } private fun removePlayer(key: String) { - val removed = mediaPlayers.remove(key) + val removed = MediaPlayerData.removeMediaPlayer(key) removed?.apply { mediaCarouselScrollHandler.onPrePlayerRemoved(removed) mediaContent.removeView(removed.view?.player) @@ -295,12 +275,7 @@ class MediaCarouselController @Inject constructor( } private fun recreatePlayers() { - // Note that this will scramble the order of players. Actively playing sessions will, at - // least, still be put in the front. If we want to maintain order, then more work is - // needed. - mediaData.forEach { - key, data -> - removePlayer(key) + MediaPlayerData.mediaData().forEach { (key, data) -> addOrUpdatePlayer(key = key, oldKey = null, data = data) } } @@ -338,7 +313,7 @@ class MediaCarouselController @Inject constructor( currentStartLocation = startLocation currentEndLocation = endLocation currentTransitionProgress = progress - for (mediaPlayer in mediaPlayers.values) { + for (mediaPlayer in MediaPlayerData.players()) { updatePlayerToState(mediaPlayer, immediately) } maybeResetSettingsCog() @@ -387,7 +362,7 @@ class MediaCarouselController @Inject constructor( private fun updateCarouselDimensions() { var width = 0 var height = 0 - for (mediaPlayer in mediaPlayers.values) { + for (mediaPlayer in MediaPlayerData.players()) { val controller = mediaPlayer.mediaViewController // When transitioning the view to gone, the view gets smaller, but the translation // Doesn't, let's add the translation @@ -449,7 +424,7 @@ class MediaCarouselController @Inject constructor( this.desiredLocation = desiredLocation this.desiredHostState = it currentlyExpanded = it.expansion > 0 - for (mediaPlayer in mediaPlayers.values) { + for (mediaPlayer in MediaPlayerData.players()) { if (animate) { mediaPlayer.mediaViewController.animatePendingStateChange( duration = duration, @@ -471,7 +446,7 @@ class MediaCarouselController @Inject constructor( } fun closeGuts() { - mediaPlayers.values.forEach { + MediaPlayerData.players().forEach { it.closeGuts(true) } } @@ -498,3 +473,50 @@ class MediaCarouselController @Inject constructor( } } } + +@VisibleForTesting +internal object MediaPlayerData { + private data class MediaSortKey( + val data: MediaData, + val updateTime: Long = 0, + val isPlaying: Boolean = false + ) + + private val comparator = + compareByDescending { it.isPlaying } + .thenByDescending { it.data.isLocalSession } + .thenByDescending { !it.data.resumption } + .thenByDescending { it.updateTime } + + private val mediaPlayers = TreeMap(comparator) + private val mediaData: MutableMap = mutableMapOf() + + fun addMediaPlayer(key: String, data: MediaData, player: MediaControlPanel) { + removeMediaPlayer(key) + val sortKey = MediaSortKey(data, System.currentTimeMillis(), player.isPlaying()) + mediaData.put(key, sortKey) + mediaPlayers.put(sortKey, player) + } + + fun getMediaPlayer(key: String, oldKey: String?): MediaControlPanel? { + // If the key was changed, update entry + oldKey?.let { + if (it != key) { + mediaData.remove(it)?.let { sortKey -> mediaData.put(key, sortKey) } + } + } + return mediaData.get(key)?.let { mediaPlayers.get(it) } + } + + fun removeMediaPlayer(key: String) = mediaData.remove(key)?.let { mediaPlayers.remove(it) } + + fun mediaData() = mediaData.entries.map { e -> Pair(e.key, e.value.data) } + + fun players() = mediaPlayers.values + + @VisibleForTesting + fun clear() { + mediaData.clear() + mediaPlayers.clear() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt index dafc52ad8025..d6a02687c905 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt @@ -81,6 +81,10 @@ data class MediaData( * Action that should be performed to restart a non active session. */ var resumeAction: Runnable?, + /** + * Local or remote playback + */ + var isLocalSession: Boolean = true, /** * Indicates that this player is a resumption player (ie. It only shows a play actions which * will start the app and start playing). diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 33475aca0bfb..1c6fb2034b5f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -31,6 +31,7 @@ import android.graphics.drawable.Drawable import android.graphics.drawable.Icon import android.media.MediaDescription import android.media.MediaMetadata +import android.media.session.MediaController import android.media.session.MediaSession import android.net.Uri import android.os.UserHandle @@ -337,7 +338,8 @@ class MediaDataManager( ) { val token = sbn.notification.extras.getParcelable(Notification.EXTRA_MEDIA_SESSION) as MediaSession.Token? - val metadata = mediaControllerFactory.create(token).metadata + val mediaController = mediaControllerFactory.create(token) + val metadata = mediaController.metadata // Foreground and Background colors computed from album art val notif: Notification = sbn.notification @@ -429,6 +431,9 @@ class MediaDataManager( } } + val isLocalSession = mediaController.playbackInfo?.playbackType == + MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL ?: true + foregroundExecutor.execute { val resumeAction: Runnable? = mediaEntries[key]?.resumeAction val hasCheckedForResume = mediaEntries[key]?.hasCheckedForResume == true @@ -436,8 +441,8 @@ class MediaDataManager( onMediaDataLoaded(key, oldKey, MediaData(sbn.normalizedUserId, true, bgColor, app, smallIconDrawable, artist, song, artWorkIcon, actionIcons, actionsToShowCollapsed, sbn.packageName, token, notif.contentIntent, null, - active, resumeAction = resumeAction, notificationKey = key, - hasCheckedForResume = hasCheckedForResume)) + active, resumeAction = resumeAction, isLocalSession = isLocalSession, + notificationKey = key, hasCheckedForResume = hasCheckedForResume)) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java index 492b33e3c4a6..2e794a40d238 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java @@ -83,8 +83,8 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { mManager.addListener(mListener); mMediaData = new MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, - new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null, true, null, false, - KEY, false); + new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null, true, null, true, + false, KEY, false); mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt new file mode 100644 index 000000000000..118cffc2d5b8 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2020 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.media + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.mock +import org.mockito.Mockito.`when` as whenever + +@SmallTest +@RunWith(AndroidTestingRunner::class) +public class MediaPlayerDataTest : SysuiTestCase() { + + companion object { + val LOCAL = true + val RESUMPTION = true + } + + @Before + fun setup() { + MediaPlayerData.clear() + } + + @Test + fun addPlayingThenRemote() { + val playerIsPlaying = mock(MediaControlPanel::class.java) + whenever(playerIsPlaying.isPlaying).thenReturn(true) + val dataIsPlaying = createMediaData(LOCAL, !RESUMPTION) + + val playerIsRemote = mock(MediaControlPanel::class.java) + whenever(playerIsRemote.isPlaying).thenReturn(false) + val dataIsRemote = createMediaData(!LOCAL, !RESUMPTION) + + MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying) + MediaPlayerData.addMediaPlayer("2", dataIsRemote, playerIsRemote) + + val players = MediaPlayerData.players() + assertThat(players).hasSize(2) + assertThat(players).containsExactly(playerIsPlaying, playerIsRemote).inOrder() + } + + @Test + fun switchPlayersPlaying() { + val playerIsPlaying1 = mock(MediaControlPanel::class.java) + whenever(playerIsPlaying1.isPlaying).thenReturn(true) + val dataIsPlaying1 = createMediaData(LOCAL, !RESUMPTION) + + val playerIsPlaying2 = mock(MediaControlPanel::class.java) + whenever(playerIsPlaying2.isPlaying).thenReturn(false) + val dataIsPlaying2 = createMediaData(LOCAL, !RESUMPTION) + + MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1) + MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2) + + whenever(playerIsPlaying1.isPlaying).thenReturn(false) + whenever(playerIsPlaying2.isPlaying).thenReturn(true) + + MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1) + MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2) + + val players = MediaPlayerData.players() + assertThat(players).hasSize(2) + assertThat(players).containsExactly(playerIsPlaying2, playerIsPlaying1).inOrder() + } + + @Test + fun fullOrderTest() { + val playerIsPlaying = mock(MediaControlPanel::class.java) + whenever(playerIsPlaying.isPlaying).thenReturn(true) + val dataIsPlaying = createMediaData(LOCAL, !RESUMPTION) + + val playerIsPlayingAndRemote = mock(MediaControlPanel::class.java) + whenever(playerIsPlayingAndRemote.isPlaying).thenReturn(true) + val dataIsPlayingAndRemote = createMediaData(!LOCAL, !RESUMPTION) + + val playerIsStoppedAndLocal = mock(MediaControlPanel::class.java) + whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false) + val dataIsStoppedAndLocal = createMediaData(LOCAL, !RESUMPTION) + + val playerIsStoppedAndRemote = mock(MediaControlPanel::class.java) + whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false) + val dataIsStoppedAndRemote = createMediaData(!LOCAL, !RESUMPTION) + + val playerCanResume = mock(MediaControlPanel::class.java) + whenever(playerCanResume.isPlaying).thenReturn(false) + val dataCanResume = createMediaData(LOCAL, RESUMPTION) + + MediaPlayerData.addMediaPlayer("3", dataIsStoppedAndLocal, playerIsStoppedAndLocal) + MediaPlayerData.addMediaPlayer("5", dataIsStoppedAndRemote, playerIsStoppedAndRemote) + MediaPlayerData.addMediaPlayer("4", dataCanResume, playerCanResume) + MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying) + MediaPlayerData.addMediaPlayer("2", dataIsPlayingAndRemote, playerIsPlayingAndRemote) + + val players = MediaPlayerData.players() + assertThat(players).hasSize(5) + assertThat(players).containsExactly(playerIsPlaying, playerIsPlayingAndRemote, + playerIsStoppedAndLocal, playerCanResume, playerIsStoppedAndRemote).inOrder() + } + + private fun createMediaData(isLocalSession: Boolean, resumption: Boolean) = + MediaData(0, false, 0, null, null, null, null, null, emptyList(), emptyList(), "", + null, null, null, true, null, isLocalSession, resumption, null, false) +} -- GitLab From e91551d5e500766bd93592db57c9428776714366 Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Mon, 31 Aug 2020 11:22:25 -0400 Subject: [PATCH 329/536] Media - Fix sysui crash on media image load Apps may throw various RuntimeExceptions when requesting a bitmap load over binder. Catch these so sysui doesn't crash loop. Fixes: 166647431 Test: use DoubleTwist app Change-Id: I7918768559afd3cc6c2f77922e1679d09859337d (cherry picked from commit 5009abe8e89a439947cf99f7a0949b04a98adf62) --- .../src/com/android/systemui/media/MediaDataManager.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 33475aca0bfb..ad2bb39ee453 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -481,7 +481,10 @@ class MediaDataManager( decoder, info, source -> decoder.isMutableRequired = true } } catch (e: IOException) { - e.printStackTrace() + Log.e(TAG, "Unable to load bitmap", e) + null + } catch (e: RuntimeException) { + Log.e(TAG, "Unable to load bitmap", e) null } } -- GitLab From 01e0f4813af8502faaa683d55dbbc024b3080741 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 31 Aug 2020 18:28:41 +0000 Subject: [PATCH 330/536] DO NOT MERGE Fix NPE in executeDeletePackageLIF. The parameter allUserHandles may sometimes be null. Change-Id: Ie58cabe4bb1cae7173ad1d027e993a0b82a9f1ef Bug: 167233572 Bug: 140256621 Test: atest EphemeralTest --- .../core/java/com/android/server/pm/PackageManagerService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 7a38a4533572..c3c655d632e7 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -19198,7 +19198,8 @@ public class PackageManagerService extends IPackageManager.Stub // We need to get the permission state before package state is (potentially) destroyed. final SparseBooleanArray hadSuspendAppsPermission = new SparseBooleanArray(); - for (int userId : allUserHandles) { + // allUserHandles could be null, so call mUserManager.getUserIds() directly which is cached anyway. + for (int userId : mUserManager.getUserIds()) { hadSuspendAppsPermission.put(userId, checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId) == PERMISSION_GRANTED); } -- GitLab From 4a6f9b97215f3fed60fe6dc2a9d285645e9fbeae Mon Sep 17 00:00:00 2001 From: kwaky Date: Fri, 28 Aug 2020 13:14:04 -0700 Subject: [PATCH 331/536] Fix AAOS SystemUI Presubmit tests that are breaking. Due to the newly added check in SystemBarConfig, tests can fail erroneously when testing behavior of when either top or bottom system bar is not enabled. Bug: 162599873 Bug: 165808744 Test: atest carsysui-presubmit --include-subdir passing. (5/5) Change-Id: Ife2ac4e746006c39eaf46cd0328c1639149891b2 Merged-In: Ife2ac4e746006c39eaf46cd0328c1639149891b2 --- .../CarNavigationBarControllerTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java index 0b164a2e1a51..84c840477302 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java @@ -48,6 +48,10 @@ import org.mockito.MockitoAnnotations; @SmallTest public class CarNavigationBarControllerTest extends SysuiTestCase { + private static final String TOP_NOTIFICATION_PANEL = + "com.android.systemui.car.notification.TopNotificationPanelViewMediator"; + private static final String BOTTOM_NOTIFICATION_PANEL = + "com.android.systemui.car.notification.BottomNotificationPanelViewMediator"; private CarNavigationBarController mCarNavigationBar; private NavigationBarViewFactory mNavigationBarViewFactory; private TestableResources mTestableResources; @@ -117,6 +121,11 @@ public class CarNavigationBarControllerTest extends SysuiTestCase { @Test public void testGetTopWindow_topDisabled_returnsNull() { mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, false); + mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true); + // If Top Notification Panel is used but top navigation bar is not enabled, SystemUI is + // expected to crash. + mTestableResources.addOverride(R.string.config_notificationPanelViewMediator, + BOTTOM_NOTIFICATION_PANEL); mCarNavigationBar = createNavigationBarController(); ViewGroup window = mCarNavigationBar.getTopWindow(); @@ -148,6 +157,11 @@ public class CarNavigationBarControllerTest extends SysuiTestCase { @Test public void testGetBottomWindow_bottomDisabled_returnsNull() { mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, false); + mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true); + // If Bottom Notification Panel is used but bottom navigation bar is not enabled, + // SystemUI is expected to crash. + mTestableResources.addOverride(R.string.config_notificationPanelViewMediator, + TOP_NOTIFICATION_PANEL); mCarNavigationBar = createNavigationBarController(); ViewGroup window = mCarNavigationBar.getBottomWindow(); -- GitLab From 56c3b76fc4b3f786ac7656646ac8d82e1e8d44f5 Mon Sep 17 00:00:00 2001 From: kwaky Date: Thu, 20 Aug 2020 13:52:48 -0700 Subject: [PATCH 332/536] Make SystemUI crash with warning if SystemBarConfigs is incompatible with NotificationPanelViewMediator. Bug: 162599873 Bug: 165806308 Test: Manual Change-Id: I855c03d11e31cf722609f2bb0b0cb6c01624b0c0 Merged-In: I855c03d11e31cf722609f2bb0b0cb6c01624b0c0 --- .../car/navigationbar/SystemBarConfigs.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java index 3527bf93682f..e7d31949eb24 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java @@ -29,6 +29,8 @@ import android.view.WindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; +import com.android.systemui.car.notification.BottomNotificationPanelViewMediator; +import com.android.systemui.car.notification.TopNotificationPanelViewMediator; import com.android.systemui.dagger.qualifiers.Main; import java.lang.annotation.ElementType; @@ -95,6 +97,7 @@ public class SystemBarConfigs { populateMaps(); readConfigs(); checkEnabledBarsHaveUniqueBarTypes(); + checkSystemBarEnabledForNotificationPanel(); setInsetPaddingsForOverlappingCorners(); sortSystemBarSidesByZOrder(); } @@ -221,6 +224,34 @@ public class SystemBarConfigs { } } + private void checkSystemBarEnabledForNotificationPanel() throws RuntimeException { + + String notificationPanelMediatorName = + mResources.getString(R.string.config_notificationPanelViewMediator); + if (notificationPanelMediatorName == null) { + return; + } + + Class notificationPanelMediatorUsed = null; + try { + notificationPanelMediatorUsed = Class.forName(notificationPanelMediatorName); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + if (!mTopNavBarEnabled && notificationPanelMediatorUsed.isAssignableFrom( + TopNotificationPanelViewMediator.class)) { + throw new RuntimeException( + "Top System Bar must be enabled to use " + notificationPanelMediatorName); + } + + if (!mBottomNavBarEnabled && notificationPanelMediatorUsed.isAssignableFrom( + BottomNotificationPanelViewMediator.class)) { + throw new RuntimeException("Bottom System Bar must be enabled to use " + + notificationPanelMediatorName); + } + } + private void setInsetPaddingsForOverlappingCorners() { setInsetPaddingForOverlappingCorner(TOP, LEFT); setInsetPaddingForOverlappingCorner(TOP, RIGHT); @@ -277,7 +308,7 @@ public class SystemBarConfigs { } private static boolean isHorizontalBar(@SystemBarSide int side) { - return side == TOP || side == BOTTOM; + return side == TOP || side == BOTTOM; } private static boolean isVerticalBar(@SystemBarSide int side) { -- GitLab From 4ed31efe0020faeafb062c2b1f86477cfe5e7180 Mon Sep 17 00:00:00 2001 From: Ben Lin Date: Mon, 31 Aug 2020 12:11:59 -0700 Subject: [PATCH 333/536] PiP: Hide menu when resize starts. Attempting to do resize while PIP menu is still visible causes weird isseus such as jank and flickering, so just hide it. This usually always happen already when user taps the outside bounds, but if the user starts from the inside corners it's problematic. Bug: 164882662 Test: Tap on PIP, see it expands and PIP menu shows up, try to resize - no more flickering Merged-In: If32aacc7e8d8f6784ad7fb83be14a8ba93c3491f Change-Id: I68b42195fa70d3f61fb42cb33297152a4da963fc --- .../systemui/pip/phone/PipResizeGestureHandler.java | 12 +++++++++--- .../android/systemui/pip/phone/PipTouchHandler.java | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java index ef73aa7cbbfe..badd8835cdd4 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java @@ -80,6 +80,7 @@ public class PipResizeGestureHandler { private final Context mContext; private final PipBoundsHandler mPipBoundsHandler; private final PipMotionHelper mMotionHelper; + private final PipMenuActivityController mMenuController; private final int mDisplayId; private final Executor mMainExecutor; private final SysUiState mSysUiState; @@ -117,13 +118,14 @@ public class PipResizeGestureHandler { public PipResizeGestureHandler(Context context, PipBoundsHandler pipBoundsHandler, PipMotionHelper motionHelper, DeviceConfigProxy deviceConfig, - PipTaskOrganizer pipTaskOrganizer, Function movementBoundsSupplier, - Runnable updateMovementBoundsRunnable, SysUiState sysUiState, - PipUiEventLogger pipUiEventLogger) { + PipTaskOrganizer pipTaskOrganizer, PipMenuActivityController pipMenuController, + Function movementBoundsSupplier, Runnable updateMovementBoundsRunnable, + SysUiState sysUiState, PipUiEventLogger pipUiEventLogger) { mContext = context; mDisplayId = context.getDisplayId(); mMainExecutor = context.getMainExecutor(); mPipBoundsHandler = pipBoundsHandler; + mMenuController = pipMenuController; mMotionHelper = motionHelper; mPipTaskOrganizer = pipTaskOrganizer; mMovementBoundsSupplier = movementBoundsSupplier; @@ -322,6 +324,10 @@ public class PipResizeGestureHandler { mInputMonitor.pilferPointers(); } if (mThresholdCrossed) { + if (mMenuController.isMenuActivityVisible()) { + mMenuController.hideMenuWithoutResize(); + mMenuController.hideMenu(); + } final Rect currentPipBounds = mMotionHelper.getBounds(); mLastResizeBounds.set(TaskResizingAlgorithm.resizeDrag(x, y, mDownPoint.x, mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x, diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index 0127ff310b78..11e609b2ffef 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -232,7 +232,7 @@ public class PipTouchHandler { mSnapAlgorithm, floatingContentCoordinator); mPipResizeGestureHandler = new PipResizeGestureHandler(context, pipBoundsHandler, mMotionHelper, - deviceConfig, pipTaskOrganizer, this::getMovementBounds, + deviceConfig, pipTaskOrganizer, menuController, this::getMovementBounds, this::updateMovementBounds, sysUiState, pipUiEventLogger); mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler, () -> mMenuController.showMenuWithDelay(MENU_STATE_FULL, mMotionHelper.getBounds(), -- GitLab From f21c885ca7e86f77c808ab17fe1de650474de487 Mon Sep 17 00:00:00 2001 From: Andrii Kulian Date: Fri, 31 Jul 2020 18:46:28 -0700 Subject: [PATCH 334/536] Require permission to create trusted displays Bug: 162627132 Test: atest VirtualDisplayTest#testTrustedVirtualDisplay Test: atest frameworks/base/packages/SystemUI/tests/src/com/android/systemui/bubbles Test: atest DisplayTest Test: atest VirtualDisplayTest#testTrustedVirtualDisplay Test: atest VirtualDisplayTest#testUntrustedSysDecorVirtualDisplay Test: adb logcat -b events Change-Id: Id06b2013ef5fdeadf321f14f8b611c733031d54d Merged-In: Id06b2013ef5fdeadf321f14f8b611c733031d54d --- core/java/android/app/ActivityView.java | 15 +++++++++++++-- .../window/VirtualDisplayTaskEmbedder.java | 9 ++++++++- core/tests/coretests/AndroidManifest.xml | 1 + .../hardware/display/VirtualDisplayTest.java | 19 +++++++++++++++++++ .../systemui/bubbles/BubbleExpandedView.java | 2 +- .../server/display/DisplayManagerService.java | 15 +++++++++++---- 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 98a23f2b0075..3cb6293f0706 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -105,7 +105,8 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd public ActivityView( @NonNull Context context, @NonNull AttributeSet attrs, int defStyle, boolean singleTaskInstance, boolean usePublicVirtualDisplay) { - this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay, false); + this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay, + false /* disableSurfaceViewBackgroundLayer */); } /** @hide */ @@ -113,12 +114,22 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd @NonNull Context context, @NonNull AttributeSet attrs, int defStyle, boolean singleTaskInstance, boolean usePublicVirtualDisplay, boolean disableSurfaceViewBackgroundLayer) { + this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay, + disableSurfaceViewBackgroundLayer, false /* useTrustedDisplay */); + } + + // TODO(b/162901735): Refactor ActivityView with Builder + /** @hide */ + public ActivityView( + @NonNull Context context, @NonNull AttributeSet attrs, int defStyle, + boolean singleTaskInstance, boolean usePublicVirtualDisplay, + boolean disableSurfaceViewBackgroundLayer, boolean useTrustedDisplay) { super(context, attrs, defStyle); if (useTaskOrganizer()) { mTaskEmbedder = new TaskOrganizerTaskEmbedder(context, this); } else { mTaskEmbedder = new VirtualDisplayTaskEmbedder(context, this, singleTaskInstance, - usePublicVirtualDisplay); + usePublicVirtualDisplay, useTrustedDisplay); } mSurfaceView = new SurfaceView(context, null, 0, 0, disableSurfaceViewBackgroundLayer); // Since ActivityView#getAlpha has been overridden, we should use parent class's alpha diff --git a/core/java/android/window/VirtualDisplayTaskEmbedder.java b/core/java/android/window/VirtualDisplayTaskEmbedder.java index 9ccb4c172158..9013da36007e 100644 --- a/core/java/android/window/VirtualDisplayTaskEmbedder.java +++ b/core/java/android/window/VirtualDisplayTaskEmbedder.java @@ -19,6 +19,7 @@ package android.window; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; import static android.view.Display.INVALID_DISPLAY; import android.app.ActivityManager; @@ -63,6 +64,7 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { private int mDisplayDensityDpi; private final boolean mSingleTaskInstance; private final boolean mUsePublicVirtualDisplay; + private final boolean mUseTrustedDisplay; private VirtualDisplay mVirtualDisplay; private Insets mForwardedInsets; private DisplayMetrics mTmpDisplayMetrics; @@ -77,10 +79,12 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { * only applicable if virtual displays are used */ public VirtualDisplayTaskEmbedder(Context context, VirtualDisplayTaskEmbedder.Host host, - boolean singleTaskInstance, boolean usePublicVirtualDisplay) { + boolean singleTaskInstance, boolean usePublicVirtualDisplay, + boolean useTrustedDisplay) { super(context, host); mSingleTaskInstance = singleTaskInstance; mUsePublicVirtualDisplay = usePublicVirtualDisplay; + mUseTrustedDisplay = useTrustedDisplay; } /** @@ -103,6 +107,9 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { if (mUsePublicVirtualDisplay) { virtualDisplayFlags |= VIRTUAL_DISPLAY_FLAG_PUBLIC; } + if (mUseTrustedDisplay) { + virtualDisplayFlags |= VIRTUAL_DISPLAY_FLAG_TRUSTED; + } mVirtualDisplay = displayManager.createVirtualDisplay( DISPLAY_NAME + "@" + System.identityHashCode(this), mHost.getWidth(), diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index 5c2841aff1d8..7597e8732153 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -129,6 +129,7 @@ + diff --git a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java index daf613976358..0f6284d22d10 100644 --- a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java +++ b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java @@ -247,6 +247,25 @@ public class VirtualDisplayTest extends AndroidTestCase { assertDisplayUnregistered(display); } + /** + * Ensures that an application can create a trusted virtual display with the permission + * {@code ADD_TRUSTED_DISPLAY}. + */ + public void testTrustedVirtualDisplay() throws Exception { + VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME, + WIDTH, HEIGHT, DENSITY, mSurface, + DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED); + assertNotNull("virtual display must not be null", virtualDisplay); + + Display display = virtualDisplay.getDisplay(); + try { + assertDisplayRegistered(display, Display.FLAG_PRIVATE | Display.FLAG_TRUSTED); + } finally { + virtualDisplay.release(); + } + assertDisplayUnregistered(display); + } + private void assertDisplayRegistered(Display display, int flags) { assertNotNull("display object must not be null", display); assertTrue("display must be valid", display.isValid()); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 3d3171208b15..110a5ab67f0d 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -301,7 +301,7 @@ public class BubbleExpandedView extends LinearLayout { mActivityView = new ActivityView(mContext, null /* attrs */, 0 /* defStyle */, true /* singleTaskInstance */, false /* usePublicVirtualDisplay*/, - true /* disableSurfaceViewBackgroundLayer */); + true /* disableSurfaceViewBackgroundLayer */, true /* useTrustedDisplay */); // Set ActivityView's alpha value as zero, since there is no view content to be shown. setContentVisibility(false); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 1058000e0b68..9a8be287690f 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -86,6 +86,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.text.TextUtils; +import android.util.EventLog; import android.util.IntArray; import android.util.Pair; import android.util.Slog; @@ -2191,10 +2192,16 @@ public final class DisplayManagerService extends SystemService { } } - if (callingUid == Process.SYSTEM_UID - || checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { - flags |= VIRTUAL_DISPLAY_FLAG_TRUSTED; - } else { + if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) { + if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { + EventLog.writeEvent(0x534e4554, "162627132", callingUid, + "Attempt to create a trusted display without holding permission!"); + throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + + "create a trusted virtual display."); + } + } + + if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) { flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; } -- GitLab From ef7b1333f0e87cd07af115719b94dd37e2de54dc Mon Sep 17 00:00:00 2001 From: Andrii Kulian Date: Fri, 31 Jul 2020 18:46:28 -0700 Subject: [PATCH 335/536] Require permission to create trusted displays Bug: 162627132 Test: atest VirtualDisplayTest#testTrustedVirtualDisplay Test: atest frameworks/base/packages/SystemUI/tests/src/com/android/systemui/bubbles Test: atest DisplayTest Test: atest VirtualDisplayTest#testTrustedVirtualDisplay Test: atest VirtualDisplayTest#testUntrustedSysDecorVirtualDisplay Test: adb logcat -b events Change-Id: Id06b2013ef5fdeadf321f14f8b611c733031d54d Merged-In: Id06b2013ef5fdeadf321f14f8b611c733031d54d --- core/java/android/app/ActivityView.java | 15 +++++++++++++-- .../window/VirtualDisplayTaskEmbedder.java | 9 ++++++++- core/tests/coretests/AndroidManifest.xml | 1 + .../hardware/display/VirtualDisplayTest.java | 19 +++++++++++++++++++ .../systemui/bubbles/BubbleExpandedView.java | 2 +- .../server/display/DisplayManagerService.java | 15 +++++++++++---- 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 98a23f2b0075..3cb6293f0706 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -105,7 +105,8 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd public ActivityView( @NonNull Context context, @NonNull AttributeSet attrs, int defStyle, boolean singleTaskInstance, boolean usePublicVirtualDisplay) { - this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay, false); + this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay, + false /* disableSurfaceViewBackgroundLayer */); } /** @hide */ @@ -113,12 +114,22 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd @NonNull Context context, @NonNull AttributeSet attrs, int defStyle, boolean singleTaskInstance, boolean usePublicVirtualDisplay, boolean disableSurfaceViewBackgroundLayer) { + this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay, + disableSurfaceViewBackgroundLayer, false /* useTrustedDisplay */); + } + + // TODO(b/162901735): Refactor ActivityView with Builder + /** @hide */ + public ActivityView( + @NonNull Context context, @NonNull AttributeSet attrs, int defStyle, + boolean singleTaskInstance, boolean usePublicVirtualDisplay, + boolean disableSurfaceViewBackgroundLayer, boolean useTrustedDisplay) { super(context, attrs, defStyle); if (useTaskOrganizer()) { mTaskEmbedder = new TaskOrganizerTaskEmbedder(context, this); } else { mTaskEmbedder = new VirtualDisplayTaskEmbedder(context, this, singleTaskInstance, - usePublicVirtualDisplay); + usePublicVirtualDisplay, useTrustedDisplay); } mSurfaceView = new SurfaceView(context, null, 0, 0, disableSurfaceViewBackgroundLayer); // Since ActivityView#getAlpha has been overridden, we should use parent class's alpha diff --git a/core/java/android/window/VirtualDisplayTaskEmbedder.java b/core/java/android/window/VirtualDisplayTaskEmbedder.java index 9ccb4c172158..9013da36007e 100644 --- a/core/java/android/window/VirtualDisplayTaskEmbedder.java +++ b/core/java/android/window/VirtualDisplayTaskEmbedder.java @@ -19,6 +19,7 @@ package android.window; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; import static android.view.Display.INVALID_DISPLAY; import android.app.ActivityManager; @@ -63,6 +64,7 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { private int mDisplayDensityDpi; private final boolean mSingleTaskInstance; private final boolean mUsePublicVirtualDisplay; + private final boolean mUseTrustedDisplay; private VirtualDisplay mVirtualDisplay; private Insets mForwardedInsets; private DisplayMetrics mTmpDisplayMetrics; @@ -77,10 +79,12 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { * only applicable if virtual displays are used */ public VirtualDisplayTaskEmbedder(Context context, VirtualDisplayTaskEmbedder.Host host, - boolean singleTaskInstance, boolean usePublicVirtualDisplay) { + boolean singleTaskInstance, boolean usePublicVirtualDisplay, + boolean useTrustedDisplay) { super(context, host); mSingleTaskInstance = singleTaskInstance; mUsePublicVirtualDisplay = usePublicVirtualDisplay; + mUseTrustedDisplay = useTrustedDisplay; } /** @@ -103,6 +107,9 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { if (mUsePublicVirtualDisplay) { virtualDisplayFlags |= VIRTUAL_DISPLAY_FLAG_PUBLIC; } + if (mUseTrustedDisplay) { + virtualDisplayFlags |= VIRTUAL_DISPLAY_FLAG_TRUSTED; + } mVirtualDisplay = displayManager.createVirtualDisplay( DISPLAY_NAME + "@" + System.identityHashCode(this), mHost.getWidth(), diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index 5c2841aff1d8..7597e8732153 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -129,6 +129,7 @@ + diff --git a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java index daf613976358..0f6284d22d10 100644 --- a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java +++ b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java @@ -247,6 +247,25 @@ public class VirtualDisplayTest extends AndroidTestCase { assertDisplayUnregistered(display); } + /** + * Ensures that an application can create a trusted virtual display with the permission + * {@code ADD_TRUSTED_DISPLAY}. + */ + public void testTrustedVirtualDisplay() throws Exception { + VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME, + WIDTH, HEIGHT, DENSITY, mSurface, + DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED); + assertNotNull("virtual display must not be null", virtualDisplay); + + Display display = virtualDisplay.getDisplay(); + try { + assertDisplayRegistered(display, Display.FLAG_PRIVATE | Display.FLAG_TRUSTED); + } finally { + virtualDisplay.release(); + } + assertDisplayUnregistered(display); + } + private void assertDisplayRegistered(Display display, int flags) { assertNotNull("display object must not be null", display); assertTrue("display must be valid", display.isValid()); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 1e556a3ed402..58d5776543a9 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -301,7 +301,7 @@ public class BubbleExpandedView extends LinearLayout { mActivityView = new ActivityView(mContext, null /* attrs */, 0 /* defStyle */, true /* singleTaskInstance */, false /* usePublicVirtualDisplay*/, - true /* disableSurfaceViewBackgroundLayer */); + true /* disableSurfaceViewBackgroundLayer */, true /* useTrustedDisplay */); // Set ActivityView's alpha value as zero, since there is no view content to be shown. setContentVisibility(false); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 24661d69a78e..852868616afd 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -86,6 +86,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.text.TextUtils; +import android.util.EventLog; import android.util.IntArray; import android.util.Pair; import android.util.Slog; @@ -2191,10 +2192,16 @@ public final class DisplayManagerService extends SystemService { } } - if (callingUid == Process.SYSTEM_UID - || checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { - flags |= VIRTUAL_DISPLAY_FLAG_TRUSTED; - } else { + if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) { + if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { + EventLog.writeEvent(0x534e4554, "162627132", callingUid, + "Attempt to create a trusted display without holding permission!"); + throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " + + "create a trusted virtual display."); + } + } + + if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) { flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; } -- GitLab From 1e8e7a94872de70aa6e661fe960854e01447b1c0 Mon Sep 17 00:00:00 2001 From: Jeff Chang Date: Fri, 7 Aug 2020 16:08:15 +0800 Subject: [PATCH 336/536] [RESTRICT AUTOMERGE] Update the visibility of activities on sleeping display Activity with showWhenLocked flag is visible when screen is off and leads to activity restart called. This CL update the visibility condition for showWhenLocked and dismisskeyguard activities and refer the keyguard visibility to ensure the function works as expected. Bug: 161036653 Test: atest ActivityRecordTests atest CtsWindowManagerDeviceTestCases:KeyguardTests atest CtsWindowManagerDeviceTestCases:KeyguardLockedTests Change-Id: I9d56e40de964e9d11193fec7008f8d880028ac50 (cherry picked from commit 73d6c7926d2cdc39de617f7213fc85f303501f37) (cherry picked from commit 31fc73a70719ed9a07a9a865c71b602e2fd0c53e) --- .../com/android/server/wm/ActivityRecord.java | 15 ++++------ .../server/wm/ActivityRecordTests.java | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 3e9377ed0664..41e48b8ec9db 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -4578,15 +4578,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } - // Check if the activity is on a sleeping display, and if it can turn it ON. - if (getDisplay().isSleeping()) { - final boolean canTurnScreenOn = !mSetToSleep || canTurnScreenOn() - || canShowWhenLocked() || containsDismissKeyguardWindow(); - if (!canTurnScreenOn) { - return false; - } - } - // Now check whether it's really visible depending on Keyguard state, and update // {@link ActivityStack} internal states. // Inform the method if this activity is the top activity of this stack, but exclude the @@ -4597,6 +4588,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this, visibleIgnoringKeyguard, isTop && isTopNotPinnedStack); + // Check if the activity is on a sleeping display, and if it can turn it ON. + // TODO(b/163993448): Do not make activity visible before display awake. + if (visibleIgnoringDisplayStatus && getDisplay().isSleeping()) { + return !mSetToSleep || canTurnScreenOn(); + } + return visibleIgnoringDisplayStatus; } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index c7b45efb2de1..6ab0697206e3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -1099,6 +1099,34 @@ public class ActivityRecordTests extends ActivityTestsBase { verify(topActivity).destroyIfPossible(anyString()); } + /** + * Verify the visibility of a show-when-locked and dismiss keyguard activity on sleeping + * display. + */ + @Test + public void testDisplaySleeping_activityInvisible() { + final KeyguardController keyguardController = + mActivity.mStackSupervisor.getKeyguardController(); + doReturn(true).when(keyguardController).isKeyguardLocked(); + final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build(); + topActivity.mVisibleRequested = true; + topActivity.nowVisible = true; + topActivity.setState(RESUMED, "test" /*reason*/); + doReturn(true).when(topActivity).containsDismissKeyguardWindow(); + doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible( + any() /* starting */, anyInt() /* configChanges */, + anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */); + topActivity.setShowWhenLocked(true); + + // Verify the top activity is occluded keyguard. + assertEquals(topActivity, mStack.topRunningActivity()); + assertTrue(mStack.topActivityOccludesKeyguard()); + + final DisplayContent display = mActivity.mDisplayContent; + doReturn(true).when(display).isSleeping(); + assertFalse(topActivity.shouldBeVisible()); + } + /** * Verify that complete finish request for a show-when-locked activity must ensure the * keyguard occluded state being updated. -- GitLab From 39c94c04934645be0be46317396a89e9cb49cfea Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Fri, 28 Aug 2020 16:58:36 +0900 Subject: [PATCH 337/536] statsd: mark libstats_jni as jni_libs This helps the build system to convey the information to linkerconfig so that jni_libs are available via libnativeloader. Bug: 150767721 Test: presubmit Merged-In: Ie32e88355828c8f696cce9d128eebb6da70026f1 Change-Id: Ie32e88355828c8f696cce9d128eebb6da70026f1 (cherry picked from commit 95642bbc3f64dc69499313ae4ed49d1d1026b97d) --- apex/statsd/Android.bp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apex/statsd/Android.bp b/apex/statsd/Android.bp index e75fa88c54fe..ede8852c5905 100644 --- a/apex/statsd/Android.bp +++ b/apex/statsd/Android.bp @@ -19,8 +19,10 @@ apex { } apex_defaults { - native_shared_libs: [ + jni_libs: [ "libstats_jni", + ], + native_shared_libs: [ "libstatspull", "libstatssocket", ], -- GitLab From bc86158b25f308ce346385d06a91000dcccb8974 Mon Sep 17 00:00:00 2001 From: Song Pan Date: Wed, 10 Jun 2020 21:46:53 +0100 Subject: [PATCH 338/536] Expose some level of logging to aid debugging. Bug: 147095027 Test: N/A Change-Id: Ic8436c7c5f27722dde3a375fa6fcf11822e9ff48 --- .../AppIntegrityManagerServiceImpl.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java index 817902d9d566..b61c6a7ca569 100644 --- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java +++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java @@ -205,8 +205,13 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { } if (DEBUG_INTEGRITY_COMPONENT) { - Slog.i(TAG, String.format("Successfully pushed rule set: %s", version)); + Slog.i( + TAG, + String.format( + "Successfully pushed rule set to version '%s' from '%s'", + version, ruleProvider)); } + FrameworkStatsLog.write( FrameworkStatsLog.INTEGRITY_RULES_PUSHED, success, @@ -324,13 +329,12 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { + getAllowedInstallers(packageInfo)); } IntegrityCheckResult result = mEvaluationEngine.evaluate(appInstallMetadata); - if (DEBUG_INTEGRITY_COMPONENT) { + if (!result.getMatchedRules().isEmpty() || DEBUG_INTEGRITY_COMPONENT) { Slog.i( TAG, - "Integrity check result: " - + result.getEffect() - + " due to " - + result.getMatchedRules()); + String.format( + "Integrity check of %s result: %s due to %s", + packageName, result.getEffect(), result.getMatchedRules())); } FrameworkStatsLog.write( @@ -673,8 +677,10 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { // Obtain the system apps that are whitelisted in config_integrityRuleProviderPackages. List allowedRuleProviders = getAllowedRuleProviderSystemApps(); if (DEBUG_INTEGRITY_COMPONENT) { - Slog.i(TAG, String.format( - "Rule provider system app list contains: %s", allowedRuleProviders)); + Slog.i( + TAG, + String.format( + "Rule provider system app list contains: %s", allowedRuleProviders)); } // Identify the package names in the caller list. @@ -730,9 +736,9 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { private boolean integrityCheckIncludesRuleProvider() { return Settings.Global.getInt( - mContext.getContentResolver(), - Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER, - 0) + mContext.getContentResolver(), + Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER, + 0) == 1; } -- GitLab From 69eb7b7435a760f5f9800f5d0e45df64c7e27b3e Mon Sep 17 00:00:00 2001 From: Nadav Bar Date: Thu, 6 Aug 2020 12:25:19 +0300 Subject: [PATCH 339/536] Fix SystemCaptionsManagerService to re-bind after a force stop This change also fixes a bug in AbstractMasterSystemService where following a "force stop", the per-user service was not updated if PACKAGE_RESTART_POLICY_REFRESH_EAGER was specified. These behavior resulted with getServiceComponentName returning null and the service not being restarted. Bug: 160735520 Bug: 160693548 Bug: 160644088 Change-Id: I2f66273bd90e9bb220f799d8ab3b024637b33c24 Merged-In: I2f66273bd90e9bb220f799d8ab3b024637b33c24 Test: Manually (cherry picked from commit 762e0f9a2e9945a8b8cf1c3c93e3b70af8201908) --- .../com/android/server/infra/AbstractMasterSystemService.java | 2 +- .../server/systemcaptions/SystemCaptionsManagerService.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java index 2672f848f192..cf03c607a368 100644 --- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java +++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java @@ -948,7 +948,7 @@ public abstract class AbstractMasterSystemService Date: Mon, 24 Aug 2020 17:04:19 -0700 Subject: [PATCH 340/536] Cached list of pre-created users on UserManagerService. PermissionManagerService calls UserManagerService to get the list of user ids multiple times on boot (O(1000) times), so these calls must be cached. PMS used to call UMS.getUserIds(), which didn't include the list of pre-created users, so it was recently changed to call UMS.getUsers() and calculate the ids, but such non-cached call increase the boot time on some devices in almost 50ms. This change fixes the regression by caching the user ids of the pre-created users as well. Test: manual verification Bug: 167265128 Bug: 165940683 Change-Id: Ib4068cce7d4cea56e0937099508469e49e3412e2 Merged-In: Ib4068cce7d4cea56e0937099508469e49e3412e2 (cherry picked from commit d4407fd5304cd71f6a42d04f59c59d943efc427a) --- .../android/server/pm/UserManagerService.java | 70 ++++++++++++++++--- .../permission/PermissionManagerService.java | 14 +--- 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 27924a68ff48..01a3d14e05df 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -114,7 +114,6 @@ import com.android.server.SystemService; import com.android.server.am.UserState; import com.android.server.storage.DeviceStorageMonitorInternal; import com.android.server.utils.TimingsTraceAndSlog; -import com.android.server.wm.ActivityTaskManagerInternal; import libcore.io.IoUtils; @@ -134,6 +133,7 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -406,6 +406,10 @@ public class UserManagerService extends IUserManager.Stub { @GuardedBy("mUsersLock") private int[] mUserIds; + + @GuardedBy("mUsersLock") + private int[] mUserIdsIncludingPreCreated; + @GuardedBy("mPackagesLock") private int mNextSerialNumber; private int mUserVersion = 0; @@ -2480,16 +2484,35 @@ public class UserManagerService extends IUserManager.Stub { } /** - * Returns an array of user ids. This array is cached here for quick access, so do not modify or - * cache it elsewhere. + * Returns an array of user ids. + * + *

    This array is cached here for quick access, so do not modify or cache it elsewhere. + * * @return the array of user ids. */ - public int[] getUserIds() { + public @NonNull int[] getUserIds() { synchronized (mUsersLock) { return mUserIds; } } + /** + * Returns an array of user ids, including pre-created users. + * + *

    This method should only used for the specific cases that need to handle pre-created users; + * most callers should call {@link #getUserIds()} instead. + * + *

    This array is cached here for quick access, so do not modify or + * cache it elsewhere. + * + * @return the array of user ids. + */ + public @NonNull int[] getUserIdsIncludingPreCreated() { + synchronized (mUsersLock) { + return mUserIdsIncludingPreCreated; + } + } + @GuardedBy({"mRestrictionsLock", "mPackagesLock"}) private void readUserListLP() { if (!mUserListFile.exists()) { @@ -4327,23 +4350,43 @@ public class UserManagerService extends IUserManager.Stub { */ private void updateUserIds() { int num = 0; + int numIncludingPreCreated = 0; synchronized (mUsersLock) { final int userSize = mUsers.size(); for (int i = 0; i < userSize; i++) { - UserInfo userInfo = mUsers.valueAt(i).info; - if (!userInfo.partial && !userInfo.preCreated) { - num++; + final UserInfo userInfo = mUsers.valueAt(i).info; + if (!userInfo.partial) { + numIncludingPreCreated++; + if (!userInfo.preCreated) { + num++; + } } } + if (DBG) { + Slog.d(LOG_TAG, "updateUserIds(): numberUsers= " + num + + " includingPreCreated=" + numIncludingPreCreated); + } final int[] newUsers = new int[num]; + final int[] newUsersIncludingPreCreated = new int[numIncludingPreCreated]; + int n = 0; + int nIncludingPreCreated = 0; for (int i = 0; i < userSize; i++) { - UserInfo userInfo = mUsers.valueAt(i).info; - if (!userInfo.partial && !userInfo.preCreated) { - newUsers[n++] = mUsers.keyAt(i); + final UserInfo userInfo = mUsers.valueAt(i).info; + if (!userInfo.partial) { + final int userId = mUsers.keyAt(i); + newUsersIncludingPreCreated[nIncludingPreCreated++] = userId; + if (!userInfo.preCreated) { + newUsers[n++] = userId; + } } } mUserIds = newUsers; + mUserIdsIncludingPreCreated = newUsersIncludingPreCreated; + if (DBG) { + Slog.d(LOG_TAG, "updateUserIds(): userIds= " + Arrays.toString(mUserIds) + + " includingPreCreated=" + Arrays.toString(mUserIdsIncludingPreCreated)); + } } } @@ -4791,6 +4834,13 @@ public class UserManagerService extends IUserManager.Stub { synchronized (mUserStates) { pw.println(" Started users state: " + mUserStates); } + synchronized (mUsersLock) { + pw.print(" Cached user IDs: "); + pw.println(Arrays.toString(mUserIds)); + pw.print(" Cached user IDs (including pre-created): "); + pw.println(Arrays.toString(mUserIdsIncludingPreCreated)); + } + } // synchronized (mPackagesLock) // Dump some capabilities diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index a4e8b1c01620..2533aa7c4302 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -83,7 +83,6 @@ import android.content.pm.PackageParser; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; -import android.content.pm.UserInfo; import android.content.pm.parsing.component.ParsedPermission; import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.permission.SplitPermissionInfoParcelable; @@ -121,7 +120,6 @@ import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; -import android.util.TimingsTraceLog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -3078,17 +3076,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { * @return user ids for created users and pre-created users */ private int[] getAllUserIds() { - final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER); - t.traceBegin("getAllUserIds"); - List users = UserManagerService.getInstance().getUsers( - /*excludePartial=*/ true, /*excludeDying=*/ true, /*excludePreCreated=*/ false); - int size = users.size(); - final int[] userIds = new int[size]; - for (int i = 0; i < size; i++) { - userIds[i] = users.get(i).id; - } - t.traceEnd(); - return userIds; + return UserManagerService.getInstance().getUserIdsIncludingPreCreated(); } /** -- GitLab From d1ba7f44e3df7693e25ca6ae5b9bf9b4c48fe4e9 Mon Sep 17 00:00:00 2001 From: Jay Aliomer Date: Mon, 20 Jul 2020 23:10:47 -0400 Subject: [PATCH 341/536] Unlock keyguard for screen recording action Fixes: 159134871 Test: RecordingServiceTest Merged-In: Iad0eccf79655a8980221121e915b87de150b66b9 Change-Id: Iad0eccf79655a8980221121e915b87de150b66b9 (cherry picked from commit 2d0d2d18475e0912372130462ba18935a0b7bae5) --- .../screenrecord/RecordingService.java | 21 +++++++++++-------- .../screenrecord/RecordingServiceTest.java | 10 ++++++++- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java index acc7f81eb722..8ec3db59117d 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java @@ -41,6 +41,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.LongRunning; import com.android.systemui.settings.CurrentUserContextTracker; +import com.android.systemui.statusbar.phone.KeyguardDismissUtil; import java.io.IOException; import java.util.concurrent.Executor; @@ -70,7 +71,7 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis private static final String ACTION_SHARE = "com.android.systemui.screenrecord.SHARE"; private final RecordingController mController; - + private final KeyguardDismissUtil mKeyguardDismissUtil; private ScreenRecordingAudioSource mAudioSource; private boolean mShowTaps; private boolean mOriginalShowTaps; @@ -83,12 +84,13 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis @Inject public RecordingService(RecordingController controller, @LongRunning Executor executor, UiEventLogger uiEventLogger, NotificationManager notificationManager, - CurrentUserContextTracker userContextTracker) { + CurrentUserContextTracker userContextTracker, KeyguardDismissUtil keyguardDismissUtil) { mController = controller; mLongExecutor = executor; mUiEventLogger = uiEventLogger; mNotificationManager = notificationManager; mUserContextTracker = userContextTracker; + mKeyguardDismissUtil = keyguardDismissUtil; } /** @@ -168,16 +170,17 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis Intent shareIntent = new Intent(Intent.ACTION_SEND) .setType("video/mp4") .putExtra(Intent.EXTRA_STREAM, shareUri); - String shareLabel = getResources().getString(R.string.screenrecord_share_label); + mKeyguardDismissUtil.executeWhenUnlocked(() -> { + String shareLabel = getResources().getString(R.string.screenrecord_share_label); + startActivity(Intent.createChooser(shareIntent, shareLabel) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + // Remove notification + mNotificationManager.cancelAsUser(null, NOTIFICATION_VIEW_ID, currentUser); + return false; + }, false); // Close quick shade sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); - - // Remove notification - mNotificationManager.cancelAsUser(null, NOTIFICATION_VIEW_ID, currentUser); - - startActivity(Intent.createChooser(shareIntent, shareLabel) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); break; } return Service.START_STICKY; diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java index e98b6b69ee76..4c9e141c45cc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java @@ -32,7 +32,9 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.settings.CurrentUserContextTracker; +import com.android.systemui.statusbar.phone.KeyguardDismissUtil; import org.junit.Before; import org.junit.Test; @@ -61,6 +63,12 @@ public class RecordingServiceTest extends SysuiTestCase { private Executor mExecutor; @Mock private CurrentUserContextTracker mUserContextTracker; + private KeyguardDismissUtil mKeyguardDismissUtil = new KeyguardDismissUtil() { + public void executeWhenUnlocked(ActivityStarter.OnDismissAction action, + boolean requiresShadeOpen) { + action.onDismiss(); + } + }; private RecordingService mRecordingService; @@ -68,7 +76,7 @@ public class RecordingServiceTest extends SysuiTestCase { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mRecordingService = Mockito.spy(new RecordingService(mController, mExecutor, mUiEventLogger, - mNotificationManager, mUserContextTracker)); + mNotificationManager, mUserContextTracker, mKeyguardDismissUtil)); // Return actual context info doReturn(mContext).when(mRecordingService).getApplicationContext(); -- GitLab From 6d90fa3d504b8bfc9e226f1431a1f0c2c18adc48 Mon Sep 17 00:00:00 2001 From: Lee Shombert Date: Tue, 1 Sep 2020 16:57:59 +0000 Subject: [PATCH 342/536] RESTRICT AUTOMERGE Revert "Construct AppsFilter cache on background thread" Bug: 167396858 This reverts commit b0f1feb01f40d77992fa83ae43f503cf49a82f07. Reason for revert: Droidcop: culprit for Bug 167396858. Verified via forrest L38300000681795599 and through discussion with the original submitter. https://android-build.googleplex.com/builds/forrest/run/L38300000681795599 Change-Id: Ia37daaa68aa6ce24716a9f2150a88f000503a002 --- .../com/android/server/pm/AppsFilter.java | 179 +++++++----------- .../server/pm/PackageManagerService.java | 4 +- .../com/android/server/pm/AppsFilterTest.java | 91 +++------ 3 files changed, 100 insertions(+), 174 deletions(-) diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java index 22d6c9909edf..c3c2e5e65103 100644 --- a/services/core/java/com/android/server/pm/AppsFilter.java +++ b/services/core/java/com/android/server/pm/AppsFilter.java @@ -35,9 +35,6 @@ import android.content.pm.parsing.component.ParsedInstrumentation; import android.content.pm.parsing.component.ParsedIntentInfo; import android.content.pm.parsing.component.ParsedMainComponent; import android.content.pm.parsing.component.ParsedProvider; -import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.HandlerThread; import android.os.Process; import android.os.Trace; import android.os.UserHandle; @@ -51,7 +48,6 @@ import android.util.SparseBooleanArray; import android.util.SparseSetArray; import com.android.internal.R; -import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.server.FgThread; @@ -65,7 +61,6 @@ import java.util.List; import java.util.Objects; import java.util.Set; import java.util.StringTokenizer; -import java.util.concurrent.Executor; /** * The entity responsible for filtering visibility between apps based on declarations in their @@ -100,12 +95,6 @@ public class AppsFilter { */ private final SparseSetArray mQueriesViaComponent = new SparseSetArray<>(); - /** - * Executor for running reasonably short background tasks such as building the initial - * visibility cache. - */ - private final Executor mBackgroundExecutor; - /** * Pending full recompute of mQueriesViaComponent. Occurs when a package adds a new set of * protected broadcast. This in turn invalidates all prior additions and require a very @@ -136,8 +125,6 @@ public class AppsFilter { private PackageParser.SigningDetails mSystemSigningDetails; private Set mProtectedBroadcasts = new ArraySet<>(); - private final Object mCacheLock = new Object(); - /** * This structure maps uid -> uid and indicates whether access from the first should be * filtered to the second. It's essentially a cache of the @@ -145,7 +132,6 @@ public class AppsFilter { * NOTE: It can only be relied upon after the system is ready to avoid unnecessary update on * initial scam and is null until {@link #onSystemReady()} is called. */ - @GuardedBy("mCacheLock") private volatile SparseArray mShouldFilterCache; @VisibleForTesting(visibility = PRIVATE) @@ -153,15 +139,13 @@ public class AppsFilter { FeatureConfig featureConfig, String[] forceQueryableWhitelist, boolean systemAppsQueryable, - @Nullable OverlayReferenceMapper.Provider overlayProvider, - Executor backgroundExecutor) { + @Nullable OverlayReferenceMapper.Provider overlayProvider) { mFeatureConfig = featureConfig; mForceQueryableByDevicePackageNames = forceQueryableWhitelist; mSystemAppsQueryable = systemAppsQueryable; mOverlayReferenceMapper = new OverlayReferenceMapper(true /*deferRebuild*/, overlayProvider); mStateProvider = stateProvider; - mBackgroundExecutor = backgroundExecutor; } /** @@ -353,13 +337,8 @@ public class AppsFilter { injector.getUserManagerInternal().getUserInfos()); } }; - HandlerThread appsFilterThread = new HandlerThread("appsFilter"); - appsFilterThread.start(); - Handler appsFilterHandler = new Handler(appsFilterThread.getLooper()); - Executor executor = new HandlerExecutor(appsFilterHandler); - AppsFilter appsFilter = new AppsFilter(stateProvider, featureConfig, - forcedQueryablePackageNames, forceSystemAppsQueryable, null, executor); + forcedQueryablePackageNames, forceSystemAppsQueryable, null); featureConfig.setAppsFilter(appsFilter); return appsFilter; } @@ -491,26 +470,29 @@ public class AppsFilter { if (mImplicitlyQueryable.add(recipientUid, visibleUid) && DEBUG_LOGGING) { Slog.i(TAG, "implicit access granted: " + recipientUid + " -> " + visibleUid); } - synchronized (mCacheLock) { - if (mShouldFilterCache != null) { - // update the cache in a one-off manner since we've got all the information we - // need. - SparseBooleanArray visibleUids = mShouldFilterCache.get(recipientUid); - if (visibleUids == null) { - visibleUids = new SparseBooleanArray(); - mShouldFilterCache.put(recipientUid, visibleUids); - } - visibleUids.put(visibleUid, false); + if (mShouldFilterCache != null) { + // update the cache in a one-off manner since we've got all the information we need. + SparseBooleanArray visibleUids = mShouldFilterCache.get(recipientUid); + if (visibleUids == null) { + visibleUids = new SparseBooleanArray(); + mShouldFilterCache.put(recipientUid, visibleUids); } + visibleUids.put(visibleUid, false); } } } public void onSystemReady() { - mOverlayReferenceMapper.rebuildIfDeferred(); + mStateProvider.runWithState(new StateProvider.CurrentStateCallback() { + @Override + public void currentState(ArrayMap settings, + UserInfo[] users) { + mShouldFilterCache = new SparseArray<>(users.length * settings.size()); + } + }); mFeatureConfig.onSystemReady(); - - updateEntireShouldFilterCacheAsync(); + mOverlayReferenceMapper.rebuildIfDeferred(); + updateEntireShouldFilterCache(); } /** @@ -528,12 +510,10 @@ public class AppsFilter { } mStateProvider.runWithState((settings, users) -> { addPackageInternal(newPkgSetting, settings); - synchronized (mCacheLock) { - if (mShouldFilterCache != null) { - updateShouldFilterCacheForPackage(mShouldFilterCache, null, newPkgSetting, - settings, users, settings.size()); - } // else, rebuild entire cache when system is ready - } + if (mShouldFilterCache != null) { + updateShouldFilterCacheForPackage( + null, newPkgSetting, settings, users, settings.size()); + } // else, rebuild entire cache when system is ready }); } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); @@ -627,7 +607,6 @@ public class AppsFilter { mFeatureConfig.updatePackageState(newPkgSetting, false /*removed*/); } - @GuardedBy("mCacheLock") private void removeAppIdFromVisibilityCache(int appId) { if (mShouldFilterCache == null) { return; @@ -646,47 +625,33 @@ public class AppsFilter { } } - private void updateEntireShouldFilterCacheAsync() { - mBackgroundExecutor.execute(this::updateEntireShouldFilterCache); - } - private void updateEntireShouldFilterCache() { mStateProvider.runWithState((settings, users) -> { - SparseArray cache = - new SparseArray<>(users.length * settings.size()); + mShouldFilterCache.clear(); for (int i = settings.size() - 1; i >= 0; i--) { - updateShouldFilterCacheForPackage(cache, + updateShouldFilterCacheForPackage( null /*skipPackage*/, settings.valueAt(i), settings, users, i); } - synchronized (mCacheLock) { - mShouldFilterCache = cache; - } }); } public void onUsersChanged() { - synchronized (mCacheLock) { - if (mShouldFilterCache != null) { - updateEntireShouldFilterCache(); - } + if (mShouldFilterCache != null) { + updateEntireShouldFilterCache(); } } private void updateShouldFilterCacheForPackage(String packageName) { - synchronized (mCacheLock) { - if (mShouldFilterCache != null) { - mStateProvider.runWithState((settings, users) -> { - updateShouldFilterCacheForPackage(mShouldFilterCache, null /* skipPackage */, - settings.get(packageName), settings, users, - settings.size() /*maxIndex*/); - }); - } - } + mStateProvider.runWithState((settings, users) -> { + updateShouldFilterCacheForPackage(null /* skipPackage */, settings.get(packageName), + settings, users, settings.size() /*maxIndex*/); + }); + } - private void updateShouldFilterCacheForPackage(SparseArray cache, - @Nullable String skipPackageName, PackageSetting subjectSetting, ArrayMap allSettings, UserInfo[] allUsers, int maxIndex) { + private void updateShouldFilterCacheForPackage(@Nullable String skipPackageName, + PackageSetting subjectSetting, ArrayMap allSettings, + UserInfo[] allUsers, int maxIndex) { for (int i = Math.min(maxIndex, allSettings.size() - 1); i >= 0; i--) { PackageSetting otherSetting = allSettings.valueAt(i); if (subjectSetting.appId == otherSetting.appId) { @@ -703,17 +668,17 @@ public class AppsFilter { for (int ou = 0; ou < userCount; ou++) { int otherUser = allUsers[ou].id; int subjectUid = UserHandle.getUid(subjectUser, subjectSetting.appId); - if (!cache.contains(subjectUid)) { - cache.put(subjectUid, new SparseBooleanArray(appxUidCount)); + if (!mShouldFilterCache.contains(subjectUid)) { + mShouldFilterCache.put(subjectUid, new SparseBooleanArray(appxUidCount)); } int otherUid = UserHandle.getUid(otherUser, otherSetting.appId); - if (!cache.contains(otherUid)) { - cache.put(otherUid, new SparseBooleanArray(appxUidCount)); + if (!mShouldFilterCache.contains(otherUid)) { + mShouldFilterCache.put(otherUid, new SparseBooleanArray(appxUidCount)); } - cache.get(subjectUid).put(otherUid, + mShouldFilterCache.get(subjectUid).put(otherUid, shouldFilterApplicationInternal( subjectUid, subjectSetting, otherSetting, otherUser)); - cache.get(otherUid).put(subjectUid, + mShouldFilterCache.get(otherUid).put(subjectUid, shouldFilterApplicationInternal( otherUid, otherSetting, subjectSetting, subjectUser)); } @@ -747,8 +712,7 @@ public class AppsFilter { * This method recomputes all component / intent-based visibility and is intended to match the * relevant logic of {@link #addPackageInternal(PackageSetting, ArrayMap)} */ - private void recomputeComponentVisibility( - ArrayMap existingSettings) { + private void recomputeComponentVisibility(ArrayMap existingSettings) { mQueriesViaComponent.clear(); for (int i = existingSettings.size() - 1; i >= 0; i--) { PackageSetting setting = existingSettings.valueAt(i); @@ -890,17 +854,15 @@ public class AppsFilter { } } - synchronized (mCacheLock) { - removeAppIdFromVisibilityCache(setting.appId); - if (mShouldFilterCache != null && setting.sharedUser != null) { - for (int i = setting.sharedUser.packages.size() - 1; i >= 0; i--) { - PackageSetting siblingSetting = setting.sharedUser.packages.valueAt(i); - if (siblingSetting == setting) { - continue; - } - updateShouldFilterCacheForPackage(mShouldFilterCache, setting.name, - siblingSetting, settings, users, settings.size()); + removeAppIdFromVisibilityCache(setting.appId); + if (mShouldFilterCache != null && setting.sharedUser != null) { + for (int i = setting.sharedUser.packages.size() - 1; i >= 0; i--) { + PackageSetting siblingSetting = setting.sharedUser.packages.valueAt(i); + if (siblingSetting == setting) { + continue; } + updateShouldFilterCacheForPackage( + setting.name, siblingSetting, settings, users, settings.size()); } } }); @@ -926,29 +888,26 @@ public class AppsFilter { || callingAppId == targetPkgSetting.appId) { return false; } - synchronized (mCacheLock) { - if (mShouldFilterCache != null) { // use cache - SparseBooleanArray shouldFilterTargets = mShouldFilterCache.get(callingUid); - final int targetUid = UserHandle.getUid(userId, targetPkgSetting.appId); - if (shouldFilterTargets == null) { - Slog.wtf(TAG, "Encountered calling uid with no cached rules: " - + callingUid); - return true; - } - int indexOfTargetUid = shouldFilterTargets.indexOfKey(targetUid); - if (indexOfTargetUid < 0) { - Slog.w(TAG, "Encountered calling -> target with no cached rules: " - + callingUid + " -> " + targetUid); - return true; - } - if (!shouldFilterTargets.valueAt(indexOfTargetUid)) { - return false; - } - } else { - if (!shouldFilterApplicationInternal( - callingUid, callingSetting, targetPkgSetting, userId)) { - return false; - } + if (mShouldFilterCache != null) { // use cache + SparseBooleanArray shouldFilterTargets = mShouldFilterCache.get(callingUid); + final int targetUid = UserHandle.getUid(userId, targetPkgSetting.appId); + if (shouldFilterTargets == null) { + Slog.wtf(TAG, "Encountered calling uid with no cached rules: " + callingUid); + return true; + } + int indexOfTargetUid = shouldFilterTargets.indexOfKey(targetUid); + if (indexOfTargetUid < 0) { + Slog.w(TAG, "Encountered calling -> target with no cached rules: " + + callingUid + " -> " + targetUid); + return true; + } + if (!shouldFilterTargets.valueAt(indexOfTargetUid)) { + return false; + } + } else { + if (!shouldFilterApplicationInternal( + callingUid, callingSetting, targetPkgSetting, userId)) { + return false; } } if (DEBUG_LOGGING || mFeatureConfig.isLoggingEnabled(callingAppId)) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 30acc3ed3673..3f925d1d9d6a 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -21446,6 +21446,8 @@ public class PackageManagerService extends IPackageManager.Stub .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL); co.onChange(true); + mAppsFilter.onSystemReady(); + // Disable any carrier apps. We do this very early in boot to prevent the apps from being // disabled after already being started. CarrierAppUtils.disableCarrierAppsUntilPrivileged( @@ -21594,8 +21596,6 @@ public class PackageManagerService extends IPackageManager.Stub mInstallerService.restoreAndApplyStagedSessionIfNeeded(); mExistingPackages = null; - - mAppsFilter.onSystemReady(); } public void waitForAppDataPrepared() { diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java index 480a02de064a..26230949cda6 100644 --- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java @@ -72,7 +72,6 @@ import java.util.Map; import java.util.Set; import java.util.function.IntFunction; import java.util.stream.Collectors; -import java.util.concurrent.Executor; @Presubmit @RunWith(JUnit4.class) @@ -92,8 +91,6 @@ public class AppsFilterTest { AppsFilter.FeatureConfig mFeatureConfigMock; @Mock AppsFilter.StateProvider mStateProvider; - @Mock - Executor mMockExecutor; private ArrayMap mExisting = new ArrayMap<>(); @@ -190,15 +187,10 @@ public class AppsFilterTest { doAnswer(invocation -> { ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0)) .currentState(mExisting, USER_INFO_LIST); - return new Object(); + return null; }).when(mStateProvider) .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class)); - doAnswer(invocation -> { - ((Runnable) invocation.getArgument(0)).run(); - return new Object(); - }).when(mMockExecutor).execute(any(Runnable.class)); - when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true); when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))).thenAnswer( (Answer) invocation -> @@ -209,8 +201,7 @@ public class AppsFilterTest { @Test public void testSystemReadyPropogates() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); appsFilter.onSystemReady(); verify(mFeatureConfigMock).onSystemReady(); } @@ -218,8 +209,7 @@ public class AppsFilterTest { @Test public void testQueriesAction_FilterMatches() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -235,8 +225,7 @@ public class AppsFilterTest { @Test public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); final Signature frameworkSignature = Mockito.mock(Signature.class); final PackageParser.SigningDetails frameworkSigningDetails = new PackageParser.SigningDetails(new Signature[]{frameworkSignature}, 1); @@ -274,8 +263,7 @@ public class AppsFilterTest { @Test public void testQueriesProvider_FilterMatches() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -292,8 +280,7 @@ public class AppsFilterTest { @Test public void testQueriesDifferentProvider_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -310,8 +297,7 @@ public class AppsFilterTest { @Test public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -329,8 +315,7 @@ public class AppsFilterTest { @Test public void testQueriesAction_NoMatchingAction_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -346,8 +331,7 @@ public class AppsFilterTest { @Test public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -367,8 +351,7 @@ public class AppsFilterTest { @Test public void testNoQueries_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -384,8 +367,7 @@ public class AppsFilterTest { @Test public void testForceQueryable_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -402,7 +384,7 @@ public class AppsFilterTest { public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception { final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"}, - false, null, mMockExecutor); + false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -420,8 +402,7 @@ public class AppsFilterTest { @Test public void testSystemSignedTarget_DoesntFilter() throws CertificateException { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); appsFilter.onSystemReady(); final Signature frameworkSignature = Mockito.mock(Signature.class); @@ -450,7 +431,7 @@ public class AppsFilterTest { public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception { final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"}, - false, null, mMockExecutor); + false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -468,7 +449,7 @@ public class AppsFilterTest { public void testSystemQueryable_DoesntFilter() throws Exception { final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, - true /* system force queryable */, null, mMockExecutor); + true /* system force queryable */, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -485,8 +466,7 @@ public class AppsFilterTest { @Test public void testQueriesPackage_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -504,8 +484,7 @@ public class AppsFilterTest { when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))) .thenReturn(false); final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -521,8 +500,7 @@ public class AppsFilterTest { @Test public void testSystemUid_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -537,8 +515,7 @@ public class AppsFilterTest { @Test public void testSystemUidSecondaryUser_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -554,8 +531,7 @@ public class AppsFilterTest { @Test public void testNonSystemUid_NoCallingSetting_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -569,8 +545,7 @@ public class AppsFilterTest { @Test public void testNoTargetPackage_filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -628,8 +603,7 @@ public class AppsFilterTest { } return Collections.emptyMap(); } - }, - mMockExecutor); + }); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -701,8 +675,7 @@ public class AppsFilterTest { } return Collections.emptyMap(); } - }, - mMockExecutor); + }); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -727,8 +700,7 @@ public class AppsFilterTest { @Test public void testInitiatingApp_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -744,8 +716,7 @@ public class AppsFilterTest { @Test public void testUninstalledInitiatingApp_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -761,8 +732,7 @@ public class AppsFilterTest { @Test public void testOriginatingApp_Filters() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -778,8 +748,7 @@ public class AppsFilterTest { @Test public void testInstallingApp_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -795,8 +764,7 @@ public class AppsFilterTest { @Test public void testInstrumentation_DoesntFilter() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -818,8 +786,7 @@ public class AppsFilterTest { @Test public void testWhoCanSee() throws Exception { final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, - mMockExecutor); + new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); -- GitLab From e80e94182cbde56dc0ff796edc2e248d85babeed Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Wed, 2 Sep 2020 00:02:17 +0800 Subject: [PATCH 343/536] Compare with oldSoftInputMode after restoring softInputMode ... of mWindowAttributes. Apps might update LayoutParams with softInputMode unspecified on applying insets, and this can cause infinite loop in the previous logic, because we would auto-compute softInputMode for the unspecified one, which makes app's softInputMode never be the same as the one in ViewRootImpl.mWindowAttributes. Fix: 163009478 Test: Print stack trace before calling requestFitSystemWindows() and follow the steps in the bug. Test: Open Messages, go to attachments, reopen IME Change-Id: I2341121b69209688c2f6fb033f51611b21422a04 --- core/java/android/view/ViewRootImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index bcf3b49c6644..5c42408dab05 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1456,7 +1456,7 @@ public final class ViewRootImpl implements ViewParent, | (oldSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST); } - if ((changes & LayoutParams.SOFT_INPUT_MODE_CHANGED) != 0) { + if (mWindowAttributes.softInputMode != oldSoftInputMode) { requestFitSystemWindows(); } -- GitLab From ff129bbc632c4509ac825945fafc02b1a3bde053 Mon Sep 17 00:00:00 2001 From: josephjang Date: Tue, 18 Aug 2020 13:08:14 +0800 Subject: [PATCH 344/536] LockSettingsService: Move down onAuthTokenKnownForUser() onAuthTokenKnownForUser() will send secret to AuthSecret to install Citadel FW update password. In order to prevent sending different secret to Citadle in corner cases, leave onAuthTokenKnownForUser() behind Synthetic password has been setup complete. Bug: 150929955 Test: atest com.android.server.locksettings Change-Id: I80baea9671b050c1d83618076ff7ae2f26dde613 Merged-In: I80baea9671b050c1d83618076ff7ae2f26dde613 --- .../com/android/server/locksettings/LockSettingsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 90370ddd21dd..69b02ceb2411 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -2620,7 +2620,6 @@ public class LockSettingsService extends ILockSettings.Stub { Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId); final AuthenticationToken auth = mSpManager.newSyntheticPasswordAndSid( getGateKeeperService(), credentialHash, credential, userId); - onAuthTokenKnownForUser(userId, auth); if (auth == null) { Slog.wtf(TAG, "initializeSyntheticPasswordLocked returns null auth token"); return null; @@ -2643,6 +2642,7 @@ public class LockSettingsService extends ILockSettings.Stub { } fixateNewestUserKeyAuth(userId); setSyntheticPasswordHandleLocked(handle, userId); + onAuthTokenKnownForUser(userId, auth); return auth; } -- GitLab From 677078e8727380fcc48890ebe046a5f2cccc8eff Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Thu, 27 Aug 2020 21:49:06 +0800 Subject: [PATCH 345/536] Make display frame compatible The display frame is used to limit the windows boundary. The frame is the same as the parent frame in most cases if the window is not attched. However, if a window doesn't have any layout related window/sysui flags and the soft input mode is not ADJUST_RESIZE, the display frame doesn't need to be inset by IME (but the parent frame does). Fix: 163435784 Test: atest ViewRootImplTest DisplayPolicyLayoutTests Merged-In: Ia61933120027642d1f0e0a490546071ca2b6c853 Change-Id: Ia61933120027642d1f0e0a490546071ca2b6c853 --- core/java/android/view/ViewRootImpl.java | 29 ++++++++++--------- core/java/android/view/WindowManager.java | 6 ++++ .../src/android/view/ViewRootImplTest.java | 11 ++++++- .../com/android/server/wm/DisplayPolicy.java | 9 ++++++ .../server/wm/DisplayPolicyLayoutTests.java | 19 ++++++++++++ .../server/wm/DisplayPolicyTestsBase.java | 2 +- 6 files changed, 61 insertions(+), 15 deletions(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 5c42408dab05..4a56761bbce5 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -53,6 +53,9 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CO import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FIT_INSETS_CONTROLLED; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; @@ -1449,11 +1452,10 @@ public final class ViewRootImpl implements ViewParent, } // Don't lose the mode we last auto-computed. - if ((attrs.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) + if ((attrs.softInputMode & SOFT_INPUT_MASK_ADJUST) == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) { mWindowAttributes.softInputMode = (mWindowAttributes.softInputMode - & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) - | (oldSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST); + & ~SOFT_INPUT_MASK_ADJUST) | (oldSoftInputMode & SOFT_INPUT_MASK_ADJUST); } if (mWindowAttributes.softInputMode != oldSoftInputMode) { @@ -2073,6 +2075,7 @@ public final class ViewRootImpl implements ViewParent, final int sysUiVis = inOutParams.systemUiVisibility | inOutParams.subtreeSystemUiVisibility; final int flags = inOutParams.flags; final int type = inOutParams.type; + final int adjust = inOutParams.softInputMode & SOFT_INPUT_MASK_ADJUST; if ((inOutParams.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) == 0) { inOutParams.insetsFlags.appearance = 0; @@ -2098,12 +2101,13 @@ public final class ViewRootImpl implements ViewParent, } } + inOutParams.privateFlags &= ~PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME; + if ((inOutParams.privateFlags & PRIVATE_FLAG_FIT_INSETS_CONTROLLED) != 0) { return; } int types = inOutParams.getFitInsetsTypes(); - int sides = inOutParams.getFitInsetsSides(); boolean ignoreVis = inOutParams.isFitInsetsIgnoringVisibility(); if (((sysUiVis & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0 @@ -2118,10 +2122,13 @@ public final class ViewRootImpl implements ViewParent, if (type == TYPE_TOAST || type == TYPE_SYSTEM_ALERT) { ignoreVis = true; } else if ((types & Type.systemBars()) == Type.systemBars()) { - types |= Type.ime(); + if (adjust == SOFT_INPUT_ADJUST_RESIZE) { + types |= Type.ime(); + } else { + inOutParams.privateFlags |= PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME; + } } inOutParams.setFitInsetsTypes(types); - inOutParams.setFitInsetsSides(sides); inOutParams.setFitInsetsIgnoringVisibility(ignoreVis); // The fitting of insets are not really controlled by the clients, so we remove the flag. @@ -2491,8 +2498,7 @@ public final class ViewRootImpl implements ViewParent, if (mFirst || mAttachInfo.mViewVisibilityChanged) { mAttachInfo.mViewVisibilityChanged = false; - int resizeMode = mSoftInputMode & - WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; + int resizeMode = mSoftInputMode & SOFT_INPUT_MASK_ADJUST; // If we are in auto resize mode, then we need to determine // what mode to use now. if (resizeMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) { @@ -2505,11 +2511,8 @@ public final class ViewRootImpl implements ViewParent, if (resizeMode == 0) { resizeMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN; } - if ((lp.softInputMode & - WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) != resizeMode) { - lp.softInputMode = (lp.softInputMode & - ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) | - resizeMode; + if ((lp.softInputMode & SOFT_INPUT_MASK_ADJUST) != resizeMode) { + lp.softInputMode = (lp.softInputMode & ~SOFT_INPUT_MASK_ADJUST) | resizeMode; params = lp; } } diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 5c6269421a1f..2a711f6974f3 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -2032,6 +2032,12 @@ public interface WindowManager extends ViewManager { */ public static final int PRIVATE_FLAG_FIT_INSETS_CONTROLLED = 0x10000000; + /** + * Flag to indicate that the parent frame of a window should be inset by IME. + * @hide + */ + public static final int PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME = 0x40000000; + /** * An internal annotation for flags that can be specified to {@link #softInputMode}. * diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java index 5c16772488d0..4cf6715ba0ca 100644 --- a/core/tests/coretests/src/android/view/ViewRootImplTest.java +++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java @@ -24,6 +24,7 @@ import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE; import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; @@ -117,7 +118,15 @@ public class ViewRootImplTest { final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION); ViewRootImpl.adjustLayoutParamsForCompatibility(attrs); - // A window which fits system bars must fit IME, unless its type is toast or system alert. + assertEquals(Type.systemBars(), attrs.getFitInsetsTypes()); + } + + @Test + public void adjustLayoutParamsForCompatibility_fitSystemBarsAndIme() { + final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION); + attrs.softInputMode |= SOFT_INPUT_ADJUST_RESIZE; + ViewRootImpl.adjustLayoutParamsForCompatibility(attrs); + assertEquals(Type.systemBars() | Type.ime(), attrs.getFitInsetsTypes()); } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 5c5ec358d004..0926027d8e84 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -29,6 +29,7 @@ import static android.view.InsetsState.ITYPE_BOTTOM_DISPLAY_CUTOUT; import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES; import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT; import static android.view.InsetsState.ITYPE_CAPTION_BAR; +import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT; import static android.view.InsetsState.ITYPE_LEFT_GESTURES; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; @@ -71,6 +72,7 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; @@ -2191,6 +2193,13 @@ public class DisplayPolicy { df.set(left, top, dfu.right - right, dfu.bottom - bottom); if (attached == null) { pf.set(df); + if ((pfl & PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME) != 0) { + final InsetsSource source = mDisplayContent.getInsetsPolicy() + .getInsetsForDispatch(win).peekSource(ITYPE_IME); + if (source != null) { + pf.inset(source.calculateInsets(pf, false /* ignoreVisibility */)); + } + } vf.set(adjust != SOFT_INPUT_ADJUST_NOTHING ? displayFrames.mCurrent : displayFrames.mDock); } else { diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java index 2f3afbcb6d72..2d3b74b75826 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -36,6 +36,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; @@ -348,6 +349,24 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0); } + @Test + public void layoutWindowLw_insetParentFrameByIme() { + final InsetsState state = + mDisplayContent.getInsetsStateController().getRawInsetsState(); + state.getSource(InsetsState.ITYPE_IME).setVisible(true); + state.getSource(InsetsState.ITYPE_IME).setFrame( + 0, DISPLAY_HEIGHT - IME_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT); + mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME; + mWindow.mBehindIme = true; + addWindow(mWindow); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); + + assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, IME_HEIGHT); + } + @Test public void layoutWindowLw_fitDisplayCutout() { addDisplayCutout(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java index 7ba3fd815b2d..c87014a8a27f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java @@ -62,7 +62,7 @@ public class DisplayPolicyTestsBase extends WindowTestsBase { static final int STATUS_BAR_HEIGHT = 10; static final int NAV_BAR_HEIGHT = 15; static final int DISPLAY_CUTOUT_HEIGHT = 8; - static final int INPUT_METHOD_WINDOW_TOP = 585; + static final int IME_HEIGHT = 415; DisplayPolicy mDisplayPolicy; -- GitLab From e92b7d792cbf3ca774607446555b48cbb7cb46ea Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Wed, 2 Sep 2020 11:50:39 -0400 Subject: [PATCH 346/536] Make dialog not exported Apps must go through ControlsProviderService.requestAddControl Test: test app Fixes: 167566024 Change-Id: I50424cb0ff1c66eeacaa7a8af5beed9d5e973384 --- packages/SystemUI/AndroidManifest.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 667433c46e50..4deb74410bb1 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -717,10 +717,9 @@ - + Date: Wed, 2 Sep 2020 09:21:01 -0400 Subject: [PATCH 347/536] Media - Handle cleanup of pending notification entries It is possible for notifications to be canceled prior to inflation, which means there will not be a callback when the notification is removed. Utitlize the NotifCollectionListener to get this event. Fixes: 166315453 Test: manual, using RCNs to generate a race condition as they create/cancel notifications immediately Change-Id: I56d3ab9ef46d86c8623f9bac9152e8a2b8341c01 (cherry picked from commit a332522abb7c91f4d1501997532f3f5173096e80) --- .../statusbar/NotificationMediaManager.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java index 739d30c2a707..8cd82cc77530 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java @@ -21,6 +21,7 @@ import static com.android.systemui.statusbar.phone.StatusBar.ENABLE_LOCKSCREEN_W import static com.android.systemui.statusbar.phone.StatusBar.SHOW_LOCKSCREEN_MEDIA_ARTWORK; import android.annotation.MainThread; +import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; import android.content.Context; @@ -57,6 +58,7 @@ import com.android.systemui.statusbar.dagger.StatusBarModule; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.LockscreenWallpaper; @@ -234,8 +236,17 @@ public class NotificationMediaManager implements Dumpable { NotificationVisibility visibility, boolean removedByUser, int reason) { - onNotificationRemoved(entry.getKey()); - mediaDataManager.onNotificationRemoved(entry.getKey()); + removeEntry(entry); + } + }); + + // Pending entries are never inflated, and will never generate a call to onEntryRemoved(). + // This can happen when notifications are added and canceled before inflation. Add this + // separate listener for cleanup, since media inflation occurs onPendingEntryAdded(). + notificationEntryManager.addCollectionListener(new NotifCollectionListener() { + @Override + public void onEntryCleanUp(@NonNull NotificationEntry entry) { + removeEntry(entry); } }); @@ -248,6 +259,11 @@ public class NotificationMediaManager implements Dumpable { mPropertiesChangedListener); } + private void removeEntry(NotificationEntry entry) { + onNotificationRemoved(entry.getKey()); + mMediaDataManager.onNotificationRemoved(entry.getKey()); + } + /** * Check if a state should be considered actively playing * @param state a PlaybackState -- GitLab From 3e91d35fa70a60bef7f09168d7317e19d3399bb9 Mon Sep 17 00:00:00 2001 From: Marco Ballesio Date: Tue, 1 Sep 2020 11:15:37 -0700 Subject: [PATCH 348/536] CachedAppOptimizer: freeze/unfreeze binder Instruct binder to perform specific handling for frozen processes. Bug: 143717177 Test: manually verified the handling of transactions to frozen processes Test: manually verified that transactions are delivered to unfrozen processes Change-Id: I81801eac859fc81a1042f5166baa3fe9dbb8258b --- .../android/server/am/CachedAppOptimizer.java | 30 +++++++++++++++++++ ...m_android_server_am_CachedAppOptimizer.cpp | 10 +++++++ 2 files changed, 40 insertions(+) diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index c5047e5eed03..966038986791 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -478,6 +478,21 @@ public final class CachedAppOptimizer { */ private static native void enableFreezerInternal(boolean enable); + /** + * Informs binder that a process is about to be frozen. If freezer is enabled on a process via + * this method, this method will synchronously dispatch all pending transactions to the + * specified pid. This method will not add significant latencies when unfreezing. + * After freezing binder calls, binder will block all transaction to the frozen pid, and return + * an error to the sending process. + * + * @param pid the target pid for which binder transactions are to be frozen + * @param freeze specifies whether to flush transactions and then freeze (true) or unfreeze + * binder for the specificed pid. + * + * @throws RuntimeException in case a flush/freeze operation could not complete successfully. + */ + private static native void freezeBinder(int pid, boolean freeze); + /** * Determines whether the freezer is supported by this system */ @@ -727,6 +742,13 @@ public final class CachedAppOptimizer { } if (!app.frozen) { + try { + freezeBinder(app.pid, false); + } catch (RuntimeException e) { + // TODO: it might be preferable to kill the target pid in this case + Slog.e(TAG_AM, "Unable to unfreeze binder for " + app.pid + " " + app.processName); + } + if (DEBUG_FREEZER) { Slog.d(TAG_AM, "sync unfroze " + app.pid + " " + app.processName); } @@ -1039,6 +1061,14 @@ public final class CachedAppOptimizer { return; } + try { + freezeBinder(pid, true); + } catch (RuntimeException e) { + // TODO: it might be preferable to kill the target pid in this case + Slog.e(TAG_AM, "Unable to freeze binder for " + pid + " " + name); + return; + } + if (pid == 0 || proc.frozen) { // Already frozen or not a real process, either one being // launched or one being killed diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp index 7e9e11d209a6..95d4ba7c199a 100644 --- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -90,11 +91,20 @@ static void com_android_server_am_CachedAppOptimizer_enableFreezerInternal( } } +static void com_android_server_am_CachedAppOptimizer_freezeBinder( + JNIEnv *env, jobject clazz, jint pid, jboolean freeze) { + + if (IPCThreadState::freeze(pid, freeze, 100 /* timeout [ms] */) != 0) { + jniThrowException(env, "java/lang/RuntimeException", "Unable to freeze/unfreeze binder"); + } +} + static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ {"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem}, {"enableFreezerInternal", "(Z)V", (void*)com_android_server_am_CachedAppOptimizer_enableFreezerInternal}, + {"freezeBinder", "(IZ)V", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder} }; int register_android_server_am_CachedAppOptimizer(JNIEnv* env) -- GitLab From 08744836fe65f37236d0020b1dd857195627d02c Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Thu, 27 Aug 2020 15:41:46 -0700 Subject: [PATCH 349/536] [Suggestion] Fix setWpa3EnterpriseConfig Add missing support for standard WPA3-Enterprise networks, which are basically WPA2-Enterprise networks + PMF. Add missing support in the Specifier as well, and add unit tests to cover these use cases. The logic detects 192-bit or standard mode by looking at the certificates. If the certificates are Suite-B, then the 192-bit mode is enabled. Otherwise, standard mode is enabled. Bug: 166670837 Test: atest WifiNetworkSuggestionTest WifiNetworkSpecifierTest Change-Id: I875d0d0584d71fe6dd3fedc8f5371e0b5ed2e5e5 Merged-In: I875d0d0584d71fe6dd3fedc8f5371e0b5ed2e5e5 (cherry picked from commit e1369b6275b90c1409dae784815bcf3affe64684) --- .../net/wifi/WifiEnterpriseConfig.java | 49 +++ .../net/wifi/WifiNetworkSpecifier.java | 31 +- .../net/wifi/WifiNetworkSuggestion.java | 31 +- wifi/tests/src/android/net/wifi/FakeKeys.java | 413 +++++++++++++++++- .../net/wifi/WifiNetworkSpecifierTest.java | 105 +++++ .../net/wifi/WifiNetworkSuggestionTest.java | 78 +++- 6 files changed, 691 insertions(+), 16 deletions(-) diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 77fa673f1960..90edc4523b7b 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -30,6 +30,9 @@ import java.lang.annotation.RetentionPolicy; import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.cert.X509Certificate; +import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.ECParameterSpec; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -1442,4 +1445,50 @@ public class WifiEnterpriseConfig implements Parcelable { } return TextUtils.isEmpty(getCaPath()); } + + /** + * Check if a given certificate Get the Suite-B cipher from the certificate + * + * @param x509Certificate Certificate to process + * @return true if the certificate OID matches the Suite-B requirements for RSA or ECDSA + * certificates, or false otherwise. + * @hide + */ + public static boolean isSuiteBCipherCert(@Nullable X509Certificate x509Certificate) { + if (x509Certificate == null) { + return false; + } + final String sigAlgOid = x509Certificate.getSigAlgOID(); + + // Wi-Fi alliance requires the use of both ECDSA secp384r1 and RSA 3072 certificates + // in WPA3-Enterprise 192-bit security networks, which are also known as Suite-B-192 + // networks, even though NSA Suite-B-192 mandates ECDSA only. The use of the term + // Suite-B was already coined in the IEEE 802.11-2016 specification for + // AKM 00-0F-AC but the test plan for WPA3-Enterprise 192-bit for APs mandates + // support for both RSA and ECDSA, and for STAs it mandates ECDSA and optionally + // RSA. In order to be compatible with all WPA3-Enterprise 192-bit deployments, + // we are supporting both types here. + if (sigAlgOid.equals("1.2.840.113549.1.1.12")) { + // sha384WithRSAEncryption + if (x509Certificate.getPublicKey() instanceof RSAPublicKey) { + final RSAPublicKey rsaPublicKey = (RSAPublicKey) x509Certificate.getPublicKey(); + if (rsaPublicKey.getModulus() != null + && rsaPublicKey.getModulus().bitLength() >= 3072) { + return true; + } + } + } else if (sigAlgOid.equals("1.2.840.10045.4.3.3")) { + // ecdsa-with-SHA384 + if (x509Certificate.getPublicKey() instanceof ECPublicKey) { + final ECPublicKey ecPublicKey = (ECPublicKey) x509Certificate.getPublicKey(); + final ECParameterSpec ecParameterSpec = ecPublicKey.getParams(); + + if (ecParameterSpec != null && ecParameterSpec.getOrder() != null + && ecParameterSpec.getOrder().bitLength() >= 384) { + return true; + } + } + } + return false; + } } diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java index b0213b0ef502..e12bb9178235 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java @@ -78,12 +78,12 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc private @Nullable String mWpa3SaePassphrase; /** * The enterprise configuration details specifying the EAP method, - * certificates and other settings associated with the WPA-EAP networks. + * certificates and other settings associated with the WPA/WPA2-Enterprise networks. */ private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig; /** * The enterprise configuration details specifying the EAP method, - * certificates and other settings associated with the SuiteB networks. + * certificates and other settings associated with the WPA3-Enterprise networks. */ private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig; /** @@ -243,7 +243,11 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc /** * Set the associated enterprise configuration for this network. Needed for authenticating - * to WPA3-SuiteB networks. See {@link WifiEnterpriseConfig} for description. + * to WPA3-Enterprise networks (standard and 192-bit security). See + * {@link WifiEnterpriseConfig} for description. For 192-bit security networks, both the + * client and CA certificates must be provided, and must be of type of either + * sha384WithRSAEncryption (OID 1.2.840.113549.1.1.12) or ecdsa-with-SHA384 + * (OID 1.2.840.10045.4.3.3). * * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}. * @return Instance of {@link Builder} to enable chaining of the builder method. @@ -284,8 +288,25 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); configuration.enterpriseConfig = mWpa2EnterpriseConfig; - } else if (mWpa3EnterpriseConfig != null) { // WPA3-SuiteB network - configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B); + } else if (mWpa3EnterpriseConfig != null) { // WPA3-Enterprise + if (mWpa3EnterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TLS + && WifiEnterpriseConfig.isSuiteBCipherCert( + mWpa3EnterpriseConfig.getClientCertificate()) + && WifiEnterpriseConfig.isSuiteBCipherCert( + mWpa3EnterpriseConfig.getCaCertificate())) { + // WPA3-Enterprise in 192-bit security mode (Suite-B) + configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B); + } else { + // WPA3-Enterprise + configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); + configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN); + configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); + configuration.allowedPairwiseCiphers.set( + WifiConfiguration.PairwiseCipher.GCMP_256); + configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); + configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); + configuration.requirePmf = true; + } configuration.enterpriseConfig = mWpa3EnterpriseConfig; } else if (mIsEnhancedOpen) { // OWE network configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE); diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 68eb1bbd8a79..d8be1d2c853c 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -72,12 +72,12 @@ public final class WifiNetworkSuggestion implements Parcelable { private @Nullable String mWpa3SaePassphrase; /** * The enterprise configuration details specifying the EAP method, - * certificates and other settings associated with the WPA-EAP networks. + * certificates and other settings associated with the WPA/WPA2-Enterprise networks. */ private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig; /** * The enterprise configuration details specifying the EAP method, - * certificates and other settings associated with the SuiteB networks. + * certificates and other settings associated with the WPA3-Enterprise networks. */ private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig; /** @@ -276,7 +276,11 @@ public final class WifiNetworkSuggestion implements Parcelable { /** * Set the associated enterprise configuration for this network. Needed for authenticating - * to WPA3 enterprise networks. See {@link WifiEnterpriseConfig} for description. + * to WPA3-Enterprise networks (standard and 192-bit security). See + * {@link WifiEnterpriseConfig} for description. For 192-bit security networks, both the + * client and CA certificates must be provided, and must be of type of either + * sha384WithRSAEncryption (OID 1.2.840.113549.1.1.12) or ecdsa-with-SHA384 + * (OID 1.2.840.10045.4.3.3). * * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}. * @return Instance of {@link Builder} to enable chaining of the builder method. @@ -522,8 +526,25 @@ public final class WifiNetworkSuggestion implements Parcelable { } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); configuration.enterpriseConfig = mWpa2EnterpriseConfig; - } else if (mWpa3EnterpriseConfig != null) { // WPA3-SuiteB network - configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B); + } else if (mWpa3EnterpriseConfig != null) { // WPA3-Enterprise + if (mWpa3EnterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TLS + && WifiEnterpriseConfig.isSuiteBCipherCert( + mWpa3EnterpriseConfig.getClientCertificate()) + && WifiEnterpriseConfig.isSuiteBCipherCert( + mWpa3EnterpriseConfig.getCaCertificate())) { + // WPA3-Enterprise in 192-bit security mode (Suite-B) + configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B); + } else { + // WPA3-Enterprise + configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); + configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN); + configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); + configuration.allowedPairwiseCiphers.set( + WifiConfiguration.PairwiseCipher.GCMP_256); + configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); + configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); + configuration.requirePmf = true; + } configuration.enterpriseConfig = mWpa3EnterpriseConfig; } else if (mIsEnhancedOpen) { // OWE network configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE); diff --git a/wifi/tests/src/android/net/wifi/FakeKeys.java b/wifi/tests/src/android/net/wifi/FakeKeys.java index 641b891a1f4d..8aa6add4a4e4 100644 --- a/wifi/tests/src/android/net/wifi/FakeKeys.java +++ b/wifi/tests/src/android/net/wifi/FakeKeys.java @@ -212,7 +212,57 @@ public class FakeKeys { (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1, (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51 }; - public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1); + public static final PrivateKey RSA_KEY1 = loadPrivateKey("RSA", FAKE_RSA_KEY_1); + + private static final String CA_SUITE_B_RSA3072_CERT_STRING = + "-----BEGIN CERTIFICATE-----\n" + + "MIIEnTCCAwWgAwIBAgIUD87Y8fFLzLr1HQ/64aEnjNq2R/4wDQYJKoZIhvcNAQEM\n" + + "BQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAO\n" + + "BgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0\n" + + "Q0EwHhcNMjAwNzIxMDIxNzU0WhcNMzAwNTMwMDIxNzU0WjBeMQswCQYDVQQGEwJV\n" + + "UzELMAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEO\n" + + "MAwGA1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTCCAaIwDQYJKoZIhvcN\n" + + "AQEBBQADggGPADCCAYoCggGBAMtrsT0otlxh0QS079KpRRbU1PQjCihSoltXnrxF\n" + + "sTWZs2weVEeYVyYU5LaauCDDgISCMtjtfbfylMBeYjpWB5hYzYQOiTzo0anWhMyb\n" + + "Ngb7gpMVZuIl6lwMYRyVRKwHWnTo2EUg1ZzW5rGe5fs/KHj6//hoNFm+3Oju0TQd\n" + + "nraQULpoERPF5B7p85Cssk8uNbviBfZXvtCuJ4N6w7PNceOY/9bbwc1mC+pPZmzV\n" + + "SOAg0vvbIQRzChm63C3jBC3xmxSOOZVrKN4zKDG2s8P0oCNGt0NlgRMrgbPRekzg\n" + + "4avkbA0vTuc2AyriTEYkdea/Mt4EpRg9XuOb43U/GJ/d/vQv2/9fsxhXmsZrn8kr\n" + + "Qo5MMHJFUd96GgHmvYSU3Mf/5r8gF626lvqHioGuTAuHUSnr02ri1WUxZ15LDRgY\n" + + "quMjDCFZfucjJPDAdtiHcFSej/4SLJlN39z8oKKNPn3aL9Gv49oAKs9S8tfDVzMk\n" + + "fDLROQFHFuW715GnnMgEAoOpRwIDAQABo1MwUTAdBgNVHQ4EFgQUeVuGmSVN4ARs\n" + + "mesUMWSJ2qWLbxUwHwYDVR0jBBgwFoAUeVuGmSVN4ARsmesUMWSJ2qWLbxUwDwYD\n" + + "VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQwFAAOCAYEAit1Lo/hegZpPuT9dlWZJ\n" + + "bC8JvAf95O8lnn6LFb69pgYOHCLgCIlvYXu9rdBUJgZo+V1MzJJljiO6RxWRfKbQ\n" + + "8WBYkoqR1EqriR3Kn8q/SjIZCdFSaznTyU1wQMveBQ6RJWXSUhYVfE9RjyFTp7B4\n" + + "UyH2uCluR/0T06HQNGfH5XpIYQqCk1Zgng5lmEmheLDPoJpa92lKeQFJMC6eYz9g\n" + + "lF1GHxPxkPfbMJ6ZDp5X6Yopu6Q6uEXhVKM/iQVcgzRkx9rid+xTYl+nOKyK/XfC\n" + + "z8P0/TFIoPTW02DLge5wKagdoCpy1B7HdrAXyUjoH4B8MsUkq3kYPFSjPzScuTtV\n" + + "kUuDw5ipCNeXCRnhbYqRDk6PX5GUu2cmN9jtaH3tbgm3fKNOsd/BO1fLIl7qjXlR\n" + + "27HHbC0JXjNvlm2DLp23v4NTxS7WZGYsxyUj5DZrxBxqCsTXu/01w1BrQKWKh9FM\n" + + "aVrlA8omfVODK2CSuw+KhEMHepRv/AUgsLl4L4+RMoa+\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CA_SUITE_B_RSA3072_CERT = + loadCertificate(CA_SUITE_B_RSA3072_CERT_STRING); + + private static final String CA_SUITE_B_ECDSA_CERT_STRING = + "-----BEGIN CERTIFICATE-----\n" + + "MIICTzCCAdSgAwIBAgIUdnLttwNPnQzFufplGOr9bTrGCqMwCgYIKoZIzj0EAwMw\n" + + "XjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNV\n" + + "BAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0Q0Ew\n" + + "HhcNMjAwNzIxMDIyNDA1WhcNMzAwNTMwMDIyNDA1WjBeMQswCQYDVQQGEwJVUzEL\n" + + "MAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEOMAwG\n" + + "A1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTB2MBAGByqGSM49AgEGBSuB\n" + + "BAAiA2IABFmntXwk9icqhDQFUP1xy04WyEpaGW4q6Q+8pujlSl/X3iotPZ++GZfp\n" + + "Mfv3YDHDBl6sELPQ2BEjyPXmpsKjOUdiUe69e88oGEdeqT2xXiQ6uzpTfJD4170i\n" + + "O/TwLrQGKKNTMFEwHQYDVR0OBBYEFCjptsX3g4g5W0L4oEP6N3gfyiZXMB8GA1Ud\n" + + "IwQYMBaAFCjptsX3g4g5W0L4oEP6N3gfyiZXMA8GA1UdEwEB/wQFMAMBAf8wCgYI\n" + + "KoZIzj0EAwMDaQAwZgIxAK61brUYRbLmQKiaEboZgrHtnPAcGo7Yzx3MwHecx3Dm\n" + + "5soIeLVYc8bPYN1pbhXW1gIxALdEe2sh03nBHyQH4adYoZungoCwt8mp/7sJFxou\n" + + "9UnRegyBgGzf74ROWdpZHzh+Pg==\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CA_SUITE_B_ECDSA_CERT = + loadCertificate(CA_SUITE_B_ECDSA_CERT_STRING); private static final String CLIENT_SUITE_B_RSA3072_CERT_STRING = "-----BEGIN CERTIFICATE-----\n" @@ -243,6 +293,363 @@ public class FakeKeys { public static final X509Certificate CLIENT_SUITE_B_RSA3072_CERT = loadCertificate(CLIENT_SUITE_B_RSA3072_CERT_STRING); + private static final byte[] CLIENT_SUITE_B_RSA3072_KEY_DATA = new byte[]{ + (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xfe, (byte) 0x02, (byte) 0x01, + (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, + (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, + (byte) 0x06, (byte) 0xe8, (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xe4, + (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x82, (byte) 0x01, + (byte) 0x81, (byte) 0x00, (byte) 0xc1, (byte) 0x22, (byte) 0xb7, (byte) 0x0b, + (byte) 0x92, (byte) 0xb9, (byte) 0xb9, (byte) 0xdb, (byte) 0x42, (byte) 0x29, + (byte) 0x39, (byte) 0xc4, (byte) 0xd7, (byte) 0x87, (byte) 0xbc, (byte) 0xcf, + (byte) 0x67, (byte) 0x19, (byte) 0xbf, (byte) 0x09, (byte) 0x81, (byte) 0xe1, + (byte) 0x77, (byte) 0xbe, (byte) 0x6b, (byte) 0xcf, (byte) 0xbb, (byte) 0x40, + (byte) 0xbb, (byte) 0x9d, (byte) 0x1e, (byte) 0x8a, (byte) 0x1c, (byte) 0xfe, + (byte) 0x54, (byte) 0x33, (byte) 0x0a, (byte) 0x58, (byte) 0x0a, (byte) 0xe0, + (byte) 0xc6, (byte) 0xd5, (byte) 0x50, (byte) 0x2d, (byte) 0x03, (byte) 0xdc, + (byte) 0x51, (byte) 0x3e, (byte) 0x53, (byte) 0x7d, (byte) 0x82, (byte) 0xef, + (byte) 0xc4, (byte) 0xb1, (byte) 0x2a, (byte) 0x84, (byte) 0xda, (byte) 0x45, + (byte) 0x6b, (byte) 0x6f, (byte) 0x3e, (byte) 0x63, (byte) 0x66, (byte) 0xf9, + (byte) 0x46, (byte) 0x85, (byte) 0x4f, (byte) 0xc2, (byte) 0xa4, (byte) 0xc3, + (byte) 0x25, (byte) 0x27, (byte) 0xa3, (byte) 0xf7, (byte) 0x6f, (byte) 0xfb, + (byte) 0x65, (byte) 0xc3, (byte) 0xa5, (byte) 0xdf, (byte) 0xf3, (byte) 0x01, + (byte) 0x14, (byte) 0x3e, (byte) 0xdc, (byte) 0x5c, (byte) 0x00, (byte) 0x7d, + (byte) 0x6a, (byte) 0x29, (byte) 0x02, (byte) 0x11, (byte) 0x32, (byte) 0x09, + (byte) 0x54, (byte) 0xb1, (byte) 0xc2, (byte) 0xc0, (byte) 0x9a, (byte) 0xfa, + (byte) 0xc9, (byte) 0x50, (byte) 0xe2, (byte) 0x3b, (byte) 0x91, (byte) 0x20, + (byte) 0xc2, (byte) 0x2e, (byte) 0x50, (byte) 0x2d, (byte) 0x4c, (byte) 0x9b, + (byte) 0x43, (byte) 0x5a, (byte) 0xa6, (byte) 0xd6, (byte) 0x72, (byte) 0x33, + (byte) 0x74, (byte) 0xe3, (byte) 0xfc, (byte) 0x80, (byte) 0x90, (byte) 0x11, + (byte) 0xfa, (byte) 0x64, (byte) 0xa3, (byte) 0xda, (byte) 0x95, (byte) 0x21, + (byte) 0xb8, (byte) 0x8a, (byte) 0xe9, (byte) 0xea, (byte) 0x09, (byte) 0x31, + (byte) 0x39, (byte) 0x18, (byte) 0xf0, (byte) 0x45, (byte) 0x9f, (byte) 0x02, + (byte) 0x7e, (byte) 0xd1, (byte) 0x4c, (byte) 0x57, (byte) 0x5f, (byte) 0x47, + (byte) 0x53, (byte) 0x8b, (byte) 0xb8, (byte) 0xed, (byte) 0x26, (byte) 0x54, + (byte) 0xe8, (byte) 0xe0, (byte) 0x2d, (byte) 0x6f, (byte) 0x7f, (byte) 0xfa, + (byte) 0xea, (byte) 0x58, (byte) 0xbf, (byte) 0xa8, (byte) 0x59, (byte) 0xd7, + (byte) 0xd9, (byte) 0xc0, (byte) 0x30, (byte) 0x0c, (byte) 0x70, (byte) 0xe1, + (byte) 0x04, (byte) 0xc9, (byte) 0xc7, (byte) 0xb9, (byte) 0x4b, (byte) 0xc0, + (byte) 0x02, (byte) 0xd7, (byte) 0xec, (byte) 0x1f, (byte) 0xad, (byte) 0x0d, + (byte) 0x83, (byte) 0x44, (byte) 0x64, (byte) 0x70, (byte) 0xea, (byte) 0x60, + (byte) 0xbd, (byte) 0xb3, (byte) 0xca, (byte) 0xf4, (byte) 0x16, (byte) 0x02, + (byte) 0x3d, (byte) 0x87, (byte) 0x0a, (byte) 0x57, (byte) 0xab, (byte) 0x7b, + (byte) 0xc4, (byte) 0x18, (byte) 0x20, (byte) 0xbc, (byte) 0x64, (byte) 0xbe, + (byte) 0x4b, (byte) 0x60, (byte) 0x06, (byte) 0x0d, (byte) 0x9c, (byte) 0xac, + (byte) 0x42, (byte) 0x49, (byte) 0x7b, (byte) 0x85, (byte) 0xdb, (byte) 0x0c, + (byte) 0x7e, (byte) 0xcb, (byte) 0x03, (byte) 0x7a, (byte) 0xeb, (byte) 0x5e, + (byte) 0x6b, (byte) 0x22, (byte) 0xa9, (byte) 0xfd, (byte) 0x59, (byte) 0x6d, + (byte) 0xf1, (byte) 0x45, (byte) 0x13, (byte) 0x32, (byte) 0xbd, (byte) 0x34, + (byte) 0x5a, (byte) 0xa8, (byte) 0xbc, (byte) 0xbf, (byte) 0xaa, (byte) 0x1a, + (byte) 0x1f, (byte) 0xb3, (byte) 0x20, (byte) 0xff, (byte) 0xb9, (byte) 0xf3, + (byte) 0xc4, (byte) 0xa1, (byte) 0x24, (byte) 0x53, (byte) 0xbd, (byte) 0x1f, + (byte) 0xf4, (byte) 0x43, (byte) 0x9c, (byte) 0x3a, (byte) 0x62, (byte) 0x4e, + (byte) 0x70, (byte) 0x05, (byte) 0x4d, (byte) 0x65, (byte) 0xd0, (byte) 0x75, + (byte) 0x3c, (byte) 0x20, (byte) 0xb3, (byte) 0x34, (byte) 0x92, (byte) 0xd1, + (byte) 0x5c, (byte) 0x36, (byte) 0x3c, (byte) 0x1f, (byte) 0x89, (byte) 0xa8, + (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0xaf, (byte) 0x43, (byte) 0x78, + (byte) 0xcb, (byte) 0xd7, (byte) 0x4f, (byte) 0x53, (byte) 0xb2, (byte) 0xf8, + (byte) 0xd6, (byte) 0x37, (byte) 0x22, (byte) 0xd3, (byte) 0xc7, (byte) 0xcb, + (byte) 0x2e, (byte) 0xb7, (byte) 0x9d, (byte) 0x06, (byte) 0x55, (byte) 0x23, + (byte) 0x6a, (byte) 0xd7, (byte) 0x00, (byte) 0xdc, (byte) 0x38, (byte) 0x36, + (byte) 0x1c, (byte) 0x12, (byte) 0xd1, (byte) 0x9e, (byte) 0x83, (byte) 0x17, + (byte) 0xe4, (byte) 0x2c, (byte) 0x4c, (byte) 0xda, (byte) 0xe3, (byte) 0xf8, + (byte) 0x65, (byte) 0x3b, (byte) 0x7b, (byte) 0x84, (byte) 0x86, (byte) 0xfc, + (byte) 0x41, (byte) 0x91, (byte) 0xf1, (byte) 0x2b, (byte) 0xe5, (byte) 0x76, + (byte) 0x36, (byte) 0x1f, (byte) 0x41, (byte) 0x35, (byte) 0x85, (byte) 0x2e, + (byte) 0x0d, (byte) 0x65, (byte) 0xfd, (byte) 0x44, (byte) 0xf5, (byte) 0x84, + (byte) 0xe3, (byte) 0xa4, (byte) 0x41, (byte) 0x9c, (byte) 0x1d, (byte) 0xb1, + (byte) 0xa5, (byte) 0xb5, (byte) 0xce, (byte) 0x02, (byte) 0xb2, (byte) 0x7a, + (byte) 0xe8, (byte) 0x85, (byte) 0x07, (byte) 0x62, (byte) 0x9d, (byte) 0x32, + (byte) 0x66, (byte) 0xc0, (byte) 0x4a, (byte) 0xaf, (byte) 0x94, (byte) 0xc7, + (byte) 0x52, (byte) 0xf5, (byte) 0x28, (byte) 0x80, (byte) 0xa8, (byte) 0xd0, + (byte) 0x88, (byte) 0x25, (byte) 0xc1, (byte) 0x67, (byte) 0x01, (byte) 0xff, + (byte) 0xc9, (byte) 0xe7, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, + (byte) 0x01, (byte) 0x02, (byte) 0x82, (byte) 0x01, (byte) 0x80, (byte) 0x04, + (byte) 0xb1, (byte) 0xcc, (byte) 0x53, (byte) 0x3a, (byte) 0xb0, (byte) 0xcb, + (byte) 0x04, (byte) 0xba, (byte) 0x59, (byte) 0xf8, (byte) 0x2e, (byte) 0x81, + (byte) 0xb2, (byte) 0xa9, (byte) 0xf3, (byte) 0x3c, (byte) 0xa5, (byte) 0x52, + (byte) 0x90, (byte) 0x6f, (byte) 0x98, (byte) 0xc4, (byte) 0x69, (byte) 0x5b, + (byte) 0x83, (byte) 0x84, (byte) 0x20, (byte) 0xb1, (byte) 0xae, (byte) 0xc3, + (byte) 0x04, (byte) 0x46, (byte) 0x6a, (byte) 0x24, (byte) 0x2f, (byte) 0xcd, + (byte) 0x6b, (byte) 0x90, (byte) 0x70, (byte) 0x20, (byte) 0x45, (byte) 0x25, + (byte) 0x1a, (byte) 0xc3, (byte) 0x02, (byte) 0x42, (byte) 0xf3, (byte) 0x49, + (byte) 0xe2, (byte) 0x3e, (byte) 0x21, (byte) 0x87, (byte) 0xdd, (byte) 0x6a, + (byte) 0x94, (byte) 0x2a, (byte) 0x1e, (byte) 0x0f, (byte) 0xdb, (byte) 0x77, + (byte) 0x5f, (byte) 0xc1, (byte) 0x2c, (byte) 0x03, (byte) 0xfb, (byte) 0xcf, + (byte) 0x91, (byte) 0x82, (byte) 0xa1, (byte) 0xbf, (byte) 0xb0, (byte) 0x73, + (byte) 0xfa, (byte) 0xda, (byte) 0xbc, (byte) 0xf8, (byte) 0x9f, (byte) 0x45, + (byte) 0xd3, (byte) 0xe8, (byte) 0xbb, (byte) 0x38, (byte) 0xfb, (byte) 0xc2, + (byte) 0x2d, (byte) 0x76, (byte) 0x51, (byte) 0x96, (byte) 0x18, (byte) 0x03, + (byte) 0x15, (byte) 0xd9, (byte) 0xea, (byte) 0x82, (byte) 0x25, (byte) 0x83, + (byte) 0xff, (byte) 0x5c, (byte) 0x85, (byte) 0x06, (byte) 0x09, (byte) 0xb2, + (byte) 0x46, (byte) 0x12, (byte) 0x64, (byte) 0x02, (byte) 0x74, (byte) 0x4f, + (byte) 0xbc, (byte) 0x9a, (byte) 0x25, (byte) 0x18, (byte) 0x01, (byte) 0x07, + (byte) 0x17, (byte) 0x25, (byte) 0x55, (byte) 0x7c, (byte) 0xdc, (byte) 0xe1, + (byte) 0xd1, (byte) 0x5a, (byte) 0x2f, (byte) 0x25, (byte) 0xaf, (byte) 0xf6, + (byte) 0x8f, (byte) 0xa4, (byte) 0x9a, (byte) 0x5a, (byte) 0x3a, (byte) 0xfe, + (byte) 0x2e, (byte) 0x93, (byte) 0x24, (byte) 0xa0, (byte) 0x27, (byte) 0xac, + (byte) 0x07, (byte) 0x75, (byte) 0x33, (byte) 0x01, (byte) 0x54, (byte) 0x23, + (byte) 0x0f, (byte) 0xe8, (byte) 0x9f, (byte) 0xfa, (byte) 0x36, (byte) 0xe6, + (byte) 0x3a, (byte) 0xd5, (byte) 0x78, (byte) 0xb0, (byte) 0xe4, (byte) 0x6a, + (byte) 0x16, (byte) 0x50, (byte) 0xbd, (byte) 0x0f, (byte) 0x9f, (byte) 0x32, + (byte) 0xa1, (byte) 0x6b, (byte) 0xf5, (byte) 0xa4, (byte) 0x34, (byte) 0x58, + (byte) 0xb6, (byte) 0xa4, (byte) 0xb3, (byte) 0xc3, (byte) 0x83, (byte) 0x08, + (byte) 0x18, (byte) 0xc7, (byte) 0xef, (byte) 0x95, (byte) 0xe2, (byte) 0x1b, + (byte) 0xba, (byte) 0x35, (byte) 0x61, (byte) 0xa3, (byte) 0xb4, (byte) 0x30, + (byte) 0xe0, (byte) 0xd1, (byte) 0xc1, (byte) 0xa2, (byte) 0x3a, (byte) 0xc6, + (byte) 0xb4, (byte) 0xd2, (byte) 0x80, (byte) 0x5a, (byte) 0xaf, (byte) 0xa4, + (byte) 0x54, (byte) 0x3c, (byte) 0x66, (byte) 0x5a, (byte) 0x1c, (byte) 0x4d, + (byte) 0xe1, (byte) 0xd9, (byte) 0x98, (byte) 0x44, (byte) 0x01, (byte) 0x1b, + (byte) 0x8c, (byte) 0xe9, (byte) 0x80, (byte) 0x54, (byte) 0x83, (byte) 0x3d, + (byte) 0x96, (byte) 0x25, (byte) 0x41, (byte) 0x1c, (byte) 0xad, (byte) 0xae, + (byte) 0x3b, (byte) 0x7a, (byte) 0xd7, (byte) 0x9d, (byte) 0x10, (byte) 0x7c, + (byte) 0xd1, (byte) 0xa7, (byte) 0x96, (byte) 0x39, (byte) 0xa5, (byte) 0x2f, + (byte) 0xbe, (byte) 0xc3, (byte) 0x2c, (byte) 0x64, (byte) 0x01, (byte) 0xfe, + (byte) 0xa2, (byte) 0xd1, (byte) 0x6a, (byte) 0xcf, (byte) 0x4c, (byte) 0x76, + (byte) 0x3b, (byte) 0xc8, (byte) 0x35, (byte) 0x21, (byte) 0xda, (byte) 0x98, + (byte) 0xcf, (byte) 0xf9, (byte) 0x29, (byte) 0xff, (byte) 0x30, (byte) 0x59, + (byte) 0x36, (byte) 0x53, (byte) 0x0b, (byte) 0xbb, (byte) 0xfa, (byte) 0xba, + (byte) 0xc4, (byte) 0x03, (byte) 0x23, (byte) 0xe0, (byte) 0xd3, (byte) 0x33, + (byte) 0xff, (byte) 0x32, (byte) 0xdb, (byte) 0x30, (byte) 0x64, (byte) 0xc7, + (byte) 0x56, (byte) 0xca, (byte) 0x55, (byte) 0x14, (byte) 0xee, (byte) 0x58, + (byte) 0xfe, (byte) 0x96, (byte) 0x7e, (byte) 0x1c, (byte) 0x34, (byte) 0x16, + (byte) 0xeb, (byte) 0x76, (byte) 0x26, (byte) 0x48, (byte) 0xe2, (byte) 0xe5, + (byte) 0x5c, (byte) 0xd5, (byte) 0x83, (byte) 0x37, (byte) 0xd9, (byte) 0x09, + (byte) 0x71, (byte) 0xbc, (byte) 0x54, (byte) 0x25, (byte) 0xca, (byte) 0x2e, + (byte) 0xdb, (byte) 0x36, (byte) 0x39, (byte) 0xcc, (byte) 0x3a, (byte) 0x81, + (byte) 0x95, (byte) 0x9e, (byte) 0xf4, (byte) 0x01, (byte) 0xa7, (byte) 0xc0, + (byte) 0x20, (byte) 0xce, (byte) 0x70, (byte) 0x55, (byte) 0x2c, (byte) 0xe0, + (byte) 0x93, (byte) 0x72, (byte) 0xa6, (byte) 0x25, (byte) 0xda, (byte) 0x64, + (byte) 0x19, (byte) 0x18, (byte) 0xd2, (byte) 0x31, (byte) 0xe2, (byte) 0x7c, + (byte) 0xf2, (byte) 0x30, (byte) 0x9e, (byte) 0x8d, (byte) 0xc6, (byte) 0x14, + (byte) 0x8a, (byte) 0x38, (byte) 0xf0, (byte) 0x94, (byte) 0xeb, (byte) 0xf4, + (byte) 0x64, (byte) 0x92, (byte) 0x3d, (byte) 0x67, (byte) 0xa6, (byte) 0x2c, + (byte) 0x52, (byte) 0xfc, (byte) 0x60, (byte) 0xca, (byte) 0x2a, (byte) 0xcf, + (byte) 0x24, (byte) 0xd5, (byte) 0x42, (byte) 0x5f, (byte) 0xc7, (byte) 0x9f, + (byte) 0xf3, (byte) 0xb4, (byte) 0xdf, (byte) 0x76, (byte) 0x6e, (byte) 0x53, + (byte) 0xa1, (byte) 0x7b, (byte) 0xae, (byte) 0xa5, (byte) 0x84, (byte) 0x1f, + (byte) 0xfa, (byte) 0xc0, (byte) 0xb4, (byte) 0x6c, (byte) 0xc9, (byte) 0x02, + (byte) 0x81, (byte) 0xc1, (byte) 0x00, (byte) 0xf3, (byte) 0x17, (byte) 0xd9, + (byte) 0x48, (byte) 0x17, (byte) 0x87, (byte) 0x84, (byte) 0x16, (byte) 0xea, + (byte) 0x2d, (byte) 0x31, (byte) 0x1b, (byte) 0xce, (byte) 0xec, (byte) 0xaf, + (byte) 0xdc, (byte) 0x6b, (byte) 0xaf, (byte) 0xc8, (byte) 0xf1, (byte) 0x40, + (byte) 0xa7, (byte) 0x4f, (byte) 0xef, (byte) 0x48, (byte) 0x08, (byte) 0x5e, + (byte) 0x9a, (byte) 0xd1, (byte) 0xc0, (byte) 0xb1, (byte) 0xfe, (byte) 0xe7, + (byte) 0x03, (byte) 0xd5, (byte) 0x96, (byte) 0x01, (byte) 0xe8, (byte) 0x40, + (byte) 0xca, (byte) 0x78, (byte) 0xcb, (byte) 0xb3, (byte) 0x28, (byte) 0x1a, + (byte) 0xf0, (byte) 0xe5, (byte) 0xf6, (byte) 0x46, (byte) 0xef, (byte) 0xcd, + (byte) 0x1a, (byte) 0x0f, (byte) 0x13, (byte) 0x2d, (byte) 0x38, (byte) 0xf8, + (byte) 0xf7, (byte) 0x88, (byte) 0x21, (byte) 0x15, (byte) 0xce, (byte) 0x48, + (byte) 0xf4, (byte) 0x92, (byte) 0x7e, (byte) 0x9b, (byte) 0x2e, (byte) 0x2f, + (byte) 0x22, (byte) 0x3e, (byte) 0x5c, (byte) 0x67, (byte) 0xd7, (byte) 0x58, + (byte) 0xf6, (byte) 0xef, (byte) 0x1f, (byte) 0xb4, (byte) 0x04, (byte) 0xc7, + (byte) 0xfd, (byte) 0x8c, (byte) 0x4e, (byte) 0x27, (byte) 0x9e, (byte) 0xb9, + (byte) 0xef, (byte) 0x0f, (byte) 0xf7, (byte) 0x4a, (byte) 0xc2, (byte) 0xf4, + (byte) 0x64, (byte) 0x6b, (byte) 0xe0, (byte) 0xfb, (byte) 0xe3, (byte) 0x45, + (byte) 0xd5, (byte) 0x37, (byte) 0xa0, (byte) 0x2a, (byte) 0xc6, (byte) 0xf3, + (byte) 0xf6, (byte) 0xcc, (byte) 0xb5, (byte) 0x94, (byte) 0xbf, (byte) 0x56, + (byte) 0xa0, (byte) 0x61, (byte) 0x36, (byte) 0x88, (byte) 0x35, (byte) 0xd5, + (byte) 0xa5, (byte) 0xad, (byte) 0x20, (byte) 0x48, (byte) 0xda, (byte) 0x70, + (byte) 0x35, (byte) 0xd9, (byte) 0x75, (byte) 0x66, (byte) 0xa5, (byte) 0xac, + (byte) 0x86, (byte) 0x7a, (byte) 0x75, (byte) 0x49, (byte) 0x88, (byte) 0x40, + (byte) 0xce, (byte) 0xb0, (byte) 0x6f, (byte) 0x57, (byte) 0x15, (byte) 0x54, + (byte) 0xd3, (byte) 0x2f, (byte) 0x11, (byte) 0x9b, (byte) 0xe3, (byte) 0x87, + (byte) 0xc8, (byte) 0x8d, (byte) 0x98, (byte) 0xc6, (byte) 0xe0, (byte) 0xbc, + (byte) 0x85, (byte) 0xb9, (byte) 0x04, (byte) 0x43, (byte) 0xa9, (byte) 0x41, + (byte) 0xce, (byte) 0x42, (byte) 0x1a, (byte) 0x57, (byte) 0x10, (byte) 0xd8, + (byte) 0xe4, (byte) 0x6a, (byte) 0x51, (byte) 0x10, (byte) 0x0a, (byte) 0xec, + (byte) 0xe4, (byte) 0x57, (byte) 0xc7, (byte) 0xee, (byte) 0xe9, (byte) 0xd6, + (byte) 0xcb, (byte) 0x3e, (byte) 0xba, (byte) 0xfa, (byte) 0xe9, (byte) 0x0e, + (byte) 0xed, (byte) 0x87, (byte) 0x04, (byte) 0x9a, (byte) 0x48, (byte) 0xba, + (byte) 0xaf, (byte) 0x08, (byte) 0xf5, (byte) 0x02, (byte) 0x81, (byte) 0xc1, + (byte) 0x00, (byte) 0xcb, (byte) 0x63, (byte) 0xd6, (byte) 0x54, (byte) 0xb6, + (byte) 0xf3, (byte) 0xf3, (byte) 0x8c, (byte) 0xf8, (byte) 0xd0, (byte) 0xd2, + (byte) 0x84, (byte) 0xc1, (byte) 0xf5, (byte) 0x12, (byte) 0xe0, (byte) 0x02, + (byte) 0x80, (byte) 0x42, (byte) 0x92, (byte) 0x4e, (byte) 0xa4, (byte) 0x5c, + (byte) 0xa5, (byte) 0x64, (byte) 0xec, (byte) 0xb7, (byte) 0xdc, (byte) 0xe0, + (byte) 0x2d, (byte) 0x5d, (byte) 0xac, (byte) 0x0e, (byte) 0x24, (byte) 0x48, + (byte) 0x13, (byte) 0x05, (byte) 0xe8, (byte) 0xff, (byte) 0x96, (byte) 0x93, + (byte) 0xba, (byte) 0x3c, (byte) 0x88, (byte) 0xcc, (byte) 0x80, (byte) 0xf9, + (byte) 0xdb, (byte) 0xa8, (byte) 0x4d, (byte) 0x86, (byte) 0x47, (byte) 0xc8, + (byte) 0xbf, (byte) 0x34, (byte) 0x2d, (byte) 0xda, (byte) 0xb6, (byte) 0x28, + (byte) 0xf0, (byte) 0x1e, (byte) 0xd2, (byte) 0x46, (byte) 0x0d, (byte) 0x6f, + (byte) 0x36, (byte) 0x8e, (byte) 0x84, (byte) 0xd8, (byte) 0xaf, (byte) 0xf7, + (byte) 0x69, (byte) 0x23, (byte) 0x77, (byte) 0xfb, (byte) 0xc5, (byte) 0x04, + (byte) 0x08, (byte) 0x18, (byte) 0xac, (byte) 0x85, (byte) 0x80, (byte) 0x87, + (byte) 0x1c, (byte) 0xfe, (byte) 0x8e, (byte) 0x5d, (byte) 0x00, (byte) 0x7f, + (byte) 0x5b, (byte) 0x33, (byte) 0xf5, (byte) 0xdf, (byte) 0x70, (byte) 0x81, + (byte) 0xad, (byte) 0x81, (byte) 0xf4, (byte) 0x5a, (byte) 0x37, (byte) 0x8a, + (byte) 0x79, (byte) 0x09, (byte) 0xc5, (byte) 0x55, (byte) 0xab, (byte) 0x58, + (byte) 0x7c, (byte) 0x47, (byte) 0xca, (byte) 0xa5, (byte) 0x80, (byte) 0x49, + (byte) 0x5f, (byte) 0x71, (byte) 0x83, (byte) 0xfb, (byte) 0x3b, (byte) 0x06, + (byte) 0xec, (byte) 0x75, (byte) 0x23, (byte) 0xc4, (byte) 0x32, (byte) 0xc7, + (byte) 0x18, (byte) 0xf6, (byte) 0x82, (byte) 0x95, (byte) 0x98, (byte) 0x39, + (byte) 0xf7, (byte) 0x92, (byte) 0x31, (byte) 0xc0, (byte) 0x89, (byte) 0xba, + (byte) 0xd4, (byte) 0xd4, (byte) 0x58, (byte) 0x4e, (byte) 0x38, (byte) 0x35, + (byte) 0x10, (byte) 0xb9, (byte) 0xf1, (byte) 0x27, (byte) 0xdc, (byte) 0xff, + (byte) 0xc7, (byte) 0xb2, (byte) 0xba, (byte) 0x1f, (byte) 0x27, (byte) 0xaf, + (byte) 0x99, (byte) 0xd5, (byte) 0xb0, (byte) 0x39, (byte) 0xe7, (byte) 0x43, + (byte) 0x88, (byte) 0xd3, (byte) 0xce, (byte) 0x38, (byte) 0xc2, (byte) 0x99, + (byte) 0x43, (byte) 0xfc, (byte) 0x8a, (byte) 0xe3, (byte) 0x60, (byte) 0x0d, + (byte) 0x0a, (byte) 0xb8, (byte) 0xc4, (byte) 0x29, (byte) 0xca, (byte) 0x0d, + (byte) 0x30, (byte) 0xaf, (byte) 0xca, (byte) 0xd0, (byte) 0xaa, (byte) 0x67, + (byte) 0xb1, (byte) 0xdd, (byte) 0xdb, (byte) 0x7a, (byte) 0x11, (byte) 0xad, + (byte) 0xeb, (byte) 0x02, (byte) 0x81, (byte) 0xc0, (byte) 0x71, (byte) 0xb8, + (byte) 0xcf, (byte) 0x72, (byte) 0x35, (byte) 0x67, (byte) 0xb5, (byte) 0x38, + (byte) 0x8f, (byte) 0x16, (byte) 0xd3, (byte) 0x29, (byte) 0x82, (byte) 0x35, + (byte) 0x21, (byte) 0xd4, (byte) 0x49, (byte) 0x20, (byte) 0x74, (byte) 0x2d, + (byte) 0xc0, (byte) 0xa4, (byte) 0x44, (byte) 0xf5, (byte) 0xd8, (byte) 0xc9, + (byte) 0xe9, (byte) 0x90, (byte) 0x1d, (byte) 0xde, (byte) 0x3a, (byte) 0xa6, + (byte) 0xd7, (byte) 0xe5, (byte) 0xe8, (byte) 0x4e, (byte) 0x83, (byte) 0xd7, + (byte) 0xe6, (byte) 0x2f, (byte) 0x92, (byte) 0x31, (byte) 0x21, (byte) 0x3f, + (byte) 0xfa, (byte) 0xd2, (byte) 0x85, (byte) 0x92, (byte) 0x1f, (byte) 0xff, + (byte) 0x61, (byte) 0x00, (byte) 0xf6, (byte) 0xda, (byte) 0x6e, (byte) 0xc6, + (byte) 0x7f, (byte) 0x5a, (byte) 0x35, (byte) 0x79, (byte) 0xdc, (byte) 0xdc, + (byte) 0xa3, (byte) 0x2e, (byte) 0x9f, (byte) 0x35, (byte) 0xd1, (byte) 0x5c, + (byte) 0xda, (byte) 0xb9, (byte) 0xf7, (byte) 0x58, (byte) 0x7d, (byte) 0x4f, + (byte) 0xb6, (byte) 0x13, (byte) 0xd7, (byte) 0x2c, (byte) 0x0a, (byte) 0xa8, + (byte) 0x4d, (byte) 0xf2, (byte) 0xe4, (byte) 0x67, (byte) 0x4f, (byte) 0x8b, + (byte) 0xa6, (byte) 0xca, (byte) 0x1a, (byte) 0xbb, (byte) 0x02, (byte) 0x63, + (byte) 0x8f, (byte) 0xb7, (byte) 0x46, (byte) 0xec, (byte) 0x7a, (byte) 0x8a, + (byte) 0x09, (byte) 0x0a, (byte) 0x45, (byte) 0x3a, (byte) 0x8d, (byte) 0xa8, + (byte) 0x83, (byte) 0x4b, (byte) 0x0a, (byte) 0xdb, (byte) 0x4b, (byte) 0x99, + (byte) 0xf3, (byte) 0x69, (byte) 0x95, (byte) 0xf0, (byte) 0xcf, (byte) 0xe9, + (byte) 0xf7, (byte) 0x67, (byte) 0xc9, (byte) 0x45, (byte) 0x18, (byte) 0x2f, + (byte) 0xf0, (byte) 0x5c, (byte) 0x90, (byte) 0xbd, (byte) 0xa6, (byte) 0x66, + (byte) 0x8c, (byte) 0xfe, (byte) 0x60, (byte) 0x5d, (byte) 0x6c, (byte) 0x27, + (byte) 0xec, (byte) 0xc1, (byte) 0x84, (byte) 0xb2, (byte) 0xa1, (byte) 0x97, + (byte) 0x9e, (byte) 0x16, (byte) 0x29, (byte) 0xa7, (byte) 0xe0, (byte) 0x38, + (byte) 0xa2, (byte) 0x36, (byte) 0x05, (byte) 0x5f, (byte) 0xda, (byte) 0x72, + (byte) 0x1a, (byte) 0x5f, (byte) 0xa8, (byte) 0x7d, (byte) 0x41, (byte) 0x35, + (byte) 0xf6, (byte) 0x4e, (byte) 0x0a, (byte) 0x88, (byte) 0x8e, (byte) 0x00, + (byte) 0x98, (byte) 0xa6, (byte) 0xca, (byte) 0xc1, (byte) 0xdf, (byte) 0x72, + (byte) 0x6c, (byte) 0xfe, (byte) 0x29, (byte) 0xbe, (byte) 0xa3, (byte) 0x9b, + (byte) 0x0b, (byte) 0x5c, (byte) 0x0b, (byte) 0x9d, (byte) 0xa7, (byte) 0x71, + (byte) 0xce, (byte) 0x04, (byte) 0xfa, (byte) 0xac, (byte) 0x01, (byte) 0x8d, + (byte) 0x52, (byte) 0xa0, (byte) 0x3d, (byte) 0xdd, (byte) 0x02, (byte) 0x81, + (byte) 0xc1, (byte) 0x00, (byte) 0xc1, (byte) 0xc0, (byte) 0x2e, (byte) 0xa9, + (byte) 0xee, (byte) 0xca, (byte) 0xff, (byte) 0xe4, (byte) 0xf8, (byte) 0x15, + (byte) 0xfd, (byte) 0xa5, (byte) 0x68, (byte) 0x1b, (byte) 0x2d, (byte) 0x4a, + (byte) 0xe6, (byte) 0x37, (byte) 0x06, (byte) 0xb3, (byte) 0xd7, (byte) 0x64, + (byte) 0xad, (byte) 0xb9, (byte) 0x05, (byte) 0x26, (byte) 0x97, (byte) 0x94, + (byte) 0x3a, (byte) 0x9e, (byte) 0x1c, (byte) 0xd0, (byte) 0xcd, (byte) 0x7b, + (byte) 0xf4, (byte) 0x88, (byte) 0xe2, (byte) 0xa5, (byte) 0x6d, (byte) 0xed, + (byte) 0x24, (byte) 0x77, (byte) 0x52, (byte) 0x39, (byte) 0x43, (byte) 0x0f, + (byte) 0x4e, (byte) 0x75, (byte) 0xd8, (byte) 0xa3, (byte) 0x59, (byte) 0x5a, + (byte) 0xc2, (byte) 0xba, (byte) 0x9a, (byte) 0x5b, (byte) 0x60, (byte) 0x31, + (byte) 0x0d, (byte) 0x58, (byte) 0x89, (byte) 0x13, (byte) 0xe8, (byte) 0x95, + (byte) 0xdd, (byte) 0xae, (byte) 0xcc, (byte) 0x1f, (byte) 0x73, (byte) 0x48, + (byte) 0x55, (byte) 0xd8, (byte) 0xfb, (byte) 0x67, (byte) 0xce, (byte) 0x18, + (byte) 0x85, (byte) 0x59, (byte) 0xad, (byte) 0x1f, (byte) 0x93, (byte) 0xe1, + (byte) 0xb7, (byte) 0x54, (byte) 0x80, (byte) 0x8e, (byte) 0x5f, (byte) 0xbc, + (byte) 0x1c, (byte) 0x96, (byte) 0x66, (byte) 0x2e, (byte) 0x40, (byte) 0x17, + (byte) 0x2e, (byte) 0x01, (byte) 0x7a, (byte) 0x7d, (byte) 0xaa, (byte) 0xff, + (byte) 0xa3, (byte) 0xd2, (byte) 0xdf, (byte) 0xe2, (byte) 0xf3, (byte) 0x54, + (byte) 0x51, (byte) 0xeb, (byte) 0xba, (byte) 0x7c, (byte) 0x2a, (byte) 0x22, + (byte) 0xc6, (byte) 0x42, (byte) 0xbc, (byte) 0xa1, (byte) 0x6c, (byte) 0xcf, + (byte) 0x73, (byte) 0x2e, (byte) 0x07, (byte) 0xfc, (byte) 0xf5, (byte) 0x67, + (byte) 0x25, (byte) 0xd0, (byte) 0xfa, (byte) 0xeb, (byte) 0xb4, (byte) 0xd4, + (byte) 0x19, (byte) 0xcc, (byte) 0x64, (byte) 0xa1, (byte) 0x2e, (byte) 0x78, + (byte) 0x45, (byte) 0xd9, (byte) 0x7f, (byte) 0x1b, (byte) 0x4c, (byte) 0x10, + (byte) 0x31, (byte) 0x44, (byte) 0xe8, (byte) 0xcc, (byte) 0xf9, (byte) 0x1b, + (byte) 0x87, (byte) 0x31, (byte) 0xd6, (byte) 0x69, (byte) 0x85, (byte) 0x4a, + (byte) 0x49, (byte) 0xf6, (byte) 0xb2, (byte) 0xe0, (byte) 0xb8, (byte) 0x98, + (byte) 0x3c, (byte) 0xf6, (byte) 0x78, (byte) 0x46, (byte) 0xc8, (byte) 0x3d, + (byte) 0x60, (byte) 0xc1, (byte) 0xaa, (byte) 0x2f, (byte) 0x28, (byte) 0xa1, + (byte) 0x14, (byte) 0x6b, (byte) 0x75, (byte) 0x4d, (byte) 0xb1, (byte) 0x3d, + (byte) 0x80, (byte) 0x49, (byte) 0x33, (byte) 0xfd, (byte) 0x71, (byte) 0xc0, + (byte) 0x13, (byte) 0x1e, (byte) 0x16, (byte) 0x69, (byte) 0x80, (byte) 0xa4, + (byte) 0x9c, (byte) 0xd7, (byte) 0x02, (byte) 0x81, (byte) 0xc1, (byte) 0x00, + (byte) 0x8c, (byte) 0x33, (byte) 0x2d, (byte) 0xd9, (byte) 0xf3, (byte) 0x42, + (byte) 0x4d, (byte) 0xca, (byte) 0x5e, (byte) 0x60, (byte) 0x14, (byte) 0x10, + (byte) 0xf6, (byte) 0xf3, (byte) 0x71, (byte) 0x15, (byte) 0x88, (byte) 0x54, + (byte) 0x84, (byte) 0x21, (byte) 0x04, (byte) 0xb1, (byte) 0xaf, (byte) 0x02, + (byte) 0x11, (byte) 0x7f, (byte) 0x42, (byte) 0x3e, (byte) 0x86, (byte) 0xcb, + (byte) 0x6c, (byte) 0xf5, (byte) 0x57, (byte) 0x78, (byte) 0x4a, (byte) 0x03, + (byte) 0x9b, (byte) 0x80, (byte) 0xc2, (byte) 0x04, (byte) 0x3a, (byte) 0x6b, + (byte) 0xb3, (byte) 0x30, (byte) 0x31, (byte) 0x7e, (byte) 0xc3, (byte) 0x89, + (byte) 0x09, (byte) 0x4e, (byte) 0x86, (byte) 0x59, (byte) 0x41, (byte) 0xb5, + (byte) 0xae, (byte) 0xd5, (byte) 0xc6, (byte) 0x38, (byte) 0xbc, (byte) 0xd7, + (byte) 0xd7, (byte) 0x8e, (byte) 0xa3, (byte) 0x1a, (byte) 0xde, (byte) 0x32, + (byte) 0xad, (byte) 0x8d, (byte) 0x15, (byte) 0x81, (byte) 0xfe, (byte) 0xac, + (byte) 0xbd, (byte) 0xd0, (byte) 0xca, (byte) 0xbc, (byte) 0xd8, (byte) 0x6a, + (byte) 0xe1, (byte) 0xfe, (byte) 0xda, (byte) 0xc4, (byte) 0xd8, (byte) 0x62, + (byte) 0x71, (byte) 0x20, (byte) 0xa3, (byte) 0xd3, (byte) 0x06, (byte) 0x11, + (byte) 0xa9, (byte) 0x53, (byte) 0x7a, (byte) 0x44, (byte) 0x89, (byte) 0x3d, + (byte) 0x28, (byte) 0x5e, (byte) 0x7d, (byte) 0xf0, (byte) 0x60, (byte) 0xeb, + (byte) 0xb5, (byte) 0xdf, (byte) 0xed, (byte) 0x4f, (byte) 0x6d, (byte) 0x05, + (byte) 0x59, (byte) 0x06, (byte) 0xb0, (byte) 0x62, (byte) 0x50, (byte) 0x1c, + (byte) 0xb7, (byte) 0x2c, (byte) 0x44, (byte) 0xa4, (byte) 0x49, (byte) 0xf8, + (byte) 0x4f, (byte) 0x4b, (byte) 0xab, (byte) 0x71, (byte) 0x5b, (byte) 0xcb, + (byte) 0x31, (byte) 0x10, (byte) 0x41, (byte) 0xe0, (byte) 0x1a, (byte) 0x15, + (byte) 0xdc, (byte) 0x4c, (byte) 0x5d, (byte) 0x4f, (byte) 0x62, (byte) 0x83, + (byte) 0xa4, (byte) 0x80, (byte) 0x06, (byte) 0x36, (byte) 0xba, (byte) 0xc9, + (byte) 0xe2, (byte) 0xa4, (byte) 0x11, (byte) 0x98, (byte) 0x6b, (byte) 0x4c, + (byte) 0xe9, (byte) 0x90, (byte) 0x55, (byte) 0x18, (byte) 0xde, (byte) 0xe1, + (byte) 0x42, (byte) 0x38, (byte) 0x28, (byte) 0xa3, (byte) 0x54, (byte) 0x56, + (byte) 0x31, (byte) 0xaf, (byte) 0x5a, (byte) 0xd6, (byte) 0xf0, (byte) 0x26, + (byte) 0xe0, (byte) 0x7a, (byte) 0xd9, (byte) 0x6c, (byte) 0x64, (byte) 0xca, + (byte) 0x5d, (byte) 0x6d, (byte) 0x3d, (byte) 0x9a, (byte) 0xfe, (byte) 0x36, + (byte) 0x93, (byte) 0x9e, (byte) 0x62, (byte) 0x94, (byte) 0xc6, (byte) 0x07, + (byte) 0x83, (byte) 0x96, (byte) 0xd6, (byte) 0x27, (byte) 0xa6, (byte) 0xd8 + }; + public static final PrivateKey CLIENT_SUITE_B_RSA3072_KEY = + loadPrivateKey("RSA", CLIENT_SUITE_B_RSA3072_KEY_DATA); + + private static final String CLIENT_SUITE_B_ECDSA_CERT_STRING = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB9zCCAX4CFDpfSZh3AH07BEfGWuMDa7Ynz6y+MAoGCCqGSM49BAMDMF4xCzAJ\n" + + "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQKDAdB\n" + + "bmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4XDTIw\n" + + "MDcyMTAyMjk1MFoXDTMwMDUzMDAyMjk1MFowYjELMAkGA1UEBhMCVVMxCzAJBgNV\n" + + "BAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsM\n" + + "BVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MHYwEAYHKoZIzj0CAQYFK4EE\n" + + "ACIDYgAEhxhVJ7dcSqrto0X+dgRxtd8BWG8cWmPjBji3MIxDLfpcMDoIB84ae1Ew\n" + + "gJn4YUYHrWsUDiVNihv8j7a/Ol1qcIY2ybH7tbezefLmagqA4vXEUXZXoUyL4ZNC\n" + + "DWcdw6LrMAoGCCqGSM49BAMDA2cAMGQCMH4aP73HrriRUJRguiuRic+X4Cqj/7YQ\n" + + "ueJmP87KF92/thhoQ9OrRo8uJITPmNDswwIwP2Q1AZCSL4BI9dYrqu07Ar+pSkXE\n" + + "R7oOqGdZR+d/MvXcFSrbIaLKEoHXmQamIHLe\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CLIENT_SUITE_B_ECDSA_CERT = + loadCertificate(CLIENT_SUITE_B_ECDSA_CERT_STRING); + + private static final byte[] CLIENT_SUITE_B_ECC_KEY_DATA = new byte[]{ + (byte) 0x30, (byte) 0x81, (byte) 0xb6, (byte) 0x02, (byte) 0x01, (byte) 0x00, + (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06, + (byte) 0x05, (byte) 0x2b, (byte) 0x81, (byte) 0x04, (byte) 0x00, (byte) 0x22, + (byte) 0x04, (byte) 0x81, (byte) 0x9e, (byte) 0x30, (byte) 0x81, (byte) 0x9b, + (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x30, (byte) 0xea, + (byte) 0x6c, (byte) 0x4b, (byte) 0x6d, (byte) 0x43, (byte) 0xf9, (byte) 0x6c, + (byte) 0x91, (byte) 0xdc, (byte) 0x2d, (byte) 0x6e, (byte) 0x87, (byte) 0x4f, + (byte) 0x0a, (byte) 0x0b, (byte) 0x97, (byte) 0x25, (byte) 0x1c, (byte) 0x79, + (byte) 0xa2, (byte) 0x07, (byte) 0xdc, (byte) 0x94, (byte) 0xc2, (byte) 0xee, + (byte) 0x64, (byte) 0x51, (byte) 0x6d, (byte) 0x4e, (byte) 0x35, (byte) 0x1c, + (byte) 0x22, (byte) 0x2f, (byte) 0xc0, (byte) 0xea, (byte) 0x09, (byte) 0x47, + (byte) 0x3e, (byte) 0xb9, (byte) 0xb6, (byte) 0xb8, (byte) 0x83, (byte) 0x9e, + (byte) 0xed, (byte) 0x59, (byte) 0xe5, (byte) 0xe7, (byte) 0x0f, (byte) 0xa1, + (byte) 0x64, (byte) 0x03, (byte) 0x62, (byte) 0x00, (byte) 0x04, (byte) 0x87, + (byte) 0x18, (byte) 0x55, (byte) 0x27, (byte) 0xb7, (byte) 0x5c, (byte) 0x4a, + (byte) 0xaa, (byte) 0xed, (byte) 0xa3, (byte) 0x45, (byte) 0xfe, (byte) 0x76, + (byte) 0x04, (byte) 0x71, (byte) 0xb5, (byte) 0xdf, (byte) 0x01, (byte) 0x58, + (byte) 0x6f, (byte) 0x1c, (byte) 0x5a, (byte) 0x63, (byte) 0xe3, (byte) 0x06, + (byte) 0x38, (byte) 0xb7, (byte) 0x30, (byte) 0x8c, (byte) 0x43, (byte) 0x2d, + (byte) 0xfa, (byte) 0x5c, (byte) 0x30, (byte) 0x3a, (byte) 0x08, (byte) 0x07, + (byte) 0xce, (byte) 0x1a, (byte) 0x7b, (byte) 0x51, (byte) 0x30, (byte) 0x80, + (byte) 0x99, (byte) 0xf8, (byte) 0x61, (byte) 0x46, (byte) 0x07, (byte) 0xad, + (byte) 0x6b, (byte) 0x14, (byte) 0x0e, (byte) 0x25, (byte) 0x4d, (byte) 0x8a, + (byte) 0x1b, (byte) 0xfc, (byte) 0x8f, (byte) 0xb6, (byte) 0xbf, (byte) 0x3a, + (byte) 0x5d, (byte) 0x6a, (byte) 0x70, (byte) 0x86, (byte) 0x36, (byte) 0xc9, + (byte) 0xb1, (byte) 0xfb, (byte) 0xb5, (byte) 0xb7, (byte) 0xb3, (byte) 0x79, + (byte) 0xf2, (byte) 0xe6, (byte) 0x6a, (byte) 0x0a, (byte) 0x80, (byte) 0xe2, + (byte) 0xf5, (byte) 0xc4, (byte) 0x51, (byte) 0x76, (byte) 0x57, (byte) 0xa1, + (byte) 0x4c, (byte) 0x8b, (byte) 0xe1, (byte) 0x93, (byte) 0x42, (byte) 0x0d, + (byte) 0x67, (byte) 0x1d, (byte) 0xc3, (byte) 0xa2, (byte) 0xeb + }; + public static final PrivateKey CLIENT_SUITE_B_ECC_KEY = + loadPrivateKey("EC", CLIENT_SUITE_B_ECC_KEY_DATA); + private static X509Certificate loadCertificate(String blob) { try { final CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); @@ -255,9 +662,9 @@ public class FakeKeys { } } - private static PrivateKey loadPrivateRSAKey(byte[] fakeKey) { + private static PrivateKey loadPrivateKey(String algorithm, byte[] fakeKey) { try { - KeyFactory kf = KeyFactory.getInstance("RSA"); + KeyFactory kf = KeyFactory.getInstance(algorithm); return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey)); } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { return null; diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java index fc0ef469ad80..6f47f3da710f 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java @@ -22,6 +22,8 @@ import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.net.MacAddress; @@ -35,6 +37,8 @@ import androidx.test.filters.SmallTest; import org.junit.Test; +import java.security.cert.X509Certificate; + /** * Unit tests for {@link android.net.wifi.WifiNetworkSpecifier}. */ @@ -45,6 +49,7 @@ public class WifiNetworkSpecifierTest { private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00"; private static final String TEST_BSSID = "12:12:12:12:12:12"; private static final String TEST_PRESHARED_KEY = "\"Test123\""; + private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch"; /** * Validate correctness of WifiNetworkSpecifier object created by @@ -135,6 +140,106 @@ public class WifiNetworkSpecifierTest { wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getPhase2Method()); } + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise network. + */ + @Test + public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); + enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0); + enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); + + NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder() + .setSsid(TEST_SSID) + .setWpa3EnterpriseConfig(enterpriseConfig) + .build(); + + assertTrue(specifier instanceof WifiNetworkSpecifier); + WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier; + + assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.IEEE8021X)); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WPA_EAP)); + assertFalse(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers + .get(WifiConfiguration.GroupCipher.CCMP)); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf); + assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey); + assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig); + } + + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit RSA SuiteB network. + */ + @Test + public void testWifiNetworkSuggestionBuilderForWpa3SuiteBRsaEapNetwork() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); + enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_RSA3072_CERT); + enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_RSA3072_KEY, + new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_RSA3072_CERT}); + + enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); + + NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder() + .setSsid(TEST_SSID) + .setWpa3EnterpriseConfig(enterpriseConfig) + .build(); + + assertTrue(specifier instanceof WifiNetworkSpecifier); + WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier; + + assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers + .get(WifiConfiguration.GroupCipher.GCMP_256)); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupManagementCiphers + .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf); + assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey); + assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig); + } + + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit ECC SuiteB network. + */ + @Test + public void testWifiNetworkSuggestionBuilderForWpa3SuiteBEccEapNetwork() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); + enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_ECDSA_CERT); + enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_ECC_KEY, + new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_ECDSA_CERT}); + + enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); + + NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder() + .setSsid(TEST_SSID) + .setWpa3EnterpriseConfig(enterpriseConfig) + .build(); + + assertTrue(specifier instanceof WifiNetworkSpecifier); + WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier; + + assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers + .get(WifiConfiguration.GroupCipher.GCMP_256)); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupManagementCiphers + .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); + assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf); + assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey); + assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig); + } /** * Ensure {@link WifiNetworkSpecifier.Builder#setSsid(String)} throws an exception diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index 16b4ad08a830..00a044269db3 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -27,6 +27,8 @@ import androidx.test.filters.SmallTest; import org.junit.Test; +import java.security.cert.X509Certificate; + /** * Unit tests for {@link android.net.wifi.WifiNetworkSuggestion}. */ @@ -199,19 +201,89 @@ public class WifiNetworkSuggestionTest { assertFalse(suggestion.isInitialAutoJoinEnabled); } - /** * Validate correctness of WifiNetworkSuggestion object created by - * {@link WifiNetworkSuggestion.Builder#build()} for SuiteB network. + * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise network. */ @Test public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() { WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); - enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0); enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWpa3EnterpriseConfig(enterpriseConfig) + .build(); + + assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); + assertTrue(suggestion.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.IEEE8021X)); + assertTrue(suggestion.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WPA_EAP)); + assertFalse(suggestion.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); + assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers + .get(WifiConfiguration.GroupCipher.CCMP)); + assertTrue(suggestion.wifiConfiguration.requirePmf); + assertNull(suggestion.wifiConfiguration.preSharedKey); + // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested + // here. + assertTrue(suggestion.isUserAllowedToManuallyConnect); + assertTrue(suggestion.isInitialAutoJoinEnabled); + assertNotNull(suggestion.getEnterpriseConfig()); + } + + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit RSA SuiteB network. + */ + @Test + public void testWifiNetworkSuggestionBuilderForWpa3SuiteBRsaEapNetwork() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); + enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_RSA3072_CERT); + enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_RSA3072_KEY, + new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_RSA3072_CERT}); + + enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); + + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWpa3EnterpriseConfig(enterpriseConfig) + .build(); + + assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); + assertTrue(suggestion.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); + assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers + .get(WifiConfiguration.GroupCipher.GCMP_256)); + assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers + .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); + assertTrue(suggestion.wifiConfiguration.requirePmf); + assertNull(suggestion.wifiConfiguration.preSharedKey); + // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested + // here. + assertTrue(suggestion.isUserAllowedToManuallyConnect); + assertTrue(suggestion.isInitialAutoJoinEnabled); + assertNotNull(suggestion.getEnterpriseConfig()); + } + + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit ECC SuiteB network. + */ + @Test + public void testWifiNetworkSuggestionBuilderForWpa3SuiteBEccEapNetwork() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); + enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_ECDSA_CERT); + enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_ECC_KEY, + new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_ECDSA_CERT}); + + enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) .setWpa3EnterpriseConfig(enterpriseConfig) -- GitLab From 0e9afe60a35cfea362919d7748c98a6596af52d2 Mon Sep 17 00:00:00 2001 From: Erin Yan Date: Thu, 27 Aug 2020 10:51:39 -0700 Subject: [PATCH 350/536] Retrieve unlockProfile attribute with private namespace Bug: 167105906 Bug: 155663736 Test: Attribute value is correctly parsed from packages/apps/Car/CompanionDeviceSupport/res/xml/car_trust_agent.xml Change-Id: If1d89607718462d8e073dee7c6482bf12c3f84c7 --- .../java/com/android/server/trust/TrustManagerService.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 2394bafc09de..26103d5d6c8c 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -123,6 +123,8 @@ public class TrustManagerService extends SystemService { private static final String TRUST_TIMEOUT_ALARM_TAG = "TrustManagerService.trustTimeoutForUser"; private static final long TRUST_TIMEOUT_IN_MILLIS = 4 * 60 * 60 * 1000; + private static final String PRIV_NAMESPACE = "http://schemas.android.com/apk/prv/res/android"; + private final ArraySet mActiveAgents = new ArraySet<>(); private final ArrayList mTrustListeners = new ArrayList<>(); private final Receiver mReceiver = new Receiver(); @@ -808,8 +810,8 @@ public class TrustManagerService extends SystemService { TypedArray sa = res .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent); cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity); - canUnlockProfile = sa.getBoolean( - com.android.internal.R.styleable.TrustAgent_unlockProfile, false); + canUnlockProfile = attrs.getAttributeBooleanValue( + PRIV_NAMESPACE, "unlockProfile", false); sa.recycle(); } catch (PackageManager.NameNotFoundException e) { caughtException = e; -- GitLab From 7857da643150e9b29f729632c68e705d7ba1ad48 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Wed, 26 Aug 2020 17:07:53 -0400 Subject: [PATCH 351/536] Sanitize more of the notification text fields Test: manual; monitor SystemUI performance when an app tries to post a messaging style notification with messages with long text Bug: 158304295 Bug: 147358092 Merged-In: c953fdf6bc498ca791aed49df04e5a07c935b63a Change-Id: I0e2ea12fc3351b1a56645b556720ea2306f5422a (cherry picked from commit c953fdf6bc498ca791aed49df04e5a07c935b63a) --- core/java/android/app/Notification.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index c179e3ca48af..04ed9da1633f 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -195,7 +195,7 @@ public class Notification implements Parcelable *

    * Avoids spamming the system with overly large strings such as full e-mails. */ - private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024; + private static final int MAX_CHARSEQUENCE_LENGTH = 1024; /** * Maximum entries of reply text that are accepted by Builder and friends. @@ -7240,7 +7240,7 @@ public class Notification implements Parcelable */ public Message(@NonNull CharSequence text, long timestamp, @Nullable Person sender, boolean remoteInputHistory) { - mText = text; + mText = safeCharSequence(text); mTimestamp = timestamp; mSender = sender; mRemoteInputHistory = remoteInputHistory; @@ -7350,7 +7350,7 @@ public class Notification implements Parcelable bundle.putLong(KEY_TIMESTAMP, mTimestamp); if (mSender != null) { // Legacy listeners need this - bundle.putCharSequence(KEY_SENDER, mSender.getName()); + bundle.putCharSequence(KEY_SENDER, safeCharSequence(mSender.getName())); bundle.putParcelable(KEY_SENDER_PERSON, mSender); } if (mDataMimeType != null) { -- GitLab From 8061246d4a35c8c2d3bea179352f0acb72290b6f Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Wed, 26 Aug 2020 17:07:53 -0400 Subject: [PATCH 352/536] Sanitize more of the notification text fields Test: manual; monitor SystemUI performance when an app tries to post a messaging style notification with messages with long text Bug: 158304295 Bug: 147358092 Merged-In: c953fdf6bc498ca791aed49df04e5a07c935b63a Change-Id: I0e2ea12fc3351b1a56645b556720ea2306f5422a (cherry picked from commit c953fdf6bc498ca791aed49df04e5a07c935b63a) --- core/java/android/app/Notification.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index a4c98e88cbc7..e26cac519756 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -205,7 +205,7 @@ public class Notification implements Parcelable *

    * Avoids spamming the system with overly large strings such as full e-mails. */ - private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024; + private static final int MAX_CHARSEQUENCE_LENGTH = 1024; /** * Maximum entries of reply text that are accepted by Builder and friends. @@ -7561,7 +7561,7 @@ public class Notification implements Parcelable */ public Message(@NonNull CharSequence text, long timestamp, @Nullable Person sender, boolean remoteInputHistory) { - mText = text; + mText = safeCharSequence(text); mTimestamp = timestamp; mSender = sender; mRemoteInputHistory = remoteInputHistory; @@ -7675,7 +7675,7 @@ public class Notification implements Parcelable bundle.putLong(KEY_TIMESTAMP, mTimestamp); if (mSender != null) { // Legacy listeners need this - bundle.putCharSequence(KEY_SENDER, mSender.getName()); + bundle.putCharSequence(KEY_SENDER, safeCharSequence(mSender.getName())); bundle.putParcelable(KEY_SENDER_PERSON, mSender); } if (mDataMimeType != null) { -- GitLab From 978d31e45a67dba9d57d45a26c1d521300ba1b6f Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Wed, 26 Aug 2020 17:07:53 -0400 Subject: [PATCH 353/536] Sanitize more of the notification text fields Test: manual; monitor SystemUI performance when an app tries to post a messaging style notification with messages with long text Bug: 158304295 Bug: 147358092 Merged-In: c953fdf6bc498ca791aed49df04e5a07c935b63a Change-Id: I0e2ea12fc3351b1a56645b556720ea2306f5422a (cherry picked from commit c953fdf6bc498ca791aed49df04e5a07c935b63a) --- core/java/android/app/Notification.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 789351e0d157..c266fbf8be0b 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -205,7 +205,7 @@ public class Notification implements Parcelable *

    * Avoids spamming the system with overly large strings such as full e-mails. */ - private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024; + private static final int MAX_CHARSEQUENCE_LENGTH = 1024; /** * Maximum entries of reply text that are accepted by Builder and friends. @@ -7573,7 +7573,7 @@ public class Notification implements Parcelable */ public Message(@NonNull CharSequence text, long timestamp, @Nullable Person sender, boolean remoteInputHistory) { - mText = text; + mText = safeCharSequence(text); mTimestamp = timestamp; mSender = sender; mRemoteInputHistory = remoteInputHistory; @@ -7687,7 +7687,7 @@ public class Notification implements Parcelable bundle.putLong(KEY_TIMESTAMP, mTimestamp); if (mSender != null) { // Legacy listeners need this - bundle.putCharSequence(KEY_SENDER, mSender.getName()); + bundle.putCharSequence(KEY_SENDER, safeCharSequence(mSender.getName())); bundle.putParcelable(KEY_SENDER_PERSON, mSender); } if (mDataMimeType != null) { -- GitLab From a19f9ed2b1c04fe7e73bab1a8ca51400dbf8a07a Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Wed, 26 Aug 2020 17:07:53 -0400 Subject: [PATCH 354/536] Sanitize more of the notification text fields Test: manual; monitor SystemUI performance when an app tries to post a messaging style notification with messages with long text Bug: 158304295 Bug: 147358092 Merged-In: c953fdf6bc498ca791aed49df04e5a07c935b63a Change-Id: I0e2ea12fc3351b1a56645b556720ea2306f5422a (cherry picked from commit c953fdf6bc498ca791aed49df04e5a07c935b63a) --- core/java/android/app/Notification.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 79d2a8102358..609083e719ba 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -207,7 +207,7 @@ public class Notification implements Parcelable *

    * Avoids spamming the system with overly large strings such as full e-mails. */ - private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024; + private static final int MAX_CHARSEQUENCE_LENGTH = 1024; /** * Maximum entries of reply text that are accepted by Builder and friends. @@ -7830,7 +7830,7 @@ public class Notification implements Parcelable */ public Message(@NonNull CharSequence text, long timestamp, @Nullable Person sender, boolean remoteInputHistory) { - mText = text; + mText = safeCharSequence(text); mTimestamp = timestamp; mSender = sender; mRemoteInputHistory = remoteInputHistory; @@ -7944,7 +7944,7 @@ public class Notification implements Parcelable bundle.putLong(KEY_TIMESTAMP, mTimestamp); if (mSender != null) { // Legacy listeners need this - bundle.putCharSequence(KEY_SENDER, mSender.getName()); + bundle.putCharSequence(KEY_SENDER, safeCharSequence(mSender.getName())); bundle.putParcelable(KEY_SENDER_PERSON, mSender); } if (mDataMimeType != null) { -- GitLab From cfa3045a5baacce7ab29e232b8d9b9029b516a96 Mon Sep 17 00:00:00 2001 From: Brad Ebinger Date: Thu, 3 Sep 2020 14:41:35 -0700 Subject: [PATCH 355/536] Modify the TelecomLoaderService to provide LocalServices to Telecom We need access to the DeviceIdleController, which is not currently accessible via the PowerWhitelistManager due to restrictions with components in the same SYSTEM process accessing public APIs (see context#enforceCallingPermission). To get around this, we need to wrap services only available as LocalServices using Binder to pass these services to the Telecom code. This is all in-process (no IPC allowed), so there should be little to no impact. Bug: 160724034 Test: miss call and verify `adb shell cmd deviceidle tempwhitelist` contains default dialer. Test: atest TelecomUnitTests; atest CtsTelecomTestCases Change-Id: I6275b550d19743e576b93f5fcd2bd3aa9ea4e1a8 --- .../telecom/InternalServiceRepository.java | 63 +++++++++++++++++++ .../server/telecom/TelecomLoaderService.java | 25 +++++--- .../telecom/IDeviceIdleControllerAdapter.aidl | 26 ++++++++ .../telecom/IInternalServiceRetriever.aidl | 27 ++++++++ .../internal/telecom/ITelecomLoader.aidl | 28 +++++++++ 5 files changed, 161 insertions(+), 8 deletions(-) create mode 100644 services/core/java/com/android/server/telecom/InternalServiceRepository.java create mode 100644 telecomm/java/com/android/internal/telecom/IDeviceIdleControllerAdapter.aidl create mode 100644 telecomm/java/com/android/internal/telecom/IInternalServiceRetriever.aidl create mode 100644 telecomm/java/com/android/internal/telecom/ITelecomLoader.aidl diff --git a/services/core/java/com/android/server/telecom/InternalServiceRepository.java b/services/core/java/com/android/server/telecom/InternalServiceRepository.java new file mode 100644 index 000000000000..76ea5c788bd7 --- /dev/null +++ b/services/core/java/com/android/server/telecom/InternalServiceRepository.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.telecom; + +import android.content.Context; +import android.os.Binder; +import android.os.Process; + +import com.android.internal.telecom.IDeviceIdleControllerAdapter; +import com.android.internal.telecom.IInternalServiceRetriever; +import com.android.server.DeviceIdleInternal; + +/** + * The Telecom APK can not access services stored in LocalService directly and since it is in the + * SYSTEM process, it also can not use the *Manager interfaces + * (see {@link Context#enforceCallingPermission(String, String)}). Instead, we must wrap these local + * services in binder interfaces to allow Telecom access. + */ +public class InternalServiceRepository extends IInternalServiceRetriever.Stub { + + private final IDeviceIdleControllerAdapter.Stub mDeviceIdleControllerAdapter = + new IDeviceIdleControllerAdapter.Stub() { + @Override + public void exemptAppTemporarilyForEvent(String packageName, long duration, int userHandle, + String reason) { + mDeviceIdleController.addPowerSaveTempWhitelistApp(Process.myUid(), packageName, + duration, userHandle, true /*sync*/, reason); + } + }; + + private final DeviceIdleInternal mDeviceIdleController; + + public InternalServiceRepository(DeviceIdleInternal deviceIdleController) { + mDeviceIdleController = deviceIdleController; + } + + @Override + public IDeviceIdleControllerAdapter getDeviceIdleController() { + ensureSystemProcess(); + return mDeviceIdleControllerAdapter; + } + + private void ensureSystemProcess() { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + // Correctness check - this should never happen. + throw new SecurityException("SYSTEM ONLY API."); + } + } +} diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java index a853529f49e4..52ad893a9ace 100644 --- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java +++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java @@ -35,7 +35,10 @@ import android.util.IntArray; import android.util.Slog; import com.android.internal.annotations.GuardedBy; +import com.android.internal.telecom.ITelecomLoader; +import com.android.internal.telecom.ITelecomService; import com.android.internal.telephony.SmsApplication; +import com.android.server.DeviceIdleInternal; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.pm.UserManagerService; @@ -53,16 +56,13 @@ public class TelecomLoaderService extends SystemService { @Override public void onServiceConnected(ComponentName name, IBinder service) { // Normally, we would listen for death here, but since telecom runs in the same process - // as this loader (process="system") thats redundant here. + // as this loader (process="system") that's redundant here. try { - service.linkToDeath(new IBinder.DeathRecipient() { - @Override - public void binderDied() { - connectToTelecom(); - } - }, 0); + ITelecomLoader telecomLoader = ITelecomLoader.Stub.asInterface(service); + ITelecomService telecomService = telecomLoader.createTelecomService(mServiceRepo); + SmsApplication.getDefaultMmsApplication(mContext, false); - ServiceManager.addService(Context.TELECOM_SERVICE, service); + ServiceManager.addService(Context.TELECOM_SERVICE, telecomService.asBinder()); synchronized (mLock) { final PermissionManagerServiceInternal permissionManager = @@ -114,6 +114,8 @@ public class TelecomLoaderService extends SystemService { @GuardedBy("mLock") private TelecomServiceConnection mServiceConnection; + private InternalServiceRepository mServiceRepo; + public TelecomLoaderService(Context context) { super(context); mContext = context; @@ -129,6 +131,8 @@ public class TelecomLoaderService extends SystemService { if (phase == PHASE_ACTIVITY_MANAGER_READY) { registerDefaultAppNotifier(); registerCarrierConfigChangedReceiver(); + // core services will have already been loaded. + setupServiceRepository(); connectToTelecom(); } } @@ -154,6 +158,11 @@ public class TelecomLoaderService extends SystemService { } } + private void setupServiceRepository() { + DeviceIdleInternal deviceIdleInternal = getLocalService(DeviceIdleInternal.class); + mServiceRepo = new InternalServiceRepository(deviceIdleInternal); + } + private void registerDefaultAppProviders() { final PermissionManagerServiceInternal permissionManager = diff --git a/telecomm/java/com/android/internal/telecom/IDeviceIdleControllerAdapter.aidl b/telecomm/java/com/android/internal/telecom/IDeviceIdleControllerAdapter.aidl new file mode 100644 index 000000000000..50bbf4c41284 --- /dev/null +++ b/telecomm/java/com/android/internal/telecom/IDeviceIdleControllerAdapter.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2020 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.internal.telecom; + +/* + * Adapter interface for using DeviceIdleController, since the PowerWhitelistManager is not + * directly accessible in the SYSTEM process. + */ +interface IDeviceIdleControllerAdapter { + void exemptAppTemporarilyForEvent(String packageName, long duration, int userHandle, + String reason); +} \ No newline at end of file diff --git a/telecomm/java/com/android/internal/telecom/IInternalServiceRetriever.aidl b/telecomm/java/com/android/internal/telecom/IInternalServiceRetriever.aidl new file mode 100644 index 000000000000..b56010696361 --- /dev/null +++ b/telecomm/java/com/android/internal/telecom/IInternalServiceRetriever.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 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.internal.telecom; + +import com.android.internal.telecom.IDeviceIdleControllerAdapter; + +/* + * Interface used to retrieve services that are only accessible via LocalService in the SYSTEM + * process. + */ +interface IInternalServiceRetriever { + IDeviceIdleControllerAdapter getDeviceIdleController(); +} diff --git a/telecomm/java/com/android/internal/telecom/ITelecomLoader.aidl b/telecomm/java/com/android/internal/telecom/ITelecomLoader.aidl new file mode 100644 index 000000000000..eda0f5b24958 --- /dev/null +++ b/telecomm/java/com/android/internal/telecom/ITelecomLoader.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 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.internal.telecom; + +import com.android.internal.telecom.ITelecomService; +import com.android.internal.telecom.IInternalServiceRetriever; + +/* + * Internal interface for getting an instance of the ITelecomService for external publication. + * Allows the TelecomLoaderService to pass additional dependencies required for creation. + */ +interface ITelecomLoader { + ITelecomService createTelecomService(IInternalServiceRetriever retriever); +} -- GitLab From 7ee68787cca0837f59658d5174e1d586dfe80ad4 Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Wed, 26 Aug 2020 14:42:08 -0700 Subject: [PATCH 356/536] Accept repeated locale as an input of LocaleList construction. Repeated locale has not been accepted and IllegalArgumentException is thrown. Instead of throwing exception, dropping repeated locale instead. Bug: 152410253 Test: atest LocaleListTest Change-Id: I80f243678ac3024eaeb0349f770cff897df7f332 --- core/java/android/os/LocaleList.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index ab4bb0b9f2cd..9c0bc45a346e 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -25,6 +25,7 @@ import android.icu.util.ULocale; import com.android.internal.annotations.GuardedBy; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -151,18 +152,18 @@ public final class LocaleList implements Parcelable { /** * Creates a new {@link LocaleList}. * + * If two or more same locales are passed, the repeated locales will be dropped. *

    For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()}, * which returns a pre-constructed empty list.

    * * @throws NullPointerException if any of the input locales is null. - * @throws IllegalArgumentException if any of the input locales repeat. */ public LocaleList(@NonNull Locale... list) { if (list.length == 0) { mList = sEmptyList; mStringRepresentation = ""; } else { - final Locale[] localeList = new Locale[list.length]; + final ArrayList localeList = new ArrayList<>(); final HashSet seenLocales = new HashSet(); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.length; i++) { @@ -170,10 +171,10 @@ public final class LocaleList implements Parcelable { if (l == null) { throw new NullPointerException("list[" + i + "] is null"); } else if (seenLocales.contains(l)) { - throw new IllegalArgumentException("list[" + i + "] is a repetition"); + // Dropping duplicated locale entries. } else { final Locale localeClone = (Locale) l.clone(); - localeList[i] = localeClone; + localeList.add(localeClone); sb.append(localeClone.toLanguageTag()); if (i < list.length - 1) { sb.append(','); @@ -181,7 +182,7 @@ public final class LocaleList implements Parcelable { seenLocales.add(localeClone); } } - mList = localeList; + mList = localeList.toArray(new Locale[localeList.size()]); mStringRepresentation = sb.toString(); } } -- GitLab From 3d25b3b9b4913e5bdc25dcbe51179276e4359ba8 Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Wed, 26 Aug 2020 14:42:08 -0700 Subject: [PATCH 357/536] Accept repeated locale as an input of LocaleList construction. Repeated locale has not been accepted and IllegalArgumentException is thrown. Instead of throwing exception, dropping repeated locale instead. Bug: 152410253 Test: atest LocaleListTest Change-Id: I80f243678ac3024eaeb0349f770cff897df7f332 --- core/java/android/os/LocaleList.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index 0de09efad8ea..32c608c93ba9 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -25,6 +25,7 @@ import android.icu.util.ULocale; import com.android.internal.annotations.GuardedBy; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -151,18 +152,18 @@ public final class LocaleList implements Parcelable { /** * Creates a new {@link LocaleList}. * + * If two or more same locales are passed, the repeated locales will be dropped. *

    For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()}, * which returns a pre-constructed empty list.

    * * @throws NullPointerException if any of the input locales is null. - * @throws IllegalArgumentException if any of the input locales repeat. */ public LocaleList(@NonNull Locale... list) { if (list.length == 0) { mList = sEmptyList; mStringRepresentation = ""; } else { - final Locale[] localeList = new Locale[list.length]; + final ArrayList localeList = new ArrayList<>(); final HashSet seenLocales = new HashSet(); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.length; i++) { @@ -170,10 +171,10 @@ public final class LocaleList implements Parcelable { if (l == null) { throw new NullPointerException("list[" + i + "] is null"); } else if (seenLocales.contains(l)) { - throw new IllegalArgumentException("list[" + i + "] is a repetition"); + // Dropping duplicated locale entries. } else { final Locale localeClone = (Locale) l.clone(); - localeList[i] = localeClone; + localeList.add(localeClone); sb.append(localeClone.toLanguageTag()); if (i < list.length - 1) { sb.append(','); @@ -181,7 +182,7 @@ public final class LocaleList implements Parcelable { seenLocales.add(localeClone); } } - mList = localeList; + mList = localeList.toArray(new Locale[localeList.size()]); mStringRepresentation = sb.toString(); } } -- GitLab From 33ee46389e535565ae6d827438ec1d7faef1368a Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Wed, 26 Aug 2020 14:42:08 -0700 Subject: [PATCH 358/536] Accept repeated locale as an input of LocaleList construction. Repeated locale has not been accepted and IllegalArgumentException is thrown. Instead of throwing exception, dropping repeated locale instead. Bug: 152410253 Test: atest LocaleListTest Change-Id: I80f243678ac3024eaeb0349f770cff897df7f332 --- core/java/android/os/LocaleList.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index 87e1b7d21f53..fbf28d7c2add 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -26,6 +26,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -171,18 +172,18 @@ public final class LocaleList implements Parcelable { /** * Creates a new {@link LocaleList}. * + * If two or more same locales are passed, the repeated locales will be dropped. *

    For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()}, * which returns a pre-constructed empty list.

    * * @throws NullPointerException if any of the input locales is null. - * @throws IllegalArgumentException if any of the input locales repeat. */ public LocaleList(@NonNull Locale... list) { if (list.length == 0) { mList = sEmptyList; mStringRepresentation = ""; } else { - final Locale[] localeList = new Locale[list.length]; + final ArrayList localeList = new ArrayList<>(); final HashSet seenLocales = new HashSet(); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.length; i++) { @@ -190,10 +191,10 @@ public final class LocaleList implements Parcelable { if (l == null) { throw new NullPointerException("list[" + i + "] is null"); } else if (seenLocales.contains(l)) { - throw new IllegalArgumentException("list[" + i + "] is a repetition"); + // Dropping duplicated locale entries. } else { final Locale localeClone = (Locale) l.clone(); - localeList[i] = localeClone; + localeList.add(localeClone); sb.append(localeClone.toLanguageTag()); if (i < list.length - 1) { sb.append(','); @@ -201,7 +202,7 @@ public final class LocaleList implements Parcelable { seenLocales.add(localeClone); } } - mList = localeList; + mList = localeList.toArray(new Locale[localeList.size()]); mStringRepresentation = sb.toString(); } } -- GitLab From 2cb650f9d0ea3767faf75a084bc9a566b2726234 Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Wed, 26 Aug 2020 14:42:08 -0700 Subject: [PATCH 359/536] Accept repeated locale as an input of LocaleList construction. Repeated locale has not been accepted and IllegalArgumentException is thrown. Instead of throwing exception, dropping repeated locale instead. Bug: 152410253 Test: atest LocaleListTest Change-Id: I80f243678ac3024eaeb0349f770cff897df7f332 --- core/java/android/os/LocaleList.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index 2dc3bebb2d10..e534f9d94d61 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -24,6 +24,7 @@ import android.icu.util.ULocale; import com.android.internal.annotations.GuardedBy; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -150,18 +151,18 @@ public final class LocaleList implements Parcelable { /** * Creates a new {@link LocaleList}. * + * If two or more same locales are passed, the repeated locales will be dropped. *

    For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()}, * which returns a pre-constructed empty list.

    * * @throws NullPointerException if any of the input locales is null. - * @throws IllegalArgumentException if any of the input locales repeat. */ public LocaleList(@NonNull Locale... list) { if (list.length == 0) { mList = sEmptyList; mStringRepresentation = ""; } else { - final Locale[] localeList = new Locale[list.length]; + final ArrayList localeList = new ArrayList<>(); final HashSet seenLocales = new HashSet(); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.length; i++) { @@ -169,10 +170,10 @@ public final class LocaleList implements Parcelable { if (l == null) { throw new NullPointerException("list[" + i + "] is null"); } else if (seenLocales.contains(l)) { - throw new IllegalArgumentException("list[" + i + "] is a repetition"); + // Dropping duplicated locale entries. } else { final Locale localeClone = (Locale) l.clone(); - localeList[i] = localeClone; + localeList.add(localeClone); sb.append(localeClone.toLanguageTag()); if (i < list.length - 1) { sb.append(','); @@ -180,7 +181,7 @@ public final class LocaleList implements Parcelable { seenLocales.add(localeClone); } } - mList = localeList; + mList = localeList.toArray(new Locale[localeList.size()]); mStringRepresentation = sb.toString(); } } -- GitLab From 142ce41bfadbbe984cb42484b98b1dddf4483c91 Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Wed, 26 Aug 2020 14:42:08 -0700 Subject: [PATCH 360/536] Accept repeated locale as an input of LocaleList construction. Repeated locale has not been accepted and IllegalArgumentException is thrown. Instead of throwing exception, dropping repeated locale instead. Bug: 152410253 Test: atest LocaleListTest Change-Id: I80f243678ac3024eaeb0349f770cff897df7f332 --- core/java/android/os/LocaleList.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index 2dc3bebb2d10..e534f9d94d61 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -24,6 +24,7 @@ import android.icu.util.ULocale; import com.android.internal.annotations.GuardedBy; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -150,18 +151,18 @@ public final class LocaleList implements Parcelable { /** * Creates a new {@link LocaleList}. * + * If two or more same locales are passed, the repeated locales will be dropped. *

    For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()}, * which returns a pre-constructed empty list.

    * * @throws NullPointerException if any of the input locales is null. - * @throws IllegalArgumentException if any of the input locales repeat. */ public LocaleList(@NonNull Locale... list) { if (list.length == 0) { mList = sEmptyList; mStringRepresentation = ""; } else { - final Locale[] localeList = new Locale[list.length]; + final ArrayList localeList = new ArrayList<>(); final HashSet seenLocales = new HashSet(); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.length; i++) { @@ -169,10 +170,10 @@ public final class LocaleList implements Parcelable { if (l == null) { throw new NullPointerException("list[" + i + "] is null"); } else if (seenLocales.contains(l)) { - throw new IllegalArgumentException("list[" + i + "] is a repetition"); + // Dropping duplicated locale entries. } else { final Locale localeClone = (Locale) l.clone(); - localeList[i] = localeClone; + localeList.add(localeClone); sb.append(localeClone.toLanguageTag()); if (i < list.length - 1) { sb.append(','); @@ -180,7 +181,7 @@ public final class LocaleList implements Parcelable { seenLocales.add(localeClone); } } - mList = localeList; + mList = localeList.toArray(new Locale[localeList.size()]); mStringRepresentation = sb.toString(); } } -- GitLab From 9b1d701af461899a03b046dbf97316abc1465ac3 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Sun, 30 Dec 2018 17:59:59 -0800 Subject: [PATCH 361/536] [CS] Add an option to block sensitive network specifier Network specifiers are used for 2 purposes: - As part of network requests to specify more information on the type of requested networks. - On network agents to specify information about their networks. The network specifiers of the requests and agents are matched to each other. However, the agent network specifier may contain sensitive information which we do not want forwarded to any app. This CL adds an option to strip out this agent network specifier before the network capabilities are forwarded to the app. Bug: 161853197 Bug: 161370134 Test: atest ConnectivityServiceTest (frameworks/base/tests/net) Test: atest frameworks/base/tests/net Test: atest frameworks/opt/net/wifi/tests/wifitests Test: atest frameworks/opt/telephony/tests/telephonytests Test: atest frameworks/opt/net/ethernet/tests Test: atest android.net.cts - some flakiness! Test: act.py ThroughputTest Test: act.py DataPathTest Test: atest SingleDeviceTest (cts) Change-Id: I38ed3ff88532ef522ab167c88d87e6e82295ffc5 Merged-In: If08d312ff814bdde1147518f923199e6349503d5 --- core/java/android/net/NetworkSpecifier.java | 27 ++++- .../android/server/ConnectivityService.java | 6 +- .../server/ConnectivityServiceTest.java | 109 ++++++++++++++++-- 3 files changed, 129 insertions(+), 13 deletions(-) diff --git a/core/java/android/net/NetworkSpecifier.java b/core/java/android/net/NetworkSpecifier.java index be2f9551daff..fcfb72035c19 100644 --- a/core/java/android/net/NetworkSpecifier.java +++ b/core/java/android/net/NetworkSpecifier.java @@ -17,7 +17,7 @@ package android.net; /** - * Describes specific properties of a network for use in a {@link NetworkRequest}. + * Describes specific properties of a requested network for use in a {@link NetworkRequest}. * * Applications cannot instantiate this class by themselves, but can obtain instances of * subclasses of this class via other APIs. @@ -49,4 +49,29 @@ public abstract class NetworkSpecifier { public void assertValidFromUid(int requestorUid) { // empty } + + /** + * Optional method which can be overridden by concrete implementations of NetworkSpecifier to + * perform any redaction of information from the NetworkSpecifier, e.g. if it contains + * sensitive information. The default implementation simply returns the object itself - i.e. + * no information is redacted. A concrete implementation may return a modified (copy) of the + * NetworkSpecifier, or even return a null to fully remove all information. + *

    + * This method is relevant to NetworkSpecifier objects used by agents - those are shared with + * apps by default. Some agents may store sensitive matching information in the specifier, + * e.g. a Wi-Fi SSID (which should not be shared since it may leak location). Those classes + * can redact to a null. Other agents use the Network Specifier to share public information + * with apps - those should not be redacted. + *

    + * The default implementation redacts no information. + * + * @return A NetworkSpecifier object to be passed along to the requesting app. + * + * @hide + */ + public NetworkSpecifier redact() { + // TODO (b/122160111): convert default to null once all platform NetworkSpecifiers + // implement this method. + return this; + } } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index b71fabae7ffe..5602d6f9acf0 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1433,6 +1433,9 @@ public class ConnectivityService extends IConnectivityManager.Stub newNc.setUids(null); newNc.setSSID(null); } + if (newNc.getNetworkSpecifier() != null) { + newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact()); + } return newNc; } @@ -5145,7 +5148,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } switch (notificationType) { case ConnectivityManager.CALLBACK_AVAILABLE: { - putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities)); + putParcelable(bundle, networkCapabilitiesRestrictedForCallerPermissions( + networkAgent.networkCapabilities, nri.mPid, nri.mUid)); putParcelable(bundle, new LinkProperties(networkAgent.linkProperties)); break; } diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 6ceed53f4ef8..719ce01eca31 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -113,7 +113,6 @@ import android.net.NetworkSpecifier; import android.net.NetworkState; import android.net.NetworkUtils; import android.net.RouteInfo; -import android.net.StringNetworkSpecifier; import android.net.UidRange; import android.net.VpnService; import android.net.captiveportal.CaptivePortalProbeResult; @@ -135,6 +134,7 @@ import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.test.mock.MockContentResolver; +import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; @@ -2495,16 +2495,76 @@ public class ConnectivityServiceTest { return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI); } + /** + * Verify request matching behavior with network specifiers. + * + * Note: this test is somewhat problematic since it involves removing capabilities from + * agents - i.e. agents rejecting requests which they previously accepted. This is flagged + * as a WTF bug in + * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)} but + * does work. + */ @Test public void testNetworkSpecifier() { + // A NetworkSpecifier subclass that matches all networks but must not be visible to apps. + class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements + Parcelable { + @Override + public boolean satisfiedBy(NetworkSpecifier other) { + return true; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) {} + + @Override + public NetworkSpecifier redact() { + return null; + } + } + + // A network specifier that matches either another LocalNetworkSpecifier with the same + // string or a ConfidentialMatchAllNetworkSpecifier, and can be passed to apps as is. + class LocalStringNetworkSpecifier extends NetworkSpecifier implements Parcelable { + private String mString; + + LocalStringNetworkSpecifier(String string) { + mString = string; + } + + @Override + public boolean satisfiedBy(NetworkSpecifier other) { + if (other instanceof LocalStringNetworkSpecifier) { + return TextUtils.equals(mString, + ((LocalStringNetworkSpecifier) other).mString); + } + if (other instanceof ConfidentialMatchAllNetworkSpecifier) return true; + return false; + } + + @Override + public int describeContents() { + return 0; + } + @Override + public void writeToParcel(Parcel dest, int flags) {} + } + + NetworkRequest rEmpty1 = newWifiRequestBuilder().build(); NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build(); NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build(); NetworkRequest rEmpty4 = newWifiRequestBuilder().setNetworkSpecifier( (NetworkSpecifier) null).build(); - NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier("foo").build(); + NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier( + new LocalStringNetworkSpecifier("foo")).build(); NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier( - new StringNetworkSpecifier("bar")).build(); + new LocalStringNetworkSpecifier("bar")).build(); TestNetworkCallback cEmpty1 = new TestNetworkCallback(); TestNetworkCallback cEmpty2 = new TestNetworkCallback(); @@ -2513,7 +2573,7 @@ public class ConnectivityServiceTest { TestNetworkCallback cFoo = new TestNetworkCallback(); TestNetworkCallback cBar = new TestNetworkCallback(); TestNetworkCallback[] emptyCallbacks = new TestNetworkCallback[] { - cEmpty1, cEmpty2, cEmpty3 }; + cEmpty1, cEmpty2, cEmpty3, cEmpty4 }; mCm.registerNetworkCallback(rEmpty1, cEmpty1); mCm.registerNetworkCallback(rEmpty2, cEmpty2); @@ -2522,6 +2582,9 @@ public class ConnectivityServiceTest { mCm.registerNetworkCallback(rFoo, cFoo); mCm.registerNetworkCallback(rBar, cBar); + LocalStringNetworkSpecifier nsFoo = new LocalStringNetworkSpecifier("foo"); + LocalStringNetworkSpecifier nsBar = new LocalStringNetworkSpecifier("bar"); + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); mWiFiNetworkAgent.connect(false); cEmpty1.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); @@ -2530,30 +2593,54 @@ public class ConnectivityServiceTest { cEmpty4.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); assertNoCallbacks(cFoo, cBar); - mWiFiNetworkAgent.setNetworkSpecifier(new StringNetworkSpecifier("foo")); + mWiFiNetworkAgent.setNetworkSpecifier(nsFoo); cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); for (TestNetworkCallback c: emptyCallbacks) { - c.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent); + c.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsFoo), + mWiFiNetworkAgent); } - cFoo.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent); + cFoo.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsFoo), + mWiFiNetworkAgent); + assertEquals(nsFoo, + mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); cFoo.assertNoCallback(); - mWiFiNetworkAgent.setNetworkSpecifier(new StringNetworkSpecifier("bar")); + mWiFiNetworkAgent.setNetworkSpecifier(nsBar); cFoo.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); cBar.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); for (TestNetworkCallback c: emptyCallbacks) { - c.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent); + c.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsBar), + mWiFiNetworkAgent); } - cBar.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent); + cBar.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsBar), + mWiFiNetworkAgent); + assertEquals(nsBar, + mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); + cBar.assertNoCallback(); + + mWiFiNetworkAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier()); + cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); + for (TestNetworkCallback c : emptyCallbacks) { + c.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier() == null, + mWiFiNetworkAgent); + } + cFoo.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier() == null, + mWiFiNetworkAgent); + cBar.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier() == null, + mWiFiNetworkAgent); + assertNull( + mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier()); + cFoo.assertNoCallback(); cBar.assertNoCallback(); mWiFiNetworkAgent.setNetworkSpecifier(null); + cFoo.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); cBar.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); for (TestNetworkCallback c: emptyCallbacks) { c.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent); } - assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cFoo, cBar); + assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); } @Test -- GitLab From 2227e0fb0aa5fbaf90d38b8dfcecd92dfcdb14ce Mon Sep 17 00:00:00 2001 From: SongFerng Wang Date: Wed, 2 Sep 2020 05:51:42 +0000 Subject: [PATCH 362/536] Merge "Add the Verizon 5G UW icon and string" am: 8d534f80c9 am: eae34dbebf am: 95c9d36dd4 am: 4faca86ae0 am: 46b1601683 Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1417008 Bug: 149357400 Change-Id: I504cb49e70352c178c8ece4490b169e3cf971390 (cherry picked from commit 0c18b916310ba4c5d354a62db06e6d49371fe105) --- .../ic_5g_plus_mobiledata.xml | 36 +++++++++++++++++++ .../ic_5g_plus_mobiledata.xml | 36 +++++++++++++++++++ .../res/values-mcc310-mnc004/strings.xml | 22 ++++++++++++ .../res/values-mcc311-mnc480/strings.xml | 22 ++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 packages/SystemUI/res/drawable-mcc310-mnc004/ic_5g_plus_mobiledata.xml create mode 100644 packages/SystemUI/res/drawable-mcc311-mnc480/ic_5g_plus_mobiledata.xml create mode 100644 packages/SystemUI/res/values-mcc310-mnc004/strings.xml create mode 100644 packages/SystemUI/res/values-mcc311-mnc480/strings.xml diff --git a/packages/SystemUI/res/drawable-mcc310-mnc004/ic_5g_plus_mobiledata.xml b/packages/SystemUI/res/drawable-mcc310-mnc004/ic_5g_plus_mobiledata.xml new file mode 100644 index 000000000000..998db3b44b19 --- /dev/null +++ b/packages/SystemUI/res/drawable-mcc310-mnc004/ic_5g_plus_mobiledata.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + diff --git a/packages/SystemUI/res/drawable-mcc311-mnc480/ic_5g_plus_mobiledata.xml b/packages/SystemUI/res/drawable-mcc311-mnc480/ic_5g_plus_mobiledata.xml new file mode 100644 index 000000000000..998db3b44b19 --- /dev/null +++ b/packages/SystemUI/res/drawable-mcc311-mnc480/ic_5g_plus_mobiledata.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + diff --git a/packages/SystemUI/res/values-mcc310-mnc004/strings.xml b/packages/SystemUI/res/values-mcc310-mnc004/strings.xml new file mode 100644 index 000000000000..f8ed0c01fa83 --- /dev/null +++ b/packages/SystemUI/res/values-mcc310-mnc004/strings.xml @@ -0,0 +1,22 @@ + + + + + 5G UW + diff --git a/packages/SystemUI/res/values-mcc311-mnc480/strings.xml b/packages/SystemUI/res/values-mcc311-mnc480/strings.xml new file mode 100644 index 000000000000..f8ed0c01fa83 --- /dev/null +++ b/packages/SystemUI/res/values-mcc311-mnc480/strings.xml @@ -0,0 +1,22 @@ + + + + + 5G UW + -- GitLab From dfc8abb1ffc7bf6c7d7b47cf2e9e14bf6422f95c Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Thu, 13 Aug 2020 22:43:52 +0800 Subject: [PATCH 363/536] Update requested state after applying pending frames When there is an insets animation, we will stop updating insets source frames until the animation is done. The previous logic didn't update the frames within the requested state while the animation is done. And the frames was relied by InsetsPolicy while playing transient bar animation. If the frames don't match the display, the insets would be wrong, and the animation wouldn't be played correctly. Fix: 161134197 Test: atest InsetsControllerTest Merged-In: Id8f3c1956fbfe3ad16f167ff76297dde6c634e81 Change-Id: Id8f3c1956fbfe3ad16f167ff76297dde6c634e81 (cherry picked from commit 23c75281ef0de8fb2b44fb93d8cf36ecf86454c7) --- core/java/android/view/InsetsController.java | 9 ++++++--- .../src/android/view/InsetsControllerTest.java | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index c383bc7a4d70..985829f6c885 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -1134,15 +1134,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (invokeCallback) { control.cancel(); } + boolean stateChanged = false; for (int i = mRunningAnimations.size() - 1; i >= 0; i--) { RunningAnimation runningAnimation = mRunningAnimations.get(i); if (runningAnimation.runner == control) { mRunningAnimations.remove(i); ArraySet types = toInternalType(control.getTypes()); for (int j = types.size() - 1; j >= 0; j--) { - if (getSourceConsumer(types.valueAt(j)).notifyAnimationFinished()) { - mHost.notifyInsetsChanged(); - } + stateChanged |= getSourceConsumer(types.valueAt(j)).notifyAnimationFinished(); } if (invokeCallback && runningAnimation.startDispatched) { dispatchAnimationEnd(runningAnimation.runner.getAnimation()); @@ -1150,6 +1149,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation break; } } + if (stateChanged) { + mHost.notifyInsetsChanged(); + updateRequestedState(); + } } private void applyLocalVisibilityOverride() { diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index 801cd4ddb94e..48695aa5a329 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -27,6 +27,7 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; import static android.view.WindowInsets.Type.ime; +import static android.view.WindowInsets.Type.navigationBars; import static android.view.WindowInsets.Type.statusBars; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; @@ -742,6 +743,20 @@ public class InsetsControllerTest { mController.onControlsChanged(createSingletonControl(ITYPE_IME)); assertEquals(newState.getSource(ITYPE_IME), mTestHost.getModifiedState().peekSource(ITYPE_IME)); + + // The modified frames cannot be updated if there is an animation. + mController.onControlsChanged(createSingletonControl(ITYPE_NAVIGATION_BAR)); + mController.hide(navigationBars()); + newState = new InsetsState(mController.getState(), true /* copySource */); + newState.getSource(ITYPE_NAVIGATION_BAR).getFrame().top--; + mController.onStateChanged(newState); + assertNotEquals(newState.getSource(ITYPE_NAVIGATION_BAR), + mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR)); + + // The modified frames can be updated while the animation is done. + mController.cancelExistingAnimations(); + assertEquals(newState.getSource(ITYPE_NAVIGATION_BAR), + mTestHost.getModifiedState().peekSource(ITYPE_NAVIGATION_BAR)); }); } -- GitLab From decfef24ccdce911e8d710548d27d5f6dd10bfb2 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 7 Sep 2020 13:39:10 +0000 Subject: [PATCH 364/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Icad4fe50fecb100674285d2a8f74201a0d706a15 --- packages/SystemUI/res/values-ar/strings.xml | 12 ++++++------ packages/SystemUI/res/values-ca/strings.xml | 2 +- packages/SystemUI/res/values-el/strings.xml | 2 +- packages/SystemUI/res/values-es/strings.xml | 2 +- packages/SystemUI/res/values-fa/strings.xml | 2 +- packages/SystemUI/res/values-hu/strings.xml | 2 +- packages/SystemUI/res/values-pl/strings.xml | 2 +- packages/SystemUI/res/values-sq/strings.xml | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index f906cf2a8f93..5fa5dc332c7a 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -232,7 +232,7 @@ "لم يتم الضبط على استخدام البيانات" "غير مفعّلة" "التوصيل عبر البلوتوث" - "وضع الطائرة." + "وضع الطيران." "‏الشبكة الافتراضية الخاصة (VPN) قيد التفعيل." "‏ليس هناك شريحة SIM." "جارٍ تغيير شبكة مشغِّل شبكة الجوّال." @@ -267,10 +267,10 @@ "‏تم تفعيل Wifi." "الجوّال %1$s. %2$s. %3$s." "البطارية %s." - "إيقاف وضع الطائرة." - "تفعيل وضع الطائرة." - "تم إيقاف وضع الطائرة." - "تم تفعيل وضع الطائرة." + "إيقاف وضع الطيران." + "تفعيل وضع الطيران." + "تم إيقاف وضع الطيران." + "تم تفعيل وضع الطيران." "كتم الصوت تمامًا" "المنبِّهات فقط" "عدم الإزعاج" @@ -664,7 +664,7 @@ "إيثرنت" "المنبّه" "الملف الشخصي للعمل" - "وضع الطائرة" + "وضع الطيران" "إضافة فئة" "إرسال فئة" "لن تسمع المنبّه القادم في %1$s إلا إذا أوقفت هذا قبل الموعد" diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 78ab320b6556..529e37a59e07 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -707,7 +707,7 @@ "Desactiva les notificacions" "Vols continuar rebent notificacions d\'aquesta aplicació?" "Silenci" - "Predeterminada" + "Predeterminat" "Bombolla" "Sense so ni vibració" "Sense so ni vibració i es mostra més avall a la secció de converses" diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 32b335ec480a..4137f8e75a26 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -691,7 +691,7 @@ "Αυτές οι ειδοποιήσεις θα ελαχιστοποιηθούν" "Αυτές οι ειδοποιήσεις θα εμφανίζονται σιωπηλά" "Αυτές οι ειδοποιήσεις θα σας ενημερώνουν" - "Συνήθως απορρίπτετε αυτές τις ειδοποιήσεις. \nΝα εξακολουθήσουν να εμφανίζονται;" + "Συνήθως παραβλέπετε αυτές τις ειδοποιήσεις. \nΝα εξακολουθήσουν να εμφανίζονται;" "Τέλος" "Εφαρμογή" "Να συνεχίσουν να εμφανίζονται αυτές οι ειδοποιήσεις;" diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 3cbf9a174fcf..135bfaa71349 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -98,7 +98,7 @@ "Sonido de tu dispositivo, como música, llamadas y tonos de llamada" "Micrófono" "Audio y micrófono del dispositivo" - "Empezar" + "Iniciar" "Grabando pantalla" "Grabando pantalla y audio" "Mostrar toques en la pantalla" diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 703d5ec070eb..410edfb74eb7 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -800,7 +800,7 @@ "برگشت" "اعلان‌ها" "میان‌برهای صفحه‌کلید" - "تغییر طرح‌بندی صفحه‌کلید" + "تغییر جانمایی صفحه‌کلید" "برنامه‌ها" "دستیار" "مرورگر" diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index f01ac1da64bd..05cf98431759 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -428,7 +428,7 @@ "Az NFC ki van kapcsolva" "Az NFC be van kapcsolva" "Képernyő rögzítése" - "Kezdés" + "Indítás" "Leállítás" "Eszköz" "Váltás az alkalmazások között felfelé csúsztatással" diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 443c8f15f400..5d7a6a18acb4 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -1021,7 +1021,7 @@ "Przenieś w lewy dolny róg" "Przenieś w prawy dolny róg" "Zamknij dymek" - "Nie wyświetlaj rozmowy jako dymku" + "Nie wyświetlaj rozmowy jako dymka" "Czatuj, korzystając z dymków" "Nowe rozmowy będą wyświetlane jako pływające ikony lub dymki. Kliknij, by otworzyć dymek. Przeciągnij, by go przenieść." "Zarządzaj dymkami w dowolnym momencie" diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 97fb0323c947..60ef3a2561b2 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -480,7 +480,7 @@ "Mirë se erdhe, i ftuar!" "Dëshiron ta vazhdosh sesionin tënd?" "Fillo nga e para" - "Po, vazhdo!" + "Po, vazhdo" "Përdorues vizitor" "Për të fshirë aplikacionet dhe të dhënat, hiqe përdoruesin vizitor" "HIQ VIZITORIN" -- GitLab From 631291cd32f461f5959b1c6ed8339397fd576330 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Wed, 19 Aug 2020 15:39:00 +0100 Subject: [PATCH 365/536] Revert "Add updatable-media jarjar rules to framework-all" We no longer need this jarjar rule because we are not re-compiling exoplayer. This reverts commit f92d07e5f95c9ae0a0248a0b99dcb736da2a1272. Bug: 149906971 Test: m && \ unzip -l out/soong/.intermediates/frameworks/base/framework-all/\ android_common/combined/framework-all.jar \ | grep exo \ | grep -v internal (no exoplayer classes) Change-Id: Ic4d7847875797be47e02987337bf685bfe1e6605 --- framework-jarjar-rules.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/framework-jarjar-rules.txt b/framework-jarjar-rules.txt index 70dedb8179b0..d8af726ffa72 100644 --- a/framework-jarjar-rules.txt +++ b/framework-jarjar-rules.txt @@ -1,6 +1,2 @@ rule android.hidl.** android.internal.hidl.@1 rule android.net.wifi.WifiAnnotations* android.internal.wifi.WifiAnnotations@1 - -# Hide media mainline module implementation classes to avoid collisions with -# app-bundled ExoPlayer classes. -rule com.google.android.exoplayer2.** android.media.internal.exo.@1 -- GitLab From 41c59babd51dfb26171365e7aa51942f1794c7c3 Mon Sep 17 00:00:00 2001 From: paulhu Date: Tue, 8 Sep 2020 11:19:01 +0800 Subject: [PATCH 366/536] Add CONNECTIVITY_USE_RESTRICTED_NETWORKS permission to DownloadProvider - DownloadManager will use the requestor app's default network to open a connection. When the VPN app lists the DownloadProvider as a disallowed application, this will fail with EPERM. - This is because in R, the DownloadProvider lost its privileges due to the removal of the CONNECTIVITY_INTERNAL permission. It's removed without considering the corner case where the DownloadProvider is excluded from using the VPN. It's the only case where this makes a difference. - Adding CONNECTIVITY_USE_RESTRICTED_NETWORKS will give DownloadProvider the ability to use the VPN again in this case, fixing the issue. Bug: 165774987 Test: Build, flash rom and boot to home. Manully test that DownloadProvider can download file via VPN. Change-Id: If8fa785568ace1f15f53daec67c06e1207d5dc9c --- data/etc/privapp-permissions-platform.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index e08e42aec391..5f34a5eb58a1 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -224,6 +224,7 @@ applications that come with the platform + -- GitLab From 27c52fcaa8f7c649be01763443df21f7dffeb028 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Tue, 8 Sep 2020 14:39:38 +0200 Subject: [PATCH 367/536] Don't kill for REQUEST_INSTALL_PACKAGES on default/error mode transition. When handling unknown sources, PackageManager transitions from MODE_DEFAULT to MODE_ERRORED, causing us to kill the app before the user has even decided whether to allow external sources or not. Since MODE_DEFAULT and MODE_ERRORED are the same from a storage point of view, ignore transitions between the two. This required some AppOps changes to store the previous mode and pass it in. Bug: 162849988 Test: run Epic installer Change-Id: Ic866216f877e9b727fe70556f66dd998966fe0a2 Merged-In: Ic866216f877e9b727fe70556f66dd998966fe0a2 --- .../os/storage/StorageManagerInternal.java | 2 +- .../android/server/StorageManagerService.java | 11 +++-- .../android/server/appop/AppOpsService.java | 44 ++++++++++++------- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java index e05991b33796..a79a1cfcd64f 100644 --- a/core/java/android/os/storage/StorageManagerInternal.java +++ b/core/java/android/os/storage/StorageManagerInternal.java @@ -118,7 +118,7 @@ public abstract class StorageManagerInternal { * affects them. */ public abstract void onAppOpsChanged(int code, int uid, - @Nullable String packageName, int mode); + @Nullable String packageName, int mode, int previousMode); /** * Asks the StorageManager to reset all state for the provided user; this will result diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 678387c540ed..391923324d0c 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -4745,15 +4745,20 @@ class StorageManagerService extends IStorageManager.Stub } } - public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode) { + public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode, + int previousMode) { final long token = Binder.clearCallingIdentity(); try { if (mIsFuseEnabled) { // When using FUSE, we may need to kill the app if the op changes switch(code) { case OP_REQUEST_INSTALL_PACKAGES: - // Always kill regardless of op change, to remount apps /storage - killAppForOpChange(code, uid); + if (previousMode == MODE_ALLOWED || mode == MODE_ALLOWED) { + // If we transition to/from MODE_ALLOWED, kill the app to make + // sure it has the correct view of /storage. Changing between + // MODE_DEFAULT / MODE_ERRORED is a no-op + killAppForOpChange(code, uid); + } return; case OP_MANAGE_EXTERNAL_STORAGE: if (mode != MODE_ALLOWED) { diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index c5bdb9edd069..600069335dbc 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -2198,6 +2198,7 @@ public class AppOpsService extends IAppOpsService.Stub { updatePermissionRevokedCompat(uid, code, mode); } + int previousMode; synchronized (this) { final int defaultMode = AppOpsManager.opToDefaultMode(code); @@ -2206,12 +2207,14 @@ public class AppOpsService extends IAppOpsService.Stub { if (mode == defaultMode) { return; } + previousMode = AppOpsManager.MODE_DEFAULT; uidState = new UidState(uid); uidState.opModes = new SparseIntArray(); uidState.opModes.put(code, mode); mUidStates.put(uid, uidState); scheduleWriteLocked(); } else if (uidState.opModes == null) { + previousMode = AppOpsManager.MODE_DEFAULT; if (mode != defaultMode) { uidState.opModes = new SparseIntArray(); uidState.opModes.put(code, mode); @@ -2221,6 +2224,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (uidState.opModes.indexOfKey(code) >= 0 && uidState.opModes.get(code) == mode) { return; } + previousMode = uidState.opModes.get(code); if (mode == defaultMode) { uidState.opModes.delete(code); if (uidState.opModes.size() <= 0) { @@ -2235,7 +2239,7 @@ public class AppOpsService extends IAppOpsService.Stub { } notifyOpChangedForAllPkgsInUid(code, uid, false, permissionPolicyCallback); - notifyOpChangedSync(code, uid, null, mode); + notifyOpChangedSync(code, uid, null, mode, previousMode); } /** @@ -2414,11 +2418,12 @@ public class AppOpsService extends IAppOpsService.Stub { } } - private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode) { + private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode, + int previousMode) { final StorageManagerInternal storageManagerInternal = LocalServices.getService(StorageManagerInternal.class); if (storageManagerInternal != null) { - storageManagerInternal.onAppOpsChanged(code, uid, packageName, mode); + storageManagerInternal.onAppOpsChanged(code, uid, packageName, mode, previousMode); } } @@ -2450,11 +2455,13 @@ public class AppOpsService extends IAppOpsService.Stub { return; } + int previousMode = AppOpsManager.MODE_DEFAULT; synchronized (this) { UidState uidState = getUidStateLocked(uid, false); Op op = getOpLocked(code, uid, packageName, null, bypass, true); if (op != null) { if (op.mode != mode) { + previousMode = op.mode; op.mode = mode; if (uidState != null) { uidState.evalForegroundOps(mOpModeWatchers); @@ -2491,7 +2498,7 @@ public class AppOpsService extends IAppOpsService.Stub { this, repCbs, code, uid, packageName)); } - notifyOpChangedSync(code, uid, packageName, mode); + notifyOpChangedSync(code, uid, packageName, mode, previousMode); } private void notifyOpChanged(ArraySet callbacks, int code, @@ -2534,7 +2541,7 @@ public class AppOpsService extends IAppOpsService.Stub { } private static ArrayList addChange(ArrayList reports, - int op, int uid, String packageName) { + int op, int uid, String packageName, int previousMode) { boolean duplicate = false; if (reports == null) { reports = new ArrayList<>(); @@ -2549,7 +2556,7 @@ public class AppOpsService extends IAppOpsService.Stub { } } if (!duplicate) { - reports.add(new ChangeRec(op, uid, packageName)); + reports.add(new ChangeRec(op, uid, packageName, previousMode)); } return reports; @@ -2557,7 +2564,7 @@ public class AppOpsService extends IAppOpsService.Stub { private static HashMap> addCallbacks( HashMap> callbacks, - int op, int uid, String packageName, ArraySet cbs) { + int op, int uid, String packageName, int previousMode, ArraySet cbs) { if (cbs == null) { return callbacks; } @@ -2568,7 +2575,7 @@ public class AppOpsService extends IAppOpsService.Stub { for (int i=0; i reports = callbacks.get(cb); - ArrayList changed = addChange(reports, op, uid, packageName); + ArrayList changed = addChange(reports, op, uid, packageName, previousMode); if (changed != reports) { callbacks.put(cb, changed); } @@ -2580,11 +2587,13 @@ public class AppOpsService extends IAppOpsService.Stub { final int op; final int uid; final String pkg; + final int previous_mode; - ChangeRec(int _op, int _uid, String _pkg) { + ChangeRec(int _op, int _uid, String _pkg, int _previous_mode) { op = _op; uid = _uid; pkg = _pkg; + previous_mode = _previous_mode; } } @@ -2620,18 +2629,19 @@ public class AppOpsService extends IAppOpsService.Stub { for (int j = uidOpCount - 1; j >= 0; j--) { final int code = opModes.keyAt(j); if (AppOpsManager.opAllowsReset(code)) { + int previousMode = opModes.valueAt(j); opModes.removeAt(j); if (opModes.size() <= 0) { uidState.opModes = null; } for (String packageName : getPackagesForUid(uidState.uid)) { callbacks = addCallbacks(callbacks, code, uidState.uid, packageName, - mOpModeWatchers.get(code)); + previousMode, mOpModeWatchers.get(code)); callbacks = addCallbacks(callbacks, code, uidState.uid, packageName, - mPackageModeWatchers.get(packageName)); + previousMode, mPackageModeWatchers.get(packageName)); allChanges = addChange(allChanges, code, uidState.uid, - packageName); + packageName, previousMode); } } } @@ -2662,16 +2672,18 @@ public class AppOpsService extends IAppOpsService.Stub { Op curOp = pkgOps.valueAt(j); if (AppOpsManager.opAllowsReset(curOp.op) && curOp.mode != AppOpsManager.opToDefaultMode(curOp.op)) { + int previousMode = curOp.mode; curOp.mode = AppOpsManager.opToDefaultMode(curOp.op); changed = true; uidChanged = true; final int uid = curOp.uidState.uid; callbacks = addCallbacks(callbacks, curOp.op, uid, packageName, - mOpModeWatchers.get(curOp.op)); + previousMode, mOpModeWatchers.get(curOp.op)); callbacks = addCallbacks(callbacks, curOp.op, uid, packageName, - mPackageModeWatchers.get(packageName)); + previousMode, mPackageModeWatchers.get(packageName)); - allChanges = addChange(allChanges, curOp.op, uid, packageName); + allChanges = addChange(allChanges, curOp.op, uid, packageName, + previousMode); curOp.removeAttributionsWithNoTime(); if (curOp.mAttributions.isEmpty()) { pkgOps.removeAt(j); @@ -2712,7 +2724,7 @@ public class AppOpsService extends IAppOpsService.Stub { for (int i = 0; i < numChanges; i++) { ChangeRec change = allChanges.get(i); notifyOpChangedSync(change.op, change.uid, change.pkg, - AppOpsManager.opToDefaultMode(change.op)); + AppOpsManager.opToDefaultMode(change.op), change.previous_mode); } } } -- GitLab From f6f287a1efc76ef90e8caea952fffee862359015 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Wed, 26 Aug 2020 17:07:53 -0400 Subject: [PATCH 368/536] DO NOT MERGE Sanitize more of the notification text fields Test: manual; monitor SystemUI performance when an app tries to post a messaging style notification with messages with long text Bug: 158304295 Bug: 147358092 Merged-In: c953fdf6bc498ca791aed49df04e5a07c935b63a Change-Id: I0e2ea12fc3351b1a56645b556720ea2306f5422a (cherry picked from commit c953fdf6bc498ca791aed49df04e5a07c935b63a) --- core/java/android/app/Notification.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 4a794c9b8c06..985b559201d0 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -184,7 +184,7 @@ public class Notification implements Parcelable *

    * Avoids spamming the system with overly large strings such as full e-mails. */ - private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024; + private static final int MAX_CHARSEQUENCE_LENGTH = 1024; /** * Maximum entries of reply text that are accepted by Builder and friends. @@ -6278,7 +6278,7 @@ public class Notification implements Parcelable * consistent during re-posts of the notification. */ public Message(CharSequence text, long timestamp, CharSequence sender){ - mText = text; + mText = safeCharSequence(text); mTimestamp = timestamp; mSender = sender; } @@ -6367,7 +6367,7 @@ public class Notification implements Parcelable } bundle.putLong(KEY_TIMESTAMP, mTimestamp); if (mSender != null) { - bundle.putCharSequence(KEY_SENDER, mSender); + bundle.putCharSequence(KEY_SENDER, safeCharSequence(mSender)); } if (mDataMimeType != null) { bundle.putString(KEY_DATA_MIME_TYPE, mDataMimeType); -- GitLab From 15a5b1cd9c5d89efc246e7f23cc0a00e1d2cb5f4 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Thu, 20 Aug 2020 13:55:17 -0400 Subject: [PATCH 369/536] Check ServiceState when showing dialog When showing the dialog the first time cellular data is turned off from QS, check if the data network is in service. If it's not, do not believe the carrier name and use a generic string instead. Test: atest NetworkControllerDataTest Bug: 156238588 Change-Id: Iee8091921ecdaba0c18f67080348240b8b8f67a7 Merged-In: Iee8091921ecdaba0c18f67080348240b8b8f67a7 (cherry picked from commit 15012a9acbdb3027a8683a85fd225d8265482827) --- .../systemui/qs/tiles/CellularTile.java | 3 ++- .../policy/MobileSignalController.java | 4 ++++ .../statusbar/policy/NetworkController.java | 1 + .../policy/NetworkControllerImpl.java | 6 +++++ .../policy/NetworkControllerDataTest.java | 22 +++++++++++++++++++ .../utils/leaks/FakeNetworkController.java | 5 +++++ 6 files changed, 40 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index bc03ca617dea..59597ac29e09 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -117,7 +117,8 @@ public class CellularTile extends QSTileImpl { return; } String carrierName = mController.getMobileDataNetworkName(); - if (TextUtils.isEmpty(carrierName)) { + boolean isInService = mController.isMobileDataNetworkInService(); + if (TextUtils.isEmpty(carrierName) || !isInService) { carrierName = mContext.getString(R.string.mobile_data_disable_message_default_carrier); } AlertDialog dialog = new Builder(mContext) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index cf83603997c0..eb2d9bce6c4e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -418,6 +418,10 @@ public class MobileSignalController extends SignalController< return (mServiceState != null && mServiceState.isEmergencyOnly()); } + public boolean isInService() { + return Utils.isInService(mServiceState); + } + private boolean isRoaming() { // During a carrier change, roaming indications need to be supressed. if (isCarrierNetworkChangeActive()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index 95a97729936b..1dbb228f58b5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -37,6 +37,7 @@ public interface NetworkController extends CallbackController, D DataUsageController getMobileDataController(); DataSaverController getDataSaverController(); String getMobileDataNetworkName(); + boolean isMobileDataNetworkInService(); int getNumberSubscriptions(); boolean hasVoiceCallingFeature(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index f41a27cf4c64..5b3c3a38c568 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -444,6 +444,12 @@ public class NetworkControllerImpl extends BroadcastReceiver return controller != null ? controller.getState().networkNameData : ""; } + @Override + public boolean isMobileDataNetworkInService() { + MobileSignalController controller = getDataController(); + return controller != null && controller.isInService(); + } + @Override public int getNumberSubscriptions() { return mMobileSignalControllers.size(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java index 6fffcff41a4f..56598f7a5bfd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java @@ -3,6 +3,8 @@ package com.android.systemui.statusbar.policy; import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN; import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -10,6 +12,7 @@ import static org.mockito.Mockito.when; import android.net.NetworkCapabilities; import android.os.Looper; import android.telephony.NetworkRegistrationInfo; +import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; @@ -259,6 +262,25 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { assertDataNetworkNameEquals(newDataName); } + @Test + public void testIsDataInService_true() { + setupDefaultSignal(); + assertTrue(mNetworkController.isMobileDataNetworkInService()); + } + + @Test + public void testIsDataInService_noSignal_false() { + assertFalse(mNetworkController.isMobileDataNetworkInService()); + } + + @Test + public void testIsDataInService_notInService_false() { + setupDefaultSignal(); + setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE); + setDataRegState(ServiceState.STATE_OUT_OF_SERVICE); + assertFalse(mNetworkController.isMobileDataNetworkInService()); + } + private void testDataActivity(int direction, boolean in, boolean out) { updateDataActivity(direction); diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java index d5ba381bfcac..e7acfae24f30 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java @@ -94,6 +94,11 @@ public class FakeNetworkController extends BaseLeakChecker return ""; } + @Override + public boolean isMobileDataNetworkInService() { + return false; + } + @Override public int getNumberSubscriptions() { return 0; -- GitLab From db023fcd738bb054402b771e5de5d758db526e30 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Wed, 26 Aug 2020 17:07:53 -0400 Subject: [PATCH 370/536] DO NOT MERGE Sanitize more of the notification text fields Test: manual; monitor SystemUI performance when an app tries to post a messaging style notification with messages with long text Bug: 158304295 Bug: 147358092 Merged-In: c953fdf6bc498ca791aed49df04e5a07c935b63a Change-Id: I0e2ea12fc3351b1a56645b556720ea2306f5422a (cherry picked from commit c953fdf6bc498ca791aed49df04e5a07c935b63a) --- core/java/android/app/Notification.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 4dd71b49b974..21c21315b606 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -183,7 +183,7 @@ public class Notification implements Parcelable *

    * Avoids spamming the system with overly large strings such as full e-mails. */ - private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024; + private static final int MAX_CHARSEQUENCE_LENGTH = 1024; /** * Maximum entries of reply text that are accepted by Builder and friends. @@ -6086,7 +6086,7 @@ public class Notification implements Parcelable * consistent during re-posts of the notification. */ public Message(CharSequence text, long timestamp, CharSequence sender){ - mText = text; + mText = safeCharSequence(text); mTimestamp = timestamp; mSender = sender; } @@ -6175,7 +6175,7 @@ public class Notification implements Parcelable } bundle.putLong(KEY_TIMESTAMP, mTimestamp); if (mSender != null) { - bundle.putCharSequence(KEY_SENDER, mSender); + bundle.putCharSequence(KEY_SENDER, safeCharSequence(mSender)); } if (mDataMimeType != null) { bundle.putString(KEY_DATA_MIME_TYPE, mDataMimeType); -- GitLab From 6987f6d675ddbe53d184910f0c96d7e46baba1fb Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Tue, 8 Sep 2020 10:46:55 -0400 Subject: [PATCH 371/536] Controls - Custom icon/color issues 1. Icon tint colors were not being reset, and improperly reused 2. Routines were using the default icon and not the app icon Fixes: 168012518 Test: Use controls with custom icons, plus enough controls to scroll the recyclerview in editing/favoriting activities Change-Id: I5501139f895739bb414fb4cfa471597254ddaa03 (cherry picked from commit 2fedcb61ea4bb3a6c2612df8b3a5c90eacfd62d5) --- .../android/systemui/controls/management/ControlAdapter.kt | 1 + .../systemui/controls/ui/ControlsUiControllerImpl.kt | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt index 31830b94e8e4..40662536e57e 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt @@ -263,6 +263,7 @@ internal class ControlHolder( val context = itemView.context val fg = context.getResources().getColorStateList(ri.foreground, context.getTheme()) + icon.imageTintList = null ci.customIcon?.let { icon.setImageIcon(it) } ?: run { diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index 5f75c96be128..5a525974f3cb 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -104,6 +104,7 @@ class ControlsUiControllerImpl @Inject constructor ( private var hidden = true private lateinit var dismissGlobalActions: Runnable private val popupThemedContext = ContextThemeWrapper(context, R.style.Control_ListPopupWindow) + private var retainCache = false private val collator = Collator.getInstance(context.resources.configuration.locales[0]) private val localeComparator = compareBy(collator) { @@ -149,6 +150,7 @@ class ControlsUiControllerImpl @Inject constructor ( this.parent = parent this.dismissGlobalActions = dismissGlobalActions hidden = false + retainCache = false allStructures = controlsController.get().getFavorites() selectedStructure = loadPreference(allStructures) @@ -235,6 +237,8 @@ class ControlsUiControllerImpl @Inject constructor ( } putIntentExtras(i, si) startActivity(context, i) + + retainCache = true } private fun putIntentExtras(intent: Intent, si: StructureInfo) { @@ -497,7 +501,7 @@ class ControlsUiControllerImpl @Inject constructor ( controlsListingController.get().removeCallback(listingCallback) - RenderInfo.clearCache() + if (!retainCache) RenderInfo.clearCache() } override fun onRefreshState(componentName: ComponentName, controls: List) { -- GitLab From c16e6dfd4bd97ab6cbca7ff8619a176d076418e0 Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Mon, 31 Aug 2020 14:50:16 -0700 Subject: [PATCH 372/536] Handle IME when target moves between splits Handle split-screen IME when target window is launched in secondary from primary split. By comparing actual InputMethod's input target to the window requesting IME window, we can allow showInsets(ime()). Fix: 159576146 Test: atest ImeInsetsSourceProviderTest Change-Id: Ife4137cc84eba99cf4f6e2f3957f13dcb95818c9 --- .../com/android/server/wm/ImeInsetsSourceProvider.java | 3 ++- .../android/server/wm/ImeInsetsSourceProviderTest.java | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java index e7fbc334306e..5ab48e158c4d 100644 --- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java @@ -138,8 +138,9 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider { && dcTarget.getParentWindow() == mImeTargetFromIme && dcTarget.mSubLayer > mImeTargetFromIme.getWindow().mSubLayer) || mImeTargetFromIme == mDisplayContent.getImeFallback() + || mImeTargetFromIme == mDisplayContent.mInputMethodInputTarget || controlTarget == mImeTargetFromIme - && (mImeTargetFromIme.getWindow() == null + && (mImeTargetFromIme.getWindow() == null || !mImeTargetFromIme.getWindow().isClosing()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java index ca739c0dd389..91cfd4e6a89d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java @@ -56,4 +56,12 @@ public class ImeInsetsSourceProviderTest extends WindowTestsBase { mImeProvider.scheduleShowImePostLayout(appWin); assertTrue(mImeProvider.isImeTargetFromDisplayContentAndImeSame()); } + + @Test + public void testInputMethodInputTargetCanShowIme() { + WindowState target = createWindow(null, TYPE_APPLICATION, "app"); + mDisplayContent.mInputMethodTarget = target; + mImeProvider.scheduleShowImePostLayout(target); + assertTrue(mImeProvider.isImeTargetFromDisplayContentAndImeSame()); + } } -- GitLab From 771d8f8fbbf58fbd1038a64c7779a469083c6178 Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Thu, 3 Sep 2020 16:13:01 -0400 Subject: [PATCH 373/536] Fix NPE in GlobalScreenshot Bug: 167655989 Fix: 167655989 Test: take screenshot, take another while first is still up, observe that NPE occurs. add null check, repeat, verify that NPE does not occur. Change-Id: I1290f3a556aba5182e3f96ce524efb86364bc3e1 --- .../src/com/android/systemui/screenshot/GlobalScreenshot.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 853897fc54ae..c3c947bc40a8 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -566,7 +566,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset private void saveScreenshot(Bitmap screenshot, Consumer finisher, Rect screenRect, Insets screenInsets, boolean showFlash) { if (mScreenshotLayout.isAttachedToWindow()) { - if (!mDismissAnimation.isRunning()) { // if we didn't already dismiss for another reason + // if we didn't already dismiss for another reason + if (mDismissAnimation == null || !mDismissAnimation.isRunning()) { mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_REENTERED); } dismissScreenshot("new screenshot requested", true); -- GitLab From 8e36f0a26e27eb70198d9518ba091c34c328dab8 Mon Sep 17 00:00:00 2001 From: yingleiw Date: Thu, 27 Aug 2020 14:54:30 -0700 Subject: [PATCH 374/536] Add accessibility manager enabled check in progressbar formatStateDescription() in onProgressRefresh() is causing performance degradation with accessibility off. Note that stateDescription is set in onInitializeAccessibilityNodeInfo to ensure that accessibility always get the update-to-date stateDescription. Otherwise, stateDescription might be stale on first accessibility focus and the user might get wrong information. Fix: b/166215147 Test: tested with talkback enabled from the beginning or from the middle. Change-Id: I9fb99b479b172d87c8d0fa1b8765dab53445b993 (cherry picked from commit fc9d9b800f0d2b39b42a82b5f6b88abd5f712228) --- core/java/android/widget/ProgressBar.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 970d70cf1fb4..f56c357c57a8 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -52,6 +52,7 @@ import android.view.View; import android.view.ViewDebug; import android.view.ViewHierarchyEncoder; import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; @@ -306,9 +307,6 @@ public class ProgressBar extends View { setMax(a.getInt(R.styleable.ProgressBar_max, mMax)); setProgress(a.getInt(R.styleable.ProgressBar_progress, mProgress)); - // onProgressRefresh() is only called when the progress changes. So we should set - // stateDescription during initialization here. - super.setStateDescription(formatStateDescription(mProgress)); setSecondaryProgress(a.getInt( R.styleable.ProgressBar_secondaryProgress, mSecondaryProgress)); @@ -1601,7 +1599,8 @@ public class ProgressBar extends View { } void onProgressRefresh(float scale, boolean fromUser, int progress) { - if (mCustomStateDescription == null) { + if (AccessibilityManager.getInstance(mContext).isEnabled() + && mCustomStateDescription == null) { super.setStateDescription(formatStateDescription(mProgress)); } } @@ -2325,6 +2324,7 @@ public class ProgressBar extends View { AccessibilityNodeInfo.RangeInfo.RANGE_TYPE_INT, getMin(), getMax(), getProgress()); info.setRangeInfo(rangeInfo); + info.setStateDescription(formatStateDescription(mProgress)); } } -- GitLab From 41b1674f775c9b3d941f78525dcfc804ef2e047a Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Wed, 26 Aug 2020 14:42:08 -0700 Subject: [PATCH 375/536] Accept repeated locale as an input of LocaleList construction. Repeated locale has not been accepted and IllegalArgumentException is thrown. Instead of throwing exception, dropping repeated locale instead. Bug: 152410253 Test: atest LocaleListTest Change-Id: I80f243678ac3024eaeb0349f770cff897df7f332 --- core/java/android/os/LocaleList.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index 0de09efad8ea..32c608c93ba9 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -25,6 +25,7 @@ import android.icu.util.ULocale; import com.android.internal.annotations.GuardedBy; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -151,18 +152,18 @@ public final class LocaleList implements Parcelable { /** * Creates a new {@link LocaleList}. * + * If two or more same locales are passed, the repeated locales will be dropped. *

    For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()}, * which returns a pre-constructed empty list.

    * * @throws NullPointerException if any of the input locales is null. - * @throws IllegalArgumentException if any of the input locales repeat. */ public LocaleList(@NonNull Locale... list) { if (list.length == 0) { mList = sEmptyList; mStringRepresentation = ""; } else { - final Locale[] localeList = new Locale[list.length]; + final ArrayList localeList = new ArrayList<>(); final HashSet seenLocales = new HashSet(); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.length; i++) { @@ -170,10 +171,10 @@ public final class LocaleList implements Parcelable { if (l == null) { throw new NullPointerException("list[" + i + "] is null"); } else if (seenLocales.contains(l)) { - throw new IllegalArgumentException("list[" + i + "] is a repetition"); + // Dropping duplicated locale entries. } else { final Locale localeClone = (Locale) l.clone(); - localeList[i] = localeClone; + localeList.add(localeClone); sb.append(localeClone.toLanguageTag()); if (i < list.length - 1) { sb.append(','); @@ -181,7 +182,7 @@ public final class LocaleList implements Parcelable { seenLocales.add(localeClone); } } - mList = localeList; + mList = localeList.toArray(new Locale[localeList.size()]); mStringRepresentation = sb.toString(); } } -- GitLab From 951fa94b6a7f9a41d38faa759148db2e8e7da7ce Mon Sep 17 00:00:00 2001 From: Suprabh Shukla Date: Thu, 3 Sep 2020 12:54:39 -0700 Subject: [PATCH 376/536] RESTRICT AUTOMERGE Remove alarms from mPendingNonWakeupAlarms While setting an alarm, we should remove any existing occurrences of the same, but we were skipping on removing any past due non-wakeup alarms. In rare cases when a caller is spamming the alarm manager, we might end up accumulating alarms inside mPendingNonWakeupAlarms that count towards the per-uid limit of the caller, and may result in an exception. Test: atest FrameworksMockingServicesTests:AlarmManagerServiceTest atest CtsAlarmManagerTestCases Bug: 167645096 Bug: 130444055 Change-Id: I2d2b08019a3b3a1e63b60d3a6e2909db7b1a1864 --- .../android/server/AlarmManagerService.java | 8 ++++ .../server/AlarmManagerServiceTest.java | 43 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 4fab067d1d3b..651f941be0b1 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -3109,6 +3109,14 @@ class AlarmManagerService extends SystemService { mPendingBackgroundAlarms.removeAt(i); } } + for (int i = mPendingNonWakeupAlarms.size() - 1; i >= 0; i--) { + final Alarm a = mPendingNonWakeupAlarms.get(i); + if (a.matches(operation, directReceiver)) { + // Don't set didRemove, since this doesn't impact the scheduled alarms. + mPendingNonWakeupAlarms.remove(i); + decrementAlarmCount(a.uid, 1); + } + } if (didRemove) { if (DEBUG_BATCH) { Slog.v(TAG, "remove(operation) changed bounds; rebatching"); diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java index ca8e50aa19c9..7bd0201b997a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java @@ -1053,6 +1053,49 @@ public class AlarmManagerServiceTest { } } + @Test + public void nonWakeupAlarmsDeferred() throws Exception { + final int numAlarms = 10; + final PendingIntent[] pis = new PendingIntent[numAlarms]; + for (int i = 0; i < numAlarms; i++) { + pis[i] = getNewMockPendingIntent(); + setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 5, pis[i]); + } + doReturn(true).when(mService).checkAllowNonWakeupDelayLocked(anyLong()); + // Advance time past all expirations. + mNowElapsedTest += numAlarms + 5; + mTestTimer.expire(); + assertEquals(numAlarms, mService.mPendingNonWakeupAlarms.size()); + + // These alarms should be sent on interactive state change to true + mService.interactiveStateChangedLocked(false); + mService.interactiveStateChangedLocked(true); + + for (int i = 0; i < numAlarms; i++) { + verify(pis[i]).send(eq(mMockContext), eq(0), any(Intent.class), any(), + any(Handler.class), isNull(), any()); + } + } + + @Test + public void alarmCountOnPendingNonWakeupAlarmsRemoved() throws Exception { + final int numAlarms = 10; + final PendingIntent[] pis = new PendingIntent[numAlarms]; + for (int i = 0; i < numAlarms; i++) { + pis[i] = getNewMockPendingIntent(); + setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 5, pis[i]); + } + doReturn(true).when(mService).checkAllowNonWakeupDelayLocked(anyLong()); + // Advance time past all expirations. + mNowElapsedTest += numAlarms + 5; + mTestTimer.expire(); + assertEquals(numAlarms, mService.mPendingNonWakeupAlarms.size()); + for (int i = 0; i < numAlarms; i++) { + mService.removeLocked(pis[i], null); + assertEquals(numAlarms - i - 1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0)); + } + } + @After public void tearDown() { if (mMockingSession != null) { -- GitLab From b6f4a0c6728d0ec5ffab4cd29deb53953eac8fa9 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Tue, 1 Sep 2020 16:08:29 -0700 Subject: [PATCH 377/536] DO NOT MERGE Adjust window focusable by view controller Some adjustments to note: 1. remove previous focusability changes per view controller 2. disallow calling insetsController.show/hide without window focus 3. update tests to depend on window focus 4. update DisplaySystemBarsController to refer to parent class for ime insets Bug: 163135884 Test: manual, atest :carsysui-presubmit Change-Id: If5adf599bc2c676ad296f89566534c1fdc9f2492 --- .../keyguard/CarKeyguardViewController.java | 5 +- .../NotificationPanelViewController.java | 4 +- .../FullScreenUserSwitcherViewController.java | 5 + .../window/OverlayPanelViewController.java | 2 - .../car/window/OverlayViewController.java | 19 ++- .../OverlayViewGlobalStateController.java | 29 +++- .../SystemUIOverlayWindowController.java | 3 + .../wm/DisplaySystemBarsController.java | 26 ++- .../OverlayPanelViewControllerTest.java | 29 ---- .../OverlayViewGlobalStateControllerTest.java | 156 ++++++++++++++---- 10 files changed, 188 insertions(+), 90 deletions(-) diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java index 51a7245ea5c6..218c95c2496f 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java @@ -141,7 +141,7 @@ public class CarKeyguardViewController extends OverlayViewController implements } @Override - protected boolean shouldShowNavigationBar() { + protected boolean shouldShowNavigationBarInsets() { return true; } @@ -177,7 +177,6 @@ public class CarKeyguardViewController extends OverlayViewController implements mKeyguardStateController.notifyKeyguardState(mShowing, /* occluded= */ false); mCarNavigationBarController.showAllKeyguardButtons(/* isSetUp= */ true); start(); - getOverlayViewGlobalStateController().setWindowFocusable(/* focusable= */ true); reset(/* hideBouncerWhenShowing= */ false); notifyKeyguardUpdateMonitor(); } @@ -192,7 +191,6 @@ public class CarKeyguardViewController extends OverlayViewController implements mBouncer.hide(/* destroyView= */ true); mCarNavigationBarController.hideAllKeyguardButtons(/* isSetUp= */ true); stop(); - getOverlayViewGlobalStateController().setWindowFocusable(/* focusable= */ false); mKeyguardStateController.notifyKeyguardDoneFading(); mHandler.post(mViewMediatorCallback::keyguardGone); notifyKeyguardUpdateMonitor(); @@ -237,7 +235,6 @@ public class CarKeyguardViewController extends OverlayViewController implements public void onCancelClicked() { if (mBouncer == null) return; - getOverlayViewGlobalStateController().setWindowFocusable(/* focusable= */ false); getOverlayViewGlobalStateController().setWindowNeedsInput(/* needsInput= */ false); mBouncer.hide(/* destroyView= */ true); diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java index a7cb0d86a6a8..7cd559a11158 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java @@ -193,12 +193,12 @@ public class NotificationPanelViewController extends OverlayPanelViewController } @Override - protected boolean shouldShowNavigationBar() { + protected boolean shouldShowNavigationBarInsets() { return true; } @Override - protected boolean shouldShowStatusBar() { + protected boolean shouldShowStatusBarInsets() { return true; } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java index 1a8f19e46798..aac4cfbf83c4 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java @@ -77,6 +77,11 @@ public class FullScreenUserSwitcherViewController extends OverlayViewController registerCarUserManagerIfPossible(); } + @Override + protected boolean shouldFocusWindow() { + return false; + } + @Override protected void showInternal() { getLayout().setVisibility(View.VISIBLE); diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java index 1b00c6301011..3c9879c671a5 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java @@ -238,7 +238,6 @@ public abstract class OverlayPanelViewController extends OverlayViewController { } onAnimateCollapsePanel(); - getOverlayViewGlobalStateController().setWindowFocusable(false); animatePanel(mClosingVelocity, /* isClosing= */ true); } @@ -415,7 +414,6 @@ public abstract class OverlayPanelViewController extends OverlayViewController { getOverlayViewGlobalStateController().hideView(/* panelViewController= */ this); } getLayout().setVisibility(visible ? View.VISIBLE : View.INVISIBLE); - getOverlayViewGlobalStateController().setWindowFocusable(visible); } /* ***************************************************************************************** * diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java index 53deb9d9dc5d..8adc1adcc41c 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java @@ -136,16 +136,18 @@ public class OverlayViewController { } /** - * Returns {@code true} if navigation bar should be displayed over this view. + * Returns {@code true} if navigation bar insets should be displayed over this view. Has no + * effect if {@link #shouldFocusWindow} returns {@code false}. */ - protected boolean shouldShowNavigationBar() { + protected boolean shouldShowNavigationBarInsets() { return false; } /** - * Returns {@code true} if status bar should be displayed over this view. + * Returns {@code true} if status bar insets should be displayed over this view. Has no + * effect if {@link #shouldFocusWindow} returns {@code false}. */ - protected boolean shouldShowStatusBar() { + protected boolean shouldShowStatusBarInsets() { return false; } @@ -156,6 +158,15 @@ public class OverlayViewController { return false; } + /** + * Returns {@code true} if the window should be focued when this view is visible. Note that + * returning {@code false} here means that {@link #shouldShowStatusBarInsets} and + * {@link #shouldShowNavigationBarInsets} will have no effect. + */ + protected boolean shouldFocusWindow() { + return true; + } + /** * Returns the insets types to fit to the sysui overlay window when this * {@link OverlayViewController} is in the foreground. diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java index 2494242c24f0..55f0975aeccf 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java @@ -18,7 +18,6 @@ package com.android.systemui.car.window; import static android.view.WindowInsets.Type.navigationBars; import static android.view.WindowInsets.Type.statusBars; -import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; import android.annotation.Nullable; import android.util.Log; @@ -118,6 +117,7 @@ public class OverlayViewGlobalStateController { updateInternalsWhenShowingView(viewController); refreshInsetTypesToFit(); + refreshWindowFocus(); refreshNavigationBarVisibility(); refreshStatusBarVisibility(); @@ -190,6 +190,7 @@ public class OverlayViewGlobalStateController { mZOrderVisibleSortedMap.remove(mZOrderMap.get(viewController)); refreshHighestZOrderWhenHidingView(viewController); refreshInsetTypesToFit(); + refreshWindowFocus(); refreshNavigationBarVisibility(); refreshStatusBarVisibility(); @@ -214,23 +215,37 @@ public class OverlayViewGlobalStateController { } private void refreshNavigationBarVisibility() { - mWindowInsetsController.setSystemBarsBehavior(BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); - if (mZOrderVisibleSortedMap.isEmpty() || mHighestZOrder.shouldShowNavigationBar()) { + if (mZOrderVisibleSortedMap.isEmpty()) { mWindowInsetsController.show(navigationBars()); - } else { + return; + } + + // Do not hide navigation bar insets if the window is not focusable. + if (mHighestZOrder.shouldFocusWindow() && !mHighestZOrder.shouldShowNavigationBarInsets()) { mWindowInsetsController.hide(navigationBars()); + } else { + mWindowInsetsController.show(navigationBars()); } } private void refreshStatusBarVisibility() { - mWindowInsetsController.setSystemBarsBehavior(BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); - if (mZOrderVisibleSortedMap.isEmpty() || mHighestZOrder.shouldShowStatusBar()) { + if (mZOrderVisibleSortedMap.isEmpty()) { mWindowInsetsController.show(statusBars()); - } else { + return; + } + + // Do not hide status bar insets if the window is not focusable. + if (mHighestZOrder.shouldFocusWindow() && !mHighestZOrder.shouldShowStatusBarInsets()) { mWindowInsetsController.hide(statusBars()); + } else { + mWindowInsetsController.show(statusBars()); } } + private void refreshWindowFocus() { + setWindowFocusable(mHighestZOrder == null ? false : mHighestZOrder.shouldFocusWindow()); + } + private void refreshInsetTypesToFit() { if (mZOrderVisibleSortedMap.isEmpty()) { setFitInsetsTypes(statusBars()); diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java index 029bd3702afe..c955fab592f3 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java @@ -16,6 +16,7 @@ package com.android.systemui.car.window; +import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import android.content.Context; @@ -104,6 +105,7 @@ public class SystemUIOverlayWindowController implements mLp.setTitle("SystemUIOverlayWindow"); mLp.packageName = mContext.getPackageName(); mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; + mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; mWindowManager.addView(mBaseLayout, mLp); mLpChanged.copyFrom(mLp); @@ -160,6 +162,7 @@ public class SystemUIOverlayWindowController implements private void updateWindow() { if (mLp != null && mLp.copyFrom(mLpChanged) != 0) { if (isAttached()) { + mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; mWindowManager.updateViewLayout(mBaseLayout, mLp); } } diff --git a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java index a831464e7987..c9ec34fd5f08 100644 --- a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java +++ b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java @@ -32,6 +32,8 @@ import androidx.annotation.VisibleForTesting; import com.android.systemui.TransactionPool; import com.android.systemui.dagger.qualifiers.Main; +import java.util.Objects; + import javax.inject.Inject; import javax.inject.Singleton; @@ -90,7 +92,7 @@ public class DisplaySystemBarsController extends DisplayImeController { } @VisibleForTesting - class PerDisplay extends IDisplayWindowInsetsController.Stub { + class PerDisplay extends DisplayImeController.PerDisplay { int mDisplayId; InsetsController mInsetsController; @@ -98,6 +100,8 @@ public class DisplaySystemBarsController extends DisplayImeController { String mPackageName; PerDisplay(int displayId) { + super(displayId, + mSystemWindows.mDisplayController.getDisplayLayout(displayId).rotation()); mDisplayId = displayId; mInsetsController = new InsetsController( new DisplaySystemBarsInsetsControllerHost(mHandler, this)); @@ -105,6 +109,7 @@ public class DisplaySystemBarsController extends DisplayImeController { @Override public void insetsChanged(InsetsState insetsState) { + super.insetsChanged(insetsState); if (mInsetsState.equals(insetsState)) { return; } @@ -118,24 +123,33 @@ public class DisplaySystemBarsController extends DisplayImeController { @Override public void insetsControlChanged(InsetsState insetsState, InsetsSourceControl[] activeControls) { + super.insetsControlChanged(insetsState, activeControls); mInsetsController.onControlsChanged(activeControls); } @Override public void hideInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme) { - mInsetsController.hide(types); + if ((types & WindowInsets.Type.ime()) == 0) { + mInsetsController.hide(types); + } else { + super.hideInsets(types, fromIme); + } + } @Override public void showInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme) { - mInsetsController.show(types); + if ((types & WindowInsets.Type.ime()) == 0) { + mInsetsController.show(types); + } else { + super.showInsets(types, fromIme); + } + } @Override public void topFocusedWindowChanged(String packageName) { - // If both package names are null or both package names are equal, return. - if (mPackageName == packageName - || (mPackageName != null && mPackageName.equals(packageName))) { + if (Objects.equals(mPackageName, packageName)) { return; } mPackageName = packageName; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java index 7311cdb68a3c..23e21e4cbed6 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java @@ -223,18 +223,6 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase { mOverlayPanelViewController.getLayout().getHeight()); } - @Test - public void animateCollapsePanel_removesWindowFocus() { - mOverlayPanelViewController.inflate(mBaseLayout); - mOverlayPanelViewController.setShouldAnimateCollapsePanel(true); - mOverlayPanelViewController.setPanelExpanded(true); - mOverlayPanelViewController.setPanelVisible(true); - - mOverlayPanelViewController.animateCollapsePanel(); - - verify(mOverlayViewGlobalStateController).setWindowFocusable(false); - } - @Test public void animateExpandPanel_shouldNotAnimateExpandPanel_doesNotExpand() { mOverlayPanelViewController.inflate(mBaseLayout); @@ -364,14 +352,6 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase { assertThat(mOverlayPanelViewController.getLayout().getVisibility()).isEqualTo(View.VISIBLE); } - @Test - public void setPanelVisible_setTrue_setWindowFocusable() { - mOverlayPanelViewController.inflate(mBaseLayout); - mOverlayPanelViewController.setPanelVisible(true); - - verify(mOverlayViewGlobalStateController).setWindowFocusable(true); - } - @Test public void setPanelVisible_setFalse_windowVisible_setsWindowNotVisible() { mOverlayPanelViewController.inflate(mBaseLayout); @@ -403,15 +383,6 @@ public class OverlayPanelViewControllerTest extends SysuiTestCase { View.INVISIBLE); } - @Test - public void setPanelVisible_setFalse_setWindowNotFocusable() { - mOverlayPanelViewController.inflate(mBaseLayout); - - mOverlayPanelViewController.setPanelVisible(false); - - verify(mOverlayViewGlobalStateController).setWindowFocusable(false); - } - @Test public void dragOpenTouchListener_isNotInflated_inflatesView() { when(mCarDeviceProvisionedController.isCurrentUserFullySetup()).thenReturn(true); diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java index ff286650ea50..294aa0d3cf9b 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java @@ -107,10 +107,55 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { verify(mOverlayViewMediator).setupOverlayContentViewControllers(); } + @Test + public void showView_nothingVisible_windowNotFocusable_shouldShowNavBar_navBarsVisible() { + setupOverlayViewController1(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(false); + when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(true); + + mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); + + verify(mWindowInsetsController).show(navigationBars()); + } + + @Test + public void showView_nothingVisible_windowNotFocusable_shouldHideNavBar_notHidden() { + setupOverlayViewController1(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(false); + when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(false); + + mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); + + verify(mWindowInsetsController, never()).hide(navigationBars()); + } + + @Test + public void showView_nothingVisible_windowNotFocusable_shouldShowStatusBar_statusBarsVisible() { + setupOverlayViewController1(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(false); + when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(true); + + mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); + + verify(mWindowInsetsController).show(statusBars()); + } + + @Test + public void showView_nothingVisible_windowNotFocusable_shouldHideStatusBar_notHidden() { + setupOverlayViewController1(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(false); + when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(false); + + mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); + + verify(mWindowInsetsController, never()).hide(statusBars()); + } + @Test public void showView_nothingAlreadyShown_shouldShowNavBarFalse_navigationBarsHidden() { setupOverlayViewController1(); - when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(false); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(false); mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); @@ -120,7 +165,8 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_nothingAlreadyShown_shouldShowNavBarTrue_navigationBarsShown() { setupOverlayViewController1(); - when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(true); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(true); mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); @@ -130,7 +176,8 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_nothingAlreadyShown_shouldShowStatusBarFalse_statusBarsHidden() { setupOverlayViewController1(); - when(mOverlayViewController1.shouldShowStatusBar()).thenReturn(false); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(false); mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); @@ -140,7 +187,8 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_nothingAlreadyShown_shouldShowStatusBarTrue_statusBarsShown() { setupOverlayViewController1(); - when(mOverlayViewController1.shouldShowStatusBar()).thenReturn(true); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(true); mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); @@ -201,9 +249,11 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_newHighestZOrder_shouldShowNavBarFalse_navigationBarsHidden() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); - when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(false); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); + when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(false); reset(mWindowInsetsController); mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable); @@ -214,9 +264,11 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_newHighestZOrder_shouldShowNavBarTrue_navigationBarsShown() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); - when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(true); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); + when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(true); mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable); @@ -226,9 +278,11 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_newHighestZOrder_shouldShowStatusBarFalse_statusBarsHidden() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); - when(mOverlayViewController2.shouldShowStatusBar()).thenReturn(false); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); + when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(false); reset(mWindowInsetsController); mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable); @@ -239,9 +293,11 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_newHighestZOrder_shouldShowStatusBarTrue_statusBarsShown() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); - when(mOverlayViewController2.shouldShowStatusBar()).thenReturn(true); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); + when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(true); mOverlayViewGlobalStateController.showView(mOverlayViewController2, mRunnable); @@ -289,9 +345,11 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_oldHighestZOrder_shouldShowNavBarFalse_navigationBarsHidden() { setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(true); - when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(false); + when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(true); + when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(false); reset(mWindowInsetsController); mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); @@ -302,9 +360,11 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_oldHighestZOrder_shouldShowNavBarTrue_navigationBarsShown() { setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(false); - when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(true); + when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(false); + when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(true); mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); @@ -314,9 +374,11 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_oldHighestZOrder_shouldShowStatusBarFalse_statusBarsHidden() { setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController1.shouldShowStatusBar()).thenReturn(true); - when(mOverlayViewController2.shouldShowStatusBar()).thenReturn(false); + when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(true); + when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(false); reset(mWindowInsetsController); mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); @@ -327,9 +389,11 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void showView_oldHighestZOrder_shouldShowStatusBarTrue_statusBarsShown() { setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController1.shouldShowStatusBar()).thenReturn(false); - when(mOverlayViewController2.shouldShowStatusBar()).thenReturn(true); + when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(false); + when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(true); mOverlayViewGlobalStateController.showView(mOverlayViewController1, mRunnable); @@ -512,10 +576,12 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void hideView_newHighestZOrder_shouldShowNavBarFalse_navigationBarHidden() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(false); + when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(false); reset(mWindowInsetsController); mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable); @@ -526,10 +592,13 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void hideView_newHighestZOrder_shouldShowNavBarTrue_navigationBarShown() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController1.shouldShowNavigationBar()).thenReturn(true); + when(mOverlayViewController1.shouldShowNavigationBarInsets()).thenReturn(true); + reset(mWindowInsetsController); mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable); @@ -539,10 +608,12 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void hideView_newHighestZOrder_shouldShowStatusBarFalse_statusBarHidden() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController1.shouldShowStatusBar()).thenReturn(false); + when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(false); reset(mWindowInsetsController); mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable); @@ -553,10 +624,13 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void hideView_newHighestZOrder_shouldShowStatusBarTrue_statusBarShown() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController1.shouldShowStatusBar()).thenReturn(true); + when(mOverlayViewController1.shouldShowStatusBarInsets()).thenReturn(true); + reset(mWindowInsetsController); mOverlayViewGlobalStateController.hideView(mOverlayViewController2, mRunnable); @@ -593,10 +667,12 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void hideView_oldHighestZOrder_shouldShowNavBarFalse_navigationBarHidden() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(false); + when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(false); reset(mWindowInsetsController); mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable); @@ -607,10 +683,12 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void hideView_oldHighestZOrder_shouldShowNavBarTrue_navigationBarShown() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController2.shouldShowNavigationBar()).thenReturn(true); + when(mOverlayViewController2.shouldShowNavigationBarInsets()).thenReturn(true); mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable); @@ -620,10 +698,12 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void hideView_oldHighestZOrder_shouldShowStatusBarFalse_statusBarHidden() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController2.shouldShowStatusBar()).thenReturn(false); + when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(false); reset(mWindowInsetsController); mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable); @@ -634,10 +714,12 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void hideView_oldHighestZOrder_shouldShowStatusBarTrue_statusBarShown() { setupOverlayViewController1(); - setOverlayViewControllerAsShowing(mOverlayViewController1); setupOverlayViewController2(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); + when(mOverlayViewController2.shouldFocusWindow()).thenReturn(true); + setOverlayViewControllerAsShowing(mOverlayViewController1); setOverlayViewControllerAsShowing(mOverlayViewController2); - when(mOverlayViewController2.shouldShowStatusBar()).thenReturn(true); + when(mOverlayViewController2.shouldShowStatusBarInsets()).thenReturn(true); mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable); @@ -673,6 +755,7 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void hideView_viewControllerOnlyShown_navigationBarShown() { setupOverlayViewController1(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController1); mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable); @@ -683,6 +766,7 @@ public class OverlayViewGlobalStateControllerTest extends SysuiTestCase { @Test public void hideView_viewControllerOnlyShown_statusBarShown() { setupOverlayViewController1(); + when(mOverlayViewController1.shouldFocusWindow()).thenReturn(true); setOverlayViewControllerAsShowing(mOverlayViewController1); mOverlayViewGlobalStateController.hideView(mOverlayViewController1, mRunnable); -- GitLab From 373ac57b2d0593d296f779df185d91bc7c9999b2 Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Wed, 26 Aug 2020 14:42:08 -0700 Subject: [PATCH 378/536] Accept repeated locale as an input of LocaleList construction. Repeated locale has not been accepted and IllegalArgumentException is thrown. Instead of throwing exception, dropping repeated locale instead. Bug: 152410253 Test: atest LocaleListTest Change-Id: I80f243678ac3024eaeb0349f770cff897df7f332 --- core/java/android/os/LocaleList.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java index ab4bb0b9f2cd..9c0bc45a346e 100644 --- a/core/java/android/os/LocaleList.java +++ b/core/java/android/os/LocaleList.java @@ -25,6 +25,7 @@ import android.icu.util.ULocale; import com.android.internal.annotations.GuardedBy; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -151,18 +152,18 @@ public final class LocaleList implements Parcelable { /** * Creates a new {@link LocaleList}. * + * If two or more same locales are passed, the repeated locales will be dropped. *

    For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()}, * which returns a pre-constructed empty list.

    * * @throws NullPointerException if any of the input locales is null. - * @throws IllegalArgumentException if any of the input locales repeat. */ public LocaleList(@NonNull Locale... list) { if (list.length == 0) { mList = sEmptyList; mStringRepresentation = ""; } else { - final Locale[] localeList = new Locale[list.length]; + final ArrayList localeList = new ArrayList<>(); final HashSet seenLocales = new HashSet(); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.length; i++) { @@ -170,10 +171,10 @@ public final class LocaleList implements Parcelable { if (l == null) { throw new NullPointerException("list[" + i + "] is null"); } else if (seenLocales.contains(l)) { - throw new IllegalArgumentException("list[" + i + "] is a repetition"); + // Dropping duplicated locale entries. } else { final Locale localeClone = (Locale) l.clone(); - localeList[i] = localeClone; + localeList.add(localeClone); sb.append(localeClone.toLanguageTag()); if (i < list.length - 1) { sb.append(','); @@ -181,7 +182,7 @@ public final class LocaleList implements Parcelable { seenLocales.add(localeClone); } } - mList = localeList; + mList = localeList.toArray(new Locale[localeList.size()]); mStringRepresentation = sb.toString(); } } -- GitLab From 44caf0ed75697e8b33346bece6e1b022403abe99 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Fri, 21 Aug 2020 15:44:55 -0700 Subject: [PATCH 379/536] AudioService: check calls to AudioSystem.initStreamVolume AudioSystem.initStreamVolume initializes the min and max stream volume indices. The return value was never checked to ensure success of the call. An unchecked failure could leave min/max values at -1 in native AudioPolicyManager, which could lead to no valid volume to be set, and thus no audio would be heard as a result. The fix consists in ensuring we retry initializing the stream volumes whenever an error is detected when calling the initialization method, or after checking whether the min/max values are valid after initialization. Bug: 161950968 Test: adb shell dumpsys audio, check lifecycle section Change-Id: I3714c0db2a9657a88488635f7d6c78e682f326aa Merged-In: I3714c0db2a9657a88488635f7d6c78e682f326aa --- .../server/audio/AudioEventLogger.java | 31 ++++- .../android/server/audio/AudioService.java | 109 ++++++++++++++++-- 2 files changed, 129 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/audio/AudioEventLogger.java b/services/core/java/com/android/server/audio/AudioEventLogger.java index 9ebd75bd0f64..af0e978726e3 100644 --- a/services/core/java/com/android/server/audio/AudioEventLogger.java +++ b/services/core/java/com/android/server/audio/AudioEventLogger.java @@ -60,7 +60,36 @@ public class AudioEventLogger { * @return the same instance of the event */ public Event printLog(String tag) { - Log.i(tag, eventToString()); + return printLog(ALOGI, tag); + } + + public static final int ALOGI = 0; + public static final int ALOGE = 1; + public static final int ALOGW = 2; + public static final int ALOGV = 3; + + /** + * Same as {@link #printLog(String)} with a log type + * @param type one of {@link #ALOGI}, {@link #ALOGE}, {@link #ALOGV} + * @param tag + * @return + */ + public Event printLog(int type, String tag) { + switch (type) { + case ALOGI: + Log.i(tag, eventToString()); + break; + case ALOGE: + Log.e(tag, eventToString()); + break; + case ALOGW: + Log.w(tag, eventToString()); + break; + case ALOGV: + default: + Log.v(tag, eventToString()); + break; + } return this; } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index fe619690ae34..75c27603d785 100755 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -26,6 +26,10 @@ import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE; import static android.provider.Settings.Secure.VOLUME_HUSH_OFF; import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE; +import static com.android.server.audio.AudioEventLogger.Event.ALOGE; +import static com.android.server.audio.AudioEventLogger.Event.ALOGI; +import static com.android.server.audio.AudioEventLogger.Event.ALOGW; + import android.Manifest; import android.annotation.IntDef; import android.annotation.NonNull; @@ -284,6 +288,7 @@ public class AudioService extends IAudioService.Stub private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29; private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30; private static final int MSG_CHECK_MODE_FOR_UID = 31; + private static final int MSG_REINIT_VOLUMES = 32; // start of messages handled under wakelock // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) @@ -673,6 +678,7 @@ public class AudioService extends IAudioService.Stub public AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer) { + sLifecycleLogger.log(new AudioEventLogger.StringEvent("AudioService()")); mContext = context; mContentResolver = context.getContentResolver(); mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); @@ -892,6 +898,9 @@ public class AudioService extends IAudioService.Stub mPrescaleAbsoluteVolume[i] = preScale[i]; } } + + // check on volume initialization + checkVolumeRangeInitialization("AudioService()"); } public void systemReady() { @@ -1019,11 +1028,15 @@ public class AudioService extends IAudioService.Stub if (!mSystemReady || (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) { Log.e(TAG, "Audioserver died."); + sLifecycleLogger.log(new AudioEventLogger.StringEvent( + "onAudioServerDied() audioserver died")); sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0, null, 500); return; } - Log.e(TAG, "Audioserver started."); + Log.i(TAG, "Audioserver started."); + sLifecycleLogger.log(new AudioEventLogger.StringEvent( + "onAudioServerDied() audioserver started")); updateAudioHalPids(); @@ -1058,14 +1071,7 @@ public class AudioService extends IAudioService.Stub mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied"); // Restore stream volumes - int numStreamTypes = AudioSystem.getNumStreamTypes(); - for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { - VolumeStreamState streamState = mStreamStates[streamType]; - AudioSystem.initStreamVolume( - streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10); - - streamState.applyAllVolumes(); - } + onReinitVolumes("after audioserver restart"); // Restore audio volume groups restoreVolumeGroups(); @@ -1163,6 +1169,72 @@ public class AudioService extends IAudioService.Stub setMicMuteFromSwitchInput(); } + private void onReinitVolumes(@NonNull String caller) { + final int numStreamTypes = AudioSystem.getNumStreamTypes(); + // keep track of any error during stream volume initialization + int status = AudioSystem.AUDIO_STATUS_OK; + for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { + VolumeStreamState streamState = mStreamStates[streamType]; + final int res = AudioSystem.initStreamVolume( + streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10); + if (res != AudioSystem.AUDIO_STATUS_OK) { + status = res; + Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType); + // stream volume initialization failed, no need to try the others, it will be + // attempted again when MSG_REINIT_VOLUMES is handled + break; + } + streamState.applyAllVolumes(); + } + + // did it work? check based on status + if (status != AudioSystem.AUDIO_STATUS_OK) { + sLifecycleLogger.log(new AudioEventLogger.StringEvent( + caller + ": initStreamVolume failed with " + status + " will retry") + .printLog(ALOGE, TAG)); + sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, + caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); + return; + } + + // did it work? check based on min/max values of some basic streams + if (!checkVolumeRangeInitialization(caller)) { + return; + } + + // success + sLifecycleLogger.log(new AudioEventLogger.StringEvent( + caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG)); + } + + /** + * Check volume ranges were properly initialized + * @return true if volume ranges were successfully initialized + */ + private boolean checkVolumeRangeInitialization(String caller) { + boolean success = true; + final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING, + AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL, + AudioSystem.STREAM_ACCESSIBILITY }; + for (int streamType : basicStreams) { + final AudioAttributes aa = new AudioAttributes.Builder() + .setInternalLegacyStreamType(streamType).build(); + if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0 + || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) { + success = false; + break; + } + } + if (!success) { + sLifecycleLogger.log(new AudioEventLogger.StringEvent( + caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry") + .printLog(ALOGW, TAG)); + sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, + caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); + } + return success; + } + private void onDispatchAudioServerStateChange(boolean state) { synchronized (mAudioServerStateListeners) { for (AsdProxy asdp : mAudioServerStateListeners.values()) { @@ -5579,7 +5651,15 @@ public class AudioService extends IAudioService.Stub mIndexMin = MIN_STREAM_VOLUME[streamType] * 10; mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex() mIndexMax = MAX_STREAM_VOLUME[streamType] * 10; - AudioSystem.initStreamVolume(streamType, mIndexMin / 10, mIndexMax / 10); + final int status = AudioSystem.initStreamVolume( + streamType, mIndexMin / 10, mIndexMax / 10); + if (status != AudioSystem.AUDIO_STATUS_OK) { + sLifecycleLogger.log(new AudioEventLogger.StringEvent( + "VSS() stream:" + streamType + " initStreamVolume=" + status) + .printLog(ALOGE, TAG)); + sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, + "VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); + } readSettings(); mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION); @@ -6433,6 +6513,10 @@ public class AudioService extends IAudioService.Stub mModeLogger.log(new PhoneStateEvent(h.getPackage(), h.getPid())); } break; + + case MSG_REINIT_VOLUMES: + onReinitVolumes((String) msg.obj); + break; } } } @@ -7363,12 +7447,16 @@ public class AudioService extends IAudioService.Stub //========================================================================================== // AudioService logging and dumpsys //========================================================================================== + static final int LOG_NB_EVENTS_LIFECYCLE = 20; static final int LOG_NB_EVENTS_PHONE_STATE = 20; static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 30; static final int LOG_NB_EVENTS_FORCE_USE = 20; static final int LOG_NB_EVENTS_VOLUME = 40; static final int LOG_NB_EVENTS_DYN_POLICY = 10; + static final AudioEventLogger sLifecycleLogger = new AudioEventLogger(LOG_NB_EVENTS_LIFECYCLE, + "audio services lifecycle"); + final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE, "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))"); @@ -7445,6 +7533,7 @@ public class AudioService extends IAudioService.Stub protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; + sLifecycleLogger.dump(pw); if (mAudioHandler != null) { pw.println("\nMessage handler (watch for unhandled messages):"); mAudioHandler.dump(new PrintWriterPrinter(pw), " "); -- GitLab From cefc89c911ef17794b81aa0a3c0966ea2339a9cc Mon Sep 17 00:00:00 2001 From: Bradley Allen Date: Wed, 9 Sep 2020 17:30:08 +0000 Subject: [PATCH 380/536] docs: Added links to the Android 11 summary pages on developer.android.com. Test: http://go/forrest-run/L06800000688439076 Bug: 163618180 Change-Id: Ibe136020df4ef60183f3726fc0f6336b58c37f99 --- core/java/android/os/Build.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 49a1cb588a3e..bde332792e18 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -1021,6 +1021,18 @@ public class Build { /** * R. + * + *

    Applications targeting this or a later release will get these new changes in behavior. + * For more information about this release, see the + * Android 11 overview.

    + * + * */ public static final int R = 30; } -- GitLab From 238de217662d27688c644ddcd523bf12b3404d9e Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Wed, 2 Sep 2020 16:32:09 -0400 Subject: [PATCH 381/536] Add screenshot back to power menu for some devices Test: atest Bug: 155251236 Change-Id: I190a03385b9136748aa75dbd26ed4556cf81599a (cherry picked from commit 858b4ae2b2ff6870e739192f4046a3ed2f914407) --- core/res/res/values/config.xml | 1 + .../globalactions/GlobalActionsDialog.java | 22 +++++++++++++++++- .../GlobalActionsDialogTest.java | 23 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 39d20bbff3ba..6ca5bf27f54c 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2774,6 +2774,7 @@ power restart logout + screenshot bugreport diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index b2e91643bed2..016ad45f7d75 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -19,6 +19,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS; import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED; @@ -547,7 +548,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, if (!mDeviceProvisioned && !action.showBeforeProvisioning()) { return false; } - return true; + return action.shouldShow(); } /** @@ -962,6 +963,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, @VisibleForTesting class ScreenshotAction extends SinglePressAction implements LongPressAction { + final String KEY_SYSTEM_NAV_2BUTTONS = "system_nav_2buttons"; + public ScreenshotAction() { super(R.drawable.ic_screenshot, R.string.global_action_screenshot); } @@ -993,6 +996,19 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, return false; } + @Override + public boolean shouldShow() { + // Include screenshot in power menu for legacy nav because it is not accessible + // through Recents in that mode + return is2ButtonNavigationEnabled(); + } + + boolean is2ButtonNavigationEnabled() { + return NAV_BAR_MODE_2BUTTON == mContext.getResources().getInteger( + com.android.internal.R.integer.config_navBarInteractionMode); + } + + @Override public boolean onLongPress() { if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SCREENRECORD_LONG_PRESS)) { @@ -1616,6 +1632,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, * @return */ CharSequence getMessage(); + + default boolean shouldShow() { + return true; + } } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java index ac8c6710e041..5e2e7c075043 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java @@ -49,6 +49,7 @@ import android.testing.TestableLooper; import android.util.FeatureFlagUtils; import android.view.IWindowManager; import android.view.View; +import android.view.WindowManagerPolicyConstants; import android.widget.FrameLayout; import androidx.test.filters.SmallTest; @@ -241,6 +242,28 @@ public class GlobalActionsDialogTest extends SysuiTestCase { verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS); } + @Test + public void testShouldShowScreenshot() { + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.integer.config_navBarInteractionMode, + WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON); + + GlobalActionsDialog.ScreenshotAction screenshotAction = + mGlobalActionsDialog.makeScreenshotActionForTesting(); + assertThat(screenshotAction.shouldShow()).isTrue(); + } + + @Test + public void testShouldNotShowScreenshot() { + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.integer.config_navBarInteractionMode, + WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON); + + GlobalActionsDialog.ScreenshotAction screenshotAction = + mGlobalActionsDialog.makeScreenshotActionForTesting(); + assertThat(screenshotAction.shouldShow()).isFalse(); + } + private void verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent event) { mTestableLooper.processAllMessages(); verify(mUiEventLogger, times(1)) -- GitLab From 7f60f432fbfac7ed1e258c32d278d2f27657994b Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Sun, 30 Dec 2018 18:00:37 -0800 Subject: [PATCH 382/536] [WIFI] Make Aware + Connectivity agent network specifiers sensitive Configure the Wi-Fi Aware agent network specifier as sensitive. This will strip it out from the network capabilities before the capabilities are forwarded to the app. Necessary since the agent network specifier contains information which the apps should not have. Bug: 161853197 Bug: 161370134 Test: atest ConnectivityServiceTest (frameworks/base/tests/net) Test: atest frameworks/base/tests/net Test: atest frameworks/opt/net/wifi/tests/wifitests Test: atest frameworks/opt/telephony/tests/telephonytests Test: atest frameworks/opt/net/ethernet/tests Test: atest android.net.cts - some flakiness! Test: act.py ThroughputTest Test: act.py DataPathTest Test: atest SingleDeviceTest (cts) Change-Id: Ia6adf2afa0f2052dc46a504ceb3e5aaba591aab8 Merged-In: I9673107a2ee13bca63539fc7dbee7f376af3ebcb --- .../net/wifi/aware/WifiAwareAgentNetworkSpecifier.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java index 7c99c497c54b..6b1485356dc2 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java @@ -149,6 +149,11 @@ public class WifiAwareAgentNetworkSpecifier extends NetworkSpecifier implements "WifiAwareAgentNetworkSpecifier should not be used in network requests"); } + @Override + public NetworkSpecifier redact() { + return null; + } + private void initialize() { try { mDigester = MessageDigest.getInstance("SHA-256"); -- GitLab From beb3609dbbf2ce03b60441d7e9e09c92c2aaae5d Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 10 Sep 2020 02:47:45 +0000 Subject: [PATCH 383/536] Remove unit test changes added in "[Suggestion] Fix setWpa3EnterpriseConfig" in rvc-qpr-dev This partially reverts commit 08744836fe65f37236d0020b1dd857195627d02c. Reason for revert: Unit tests are out of sync with prebuilt Wifi mainline module Bug: 168158154 Change-Id: I0cda9de836b6f00a06474515f17e67194c6246cd Test: Treehugger Merged-In: I875d0d0584d71fe6dd3fedc8f5371e0b5ed2e5e5 --- wifi/tests/src/android/net/wifi/FakeKeys.java | 413 +----------------- .../net/wifi/WifiNetworkSpecifierTest.java | 105 ----- .../net/wifi/WifiNetworkSuggestionTest.java | 78 +--- 3 files changed, 6 insertions(+), 590 deletions(-) diff --git a/wifi/tests/src/android/net/wifi/FakeKeys.java b/wifi/tests/src/android/net/wifi/FakeKeys.java index 8aa6add4a4e4..641b891a1f4d 100644 --- a/wifi/tests/src/android/net/wifi/FakeKeys.java +++ b/wifi/tests/src/android/net/wifi/FakeKeys.java @@ -212,57 +212,7 @@ public class FakeKeys { (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1, (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51 }; - public static final PrivateKey RSA_KEY1 = loadPrivateKey("RSA", FAKE_RSA_KEY_1); - - private static final String CA_SUITE_B_RSA3072_CERT_STRING = - "-----BEGIN CERTIFICATE-----\n" - + "MIIEnTCCAwWgAwIBAgIUD87Y8fFLzLr1HQ/64aEnjNq2R/4wDQYJKoZIhvcNAQEM\n" - + "BQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAO\n" - + "BgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0\n" - + "Q0EwHhcNMjAwNzIxMDIxNzU0WhcNMzAwNTMwMDIxNzU0WjBeMQswCQYDVQQGEwJV\n" - + "UzELMAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEO\n" - + "MAwGA1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTCCAaIwDQYJKoZIhvcN\n" - + "AQEBBQADggGPADCCAYoCggGBAMtrsT0otlxh0QS079KpRRbU1PQjCihSoltXnrxF\n" - + "sTWZs2weVEeYVyYU5LaauCDDgISCMtjtfbfylMBeYjpWB5hYzYQOiTzo0anWhMyb\n" - + "Ngb7gpMVZuIl6lwMYRyVRKwHWnTo2EUg1ZzW5rGe5fs/KHj6//hoNFm+3Oju0TQd\n" - + "nraQULpoERPF5B7p85Cssk8uNbviBfZXvtCuJ4N6w7PNceOY/9bbwc1mC+pPZmzV\n" - + "SOAg0vvbIQRzChm63C3jBC3xmxSOOZVrKN4zKDG2s8P0oCNGt0NlgRMrgbPRekzg\n" - + "4avkbA0vTuc2AyriTEYkdea/Mt4EpRg9XuOb43U/GJ/d/vQv2/9fsxhXmsZrn8kr\n" - + "Qo5MMHJFUd96GgHmvYSU3Mf/5r8gF626lvqHioGuTAuHUSnr02ri1WUxZ15LDRgY\n" - + "quMjDCFZfucjJPDAdtiHcFSej/4SLJlN39z8oKKNPn3aL9Gv49oAKs9S8tfDVzMk\n" - + "fDLROQFHFuW715GnnMgEAoOpRwIDAQABo1MwUTAdBgNVHQ4EFgQUeVuGmSVN4ARs\n" - + "mesUMWSJ2qWLbxUwHwYDVR0jBBgwFoAUeVuGmSVN4ARsmesUMWSJ2qWLbxUwDwYD\n" - + "VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQwFAAOCAYEAit1Lo/hegZpPuT9dlWZJ\n" - + "bC8JvAf95O8lnn6LFb69pgYOHCLgCIlvYXu9rdBUJgZo+V1MzJJljiO6RxWRfKbQ\n" - + "8WBYkoqR1EqriR3Kn8q/SjIZCdFSaznTyU1wQMveBQ6RJWXSUhYVfE9RjyFTp7B4\n" - + "UyH2uCluR/0T06HQNGfH5XpIYQqCk1Zgng5lmEmheLDPoJpa92lKeQFJMC6eYz9g\n" - + "lF1GHxPxkPfbMJ6ZDp5X6Yopu6Q6uEXhVKM/iQVcgzRkx9rid+xTYl+nOKyK/XfC\n" - + "z8P0/TFIoPTW02DLge5wKagdoCpy1B7HdrAXyUjoH4B8MsUkq3kYPFSjPzScuTtV\n" - + "kUuDw5ipCNeXCRnhbYqRDk6PX5GUu2cmN9jtaH3tbgm3fKNOsd/BO1fLIl7qjXlR\n" - + "27HHbC0JXjNvlm2DLp23v4NTxS7WZGYsxyUj5DZrxBxqCsTXu/01w1BrQKWKh9FM\n" - + "aVrlA8omfVODK2CSuw+KhEMHepRv/AUgsLl4L4+RMoa+\n" - + "-----END CERTIFICATE-----\n"; - public static final X509Certificate CA_SUITE_B_RSA3072_CERT = - loadCertificate(CA_SUITE_B_RSA3072_CERT_STRING); - - private static final String CA_SUITE_B_ECDSA_CERT_STRING = - "-----BEGIN CERTIFICATE-----\n" - + "MIICTzCCAdSgAwIBAgIUdnLttwNPnQzFufplGOr9bTrGCqMwCgYIKoZIzj0EAwMw\n" - + "XjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNV\n" - + "BAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0Q0Ew\n" - + "HhcNMjAwNzIxMDIyNDA1WhcNMzAwNTMwMDIyNDA1WjBeMQswCQYDVQQGEwJVUzEL\n" - + "MAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEOMAwG\n" - + "A1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTB2MBAGByqGSM49AgEGBSuB\n" - + "BAAiA2IABFmntXwk9icqhDQFUP1xy04WyEpaGW4q6Q+8pujlSl/X3iotPZ++GZfp\n" - + "Mfv3YDHDBl6sELPQ2BEjyPXmpsKjOUdiUe69e88oGEdeqT2xXiQ6uzpTfJD4170i\n" - + "O/TwLrQGKKNTMFEwHQYDVR0OBBYEFCjptsX3g4g5W0L4oEP6N3gfyiZXMB8GA1Ud\n" - + "IwQYMBaAFCjptsX3g4g5W0L4oEP6N3gfyiZXMA8GA1UdEwEB/wQFMAMBAf8wCgYI\n" - + "KoZIzj0EAwMDaQAwZgIxAK61brUYRbLmQKiaEboZgrHtnPAcGo7Yzx3MwHecx3Dm\n" - + "5soIeLVYc8bPYN1pbhXW1gIxALdEe2sh03nBHyQH4adYoZungoCwt8mp/7sJFxou\n" - + "9UnRegyBgGzf74ROWdpZHzh+Pg==\n" - + "-----END CERTIFICATE-----\n"; - public static final X509Certificate CA_SUITE_B_ECDSA_CERT = - loadCertificate(CA_SUITE_B_ECDSA_CERT_STRING); + public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1); private static final String CLIENT_SUITE_B_RSA3072_CERT_STRING = "-----BEGIN CERTIFICATE-----\n" @@ -293,363 +243,6 @@ public class FakeKeys { public static final X509Certificate CLIENT_SUITE_B_RSA3072_CERT = loadCertificate(CLIENT_SUITE_B_RSA3072_CERT_STRING); - private static final byte[] CLIENT_SUITE_B_RSA3072_KEY_DATA = new byte[]{ - (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xfe, (byte) 0x02, (byte) 0x01, - (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, - (byte) 0x06, (byte) 0xe8, (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xe4, - (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x82, (byte) 0x01, - (byte) 0x81, (byte) 0x00, (byte) 0xc1, (byte) 0x22, (byte) 0xb7, (byte) 0x0b, - (byte) 0x92, (byte) 0xb9, (byte) 0xb9, (byte) 0xdb, (byte) 0x42, (byte) 0x29, - (byte) 0x39, (byte) 0xc4, (byte) 0xd7, (byte) 0x87, (byte) 0xbc, (byte) 0xcf, - (byte) 0x67, (byte) 0x19, (byte) 0xbf, (byte) 0x09, (byte) 0x81, (byte) 0xe1, - (byte) 0x77, (byte) 0xbe, (byte) 0x6b, (byte) 0xcf, (byte) 0xbb, (byte) 0x40, - (byte) 0xbb, (byte) 0x9d, (byte) 0x1e, (byte) 0x8a, (byte) 0x1c, (byte) 0xfe, - (byte) 0x54, (byte) 0x33, (byte) 0x0a, (byte) 0x58, (byte) 0x0a, (byte) 0xe0, - (byte) 0xc6, (byte) 0xd5, (byte) 0x50, (byte) 0x2d, (byte) 0x03, (byte) 0xdc, - (byte) 0x51, (byte) 0x3e, (byte) 0x53, (byte) 0x7d, (byte) 0x82, (byte) 0xef, - (byte) 0xc4, (byte) 0xb1, (byte) 0x2a, (byte) 0x84, (byte) 0xda, (byte) 0x45, - (byte) 0x6b, (byte) 0x6f, (byte) 0x3e, (byte) 0x63, (byte) 0x66, (byte) 0xf9, - (byte) 0x46, (byte) 0x85, (byte) 0x4f, (byte) 0xc2, (byte) 0xa4, (byte) 0xc3, - (byte) 0x25, (byte) 0x27, (byte) 0xa3, (byte) 0xf7, (byte) 0x6f, (byte) 0xfb, - (byte) 0x65, (byte) 0xc3, (byte) 0xa5, (byte) 0xdf, (byte) 0xf3, (byte) 0x01, - (byte) 0x14, (byte) 0x3e, (byte) 0xdc, (byte) 0x5c, (byte) 0x00, (byte) 0x7d, - (byte) 0x6a, (byte) 0x29, (byte) 0x02, (byte) 0x11, (byte) 0x32, (byte) 0x09, - (byte) 0x54, (byte) 0xb1, (byte) 0xc2, (byte) 0xc0, (byte) 0x9a, (byte) 0xfa, - (byte) 0xc9, (byte) 0x50, (byte) 0xe2, (byte) 0x3b, (byte) 0x91, (byte) 0x20, - (byte) 0xc2, (byte) 0x2e, (byte) 0x50, (byte) 0x2d, (byte) 0x4c, (byte) 0x9b, - (byte) 0x43, (byte) 0x5a, (byte) 0xa6, (byte) 0xd6, (byte) 0x72, (byte) 0x33, - (byte) 0x74, (byte) 0xe3, (byte) 0xfc, (byte) 0x80, (byte) 0x90, (byte) 0x11, - (byte) 0xfa, (byte) 0x64, (byte) 0xa3, (byte) 0xda, (byte) 0x95, (byte) 0x21, - (byte) 0xb8, (byte) 0x8a, (byte) 0xe9, (byte) 0xea, (byte) 0x09, (byte) 0x31, - (byte) 0x39, (byte) 0x18, (byte) 0xf0, (byte) 0x45, (byte) 0x9f, (byte) 0x02, - (byte) 0x7e, (byte) 0xd1, (byte) 0x4c, (byte) 0x57, (byte) 0x5f, (byte) 0x47, - (byte) 0x53, (byte) 0x8b, (byte) 0xb8, (byte) 0xed, (byte) 0x26, (byte) 0x54, - (byte) 0xe8, (byte) 0xe0, (byte) 0x2d, (byte) 0x6f, (byte) 0x7f, (byte) 0xfa, - (byte) 0xea, (byte) 0x58, (byte) 0xbf, (byte) 0xa8, (byte) 0x59, (byte) 0xd7, - (byte) 0xd9, (byte) 0xc0, (byte) 0x30, (byte) 0x0c, (byte) 0x70, (byte) 0xe1, - (byte) 0x04, (byte) 0xc9, (byte) 0xc7, (byte) 0xb9, (byte) 0x4b, (byte) 0xc0, - (byte) 0x02, (byte) 0xd7, (byte) 0xec, (byte) 0x1f, (byte) 0xad, (byte) 0x0d, - (byte) 0x83, (byte) 0x44, (byte) 0x64, (byte) 0x70, (byte) 0xea, (byte) 0x60, - (byte) 0xbd, (byte) 0xb3, (byte) 0xca, (byte) 0xf4, (byte) 0x16, (byte) 0x02, - (byte) 0x3d, (byte) 0x87, (byte) 0x0a, (byte) 0x57, (byte) 0xab, (byte) 0x7b, - (byte) 0xc4, (byte) 0x18, (byte) 0x20, (byte) 0xbc, (byte) 0x64, (byte) 0xbe, - (byte) 0x4b, (byte) 0x60, (byte) 0x06, (byte) 0x0d, (byte) 0x9c, (byte) 0xac, - (byte) 0x42, (byte) 0x49, (byte) 0x7b, (byte) 0x85, (byte) 0xdb, (byte) 0x0c, - (byte) 0x7e, (byte) 0xcb, (byte) 0x03, (byte) 0x7a, (byte) 0xeb, (byte) 0x5e, - (byte) 0x6b, (byte) 0x22, (byte) 0xa9, (byte) 0xfd, (byte) 0x59, (byte) 0x6d, - (byte) 0xf1, (byte) 0x45, (byte) 0x13, (byte) 0x32, (byte) 0xbd, (byte) 0x34, - (byte) 0x5a, (byte) 0xa8, (byte) 0xbc, (byte) 0xbf, (byte) 0xaa, (byte) 0x1a, - (byte) 0x1f, (byte) 0xb3, (byte) 0x20, (byte) 0xff, (byte) 0xb9, (byte) 0xf3, - (byte) 0xc4, (byte) 0xa1, (byte) 0x24, (byte) 0x53, (byte) 0xbd, (byte) 0x1f, - (byte) 0xf4, (byte) 0x43, (byte) 0x9c, (byte) 0x3a, (byte) 0x62, (byte) 0x4e, - (byte) 0x70, (byte) 0x05, (byte) 0x4d, (byte) 0x65, (byte) 0xd0, (byte) 0x75, - (byte) 0x3c, (byte) 0x20, (byte) 0xb3, (byte) 0x34, (byte) 0x92, (byte) 0xd1, - (byte) 0x5c, (byte) 0x36, (byte) 0x3c, (byte) 0x1f, (byte) 0x89, (byte) 0xa8, - (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0xaf, (byte) 0x43, (byte) 0x78, - (byte) 0xcb, (byte) 0xd7, (byte) 0x4f, (byte) 0x53, (byte) 0xb2, (byte) 0xf8, - (byte) 0xd6, (byte) 0x37, (byte) 0x22, (byte) 0xd3, (byte) 0xc7, (byte) 0xcb, - (byte) 0x2e, (byte) 0xb7, (byte) 0x9d, (byte) 0x06, (byte) 0x55, (byte) 0x23, - (byte) 0x6a, (byte) 0xd7, (byte) 0x00, (byte) 0xdc, (byte) 0x38, (byte) 0x36, - (byte) 0x1c, (byte) 0x12, (byte) 0xd1, (byte) 0x9e, (byte) 0x83, (byte) 0x17, - (byte) 0xe4, (byte) 0x2c, (byte) 0x4c, (byte) 0xda, (byte) 0xe3, (byte) 0xf8, - (byte) 0x65, (byte) 0x3b, (byte) 0x7b, (byte) 0x84, (byte) 0x86, (byte) 0xfc, - (byte) 0x41, (byte) 0x91, (byte) 0xf1, (byte) 0x2b, (byte) 0xe5, (byte) 0x76, - (byte) 0x36, (byte) 0x1f, (byte) 0x41, (byte) 0x35, (byte) 0x85, (byte) 0x2e, - (byte) 0x0d, (byte) 0x65, (byte) 0xfd, (byte) 0x44, (byte) 0xf5, (byte) 0x84, - (byte) 0xe3, (byte) 0xa4, (byte) 0x41, (byte) 0x9c, (byte) 0x1d, (byte) 0xb1, - (byte) 0xa5, (byte) 0xb5, (byte) 0xce, (byte) 0x02, (byte) 0xb2, (byte) 0x7a, - (byte) 0xe8, (byte) 0x85, (byte) 0x07, (byte) 0x62, (byte) 0x9d, (byte) 0x32, - (byte) 0x66, (byte) 0xc0, (byte) 0x4a, (byte) 0xaf, (byte) 0x94, (byte) 0xc7, - (byte) 0x52, (byte) 0xf5, (byte) 0x28, (byte) 0x80, (byte) 0xa8, (byte) 0xd0, - (byte) 0x88, (byte) 0x25, (byte) 0xc1, (byte) 0x67, (byte) 0x01, (byte) 0xff, - (byte) 0xc9, (byte) 0xe7, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, - (byte) 0x01, (byte) 0x02, (byte) 0x82, (byte) 0x01, (byte) 0x80, (byte) 0x04, - (byte) 0xb1, (byte) 0xcc, (byte) 0x53, (byte) 0x3a, (byte) 0xb0, (byte) 0xcb, - (byte) 0x04, (byte) 0xba, (byte) 0x59, (byte) 0xf8, (byte) 0x2e, (byte) 0x81, - (byte) 0xb2, (byte) 0xa9, (byte) 0xf3, (byte) 0x3c, (byte) 0xa5, (byte) 0x52, - (byte) 0x90, (byte) 0x6f, (byte) 0x98, (byte) 0xc4, (byte) 0x69, (byte) 0x5b, - (byte) 0x83, (byte) 0x84, (byte) 0x20, (byte) 0xb1, (byte) 0xae, (byte) 0xc3, - (byte) 0x04, (byte) 0x46, (byte) 0x6a, (byte) 0x24, (byte) 0x2f, (byte) 0xcd, - (byte) 0x6b, (byte) 0x90, (byte) 0x70, (byte) 0x20, (byte) 0x45, (byte) 0x25, - (byte) 0x1a, (byte) 0xc3, (byte) 0x02, (byte) 0x42, (byte) 0xf3, (byte) 0x49, - (byte) 0xe2, (byte) 0x3e, (byte) 0x21, (byte) 0x87, (byte) 0xdd, (byte) 0x6a, - (byte) 0x94, (byte) 0x2a, (byte) 0x1e, (byte) 0x0f, (byte) 0xdb, (byte) 0x77, - (byte) 0x5f, (byte) 0xc1, (byte) 0x2c, (byte) 0x03, (byte) 0xfb, (byte) 0xcf, - (byte) 0x91, (byte) 0x82, (byte) 0xa1, (byte) 0xbf, (byte) 0xb0, (byte) 0x73, - (byte) 0xfa, (byte) 0xda, (byte) 0xbc, (byte) 0xf8, (byte) 0x9f, (byte) 0x45, - (byte) 0xd3, (byte) 0xe8, (byte) 0xbb, (byte) 0x38, (byte) 0xfb, (byte) 0xc2, - (byte) 0x2d, (byte) 0x76, (byte) 0x51, (byte) 0x96, (byte) 0x18, (byte) 0x03, - (byte) 0x15, (byte) 0xd9, (byte) 0xea, (byte) 0x82, (byte) 0x25, (byte) 0x83, - (byte) 0xff, (byte) 0x5c, (byte) 0x85, (byte) 0x06, (byte) 0x09, (byte) 0xb2, - (byte) 0x46, (byte) 0x12, (byte) 0x64, (byte) 0x02, (byte) 0x74, (byte) 0x4f, - (byte) 0xbc, (byte) 0x9a, (byte) 0x25, (byte) 0x18, (byte) 0x01, (byte) 0x07, - (byte) 0x17, (byte) 0x25, (byte) 0x55, (byte) 0x7c, (byte) 0xdc, (byte) 0xe1, - (byte) 0xd1, (byte) 0x5a, (byte) 0x2f, (byte) 0x25, (byte) 0xaf, (byte) 0xf6, - (byte) 0x8f, (byte) 0xa4, (byte) 0x9a, (byte) 0x5a, (byte) 0x3a, (byte) 0xfe, - (byte) 0x2e, (byte) 0x93, (byte) 0x24, (byte) 0xa0, (byte) 0x27, (byte) 0xac, - (byte) 0x07, (byte) 0x75, (byte) 0x33, (byte) 0x01, (byte) 0x54, (byte) 0x23, - (byte) 0x0f, (byte) 0xe8, (byte) 0x9f, (byte) 0xfa, (byte) 0x36, (byte) 0xe6, - (byte) 0x3a, (byte) 0xd5, (byte) 0x78, (byte) 0xb0, (byte) 0xe4, (byte) 0x6a, - (byte) 0x16, (byte) 0x50, (byte) 0xbd, (byte) 0x0f, (byte) 0x9f, (byte) 0x32, - (byte) 0xa1, (byte) 0x6b, (byte) 0xf5, (byte) 0xa4, (byte) 0x34, (byte) 0x58, - (byte) 0xb6, (byte) 0xa4, (byte) 0xb3, (byte) 0xc3, (byte) 0x83, (byte) 0x08, - (byte) 0x18, (byte) 0xc7, (byte) 0xef, (byte) 0x95, (byte) 0xe2, (byte) 0x1b, - (byte) 0xba, (byte) 0x35, (byte) 0x61, (byte) 0xa3, (byte) 0xb4, (byte) 0x30, - (byte) 0xe0, (byte) 0xd1, (byte) 0xc1, (byte) 0xa2, (byte) 0x3a, (byte) 0xc6, - (byte) 0xb4, (byte) 0xd2, (byte) 0x80, (byte) 0x5a, (byte) 0xaf, (byte) 0xa4, - (byte) 0x54, (byte) 0x3c, (byte) 0x66, (byte) 0x5a, (byte) 0x1c, (byte) 0x4d, - (byte) 0xe1, (byte) 0xd9, (byte) 0x98, (byte) 0x44, (byte) 0x01, (byte) 0x1b, - (byte) 0x8c, (byte) 0xe9, (byte) 0x80, (byte) 0x54, (byte) 0x83, (byte) 0x3d, - (byte) 0x96, (byte) 0x25, (byte) 0x41, (byte) 0x1c, (byte) 0xad, (byte) 0xae, - (byte) 0x3b, (byte) 0x7a, (byte) 0xd7, (byte) 0x9d, (byte) 0x10, (byte) 0x7c, - (byte) 0xd1, (byte) 0xa7, (byte) 0x96, (byte) 0x39, (byte) 0xa5, (byte) 0x2f, - (byte) 0xbe, (byte) 0xc3, (byte) 0x2c, (byte) 0x64, (byte) 0x01, (byte) 0xfe, - (byte) 0xa2, (byte) 0xd1, (byte) 0x6a, (byte) 0xcf, (byte) 0x4c, (byte) 0x76, - (byte) 0x3b, (byte) 0xc8, (byte) 0x35, (byte) 0x21, (byte) 0xda, (byte) 0x98, - (byte) 0xcf, (byte) 0xf9, (byte) 0x29, (byte) 0xff, (byte) 0x30, (byte) 0x59, - (byte) 0x36, (byte) 0x53, (byte) 0x0b, (byte) 0xbb, (byte) 0xfa, (byte) 0xba, - (byte) 0xc4, (byte) 0x03, (byte) 0x23, (byte) 0xe0, (byte) 0xd3, (byte) 0x33, - (byte) 0xff, (byte) 0x32, (byte) 0xdb, (byte) 0x30, (byte) 0x64, (byte) 0xc7, - (byte) 0x56, (byte) 0xca, (byte) 0x55, (byte) 0x14, (byte) 0xee, (byte) 0x58, - (byte) 0xfe, (byte) 0x96, (byte) 0x7e, (byte) 0x1c, (byte) 0x34, (byte) 0x16, - (byte) 0xeb, (byte) 0x76, (byte) 0x26, (byte) 0x48, (byte) 0xe2, (byte) 0xe5, - (byte) 0x5c, (byte) 0xd5, (byte) 0x83, (byte) 0x37, (byte) 0xd9, (byte) 0x09, - (byte) 0x71, (byte) 0xbc, (byte) 0x54, (byte) 0x25, (byte) 0xca, (byte) 0x2e, - (byte) 0xdb, (byte) 0x36, (byte) 0x39, (byte) 0xcc, (byte) 0x3a, (byte) 0x81, - (byte) 0x95, (byte) 0x9e, (byte) 0xf4, (byte) 0x01, (byte) 0xa7, (byte) 0xc0, - (byte) 0x20, (byte) 0xce, (byte) 0x70, (byte) 0x55, (byte) 0x2c, (byte) 0xe0, - (byte) 0x93, (byte) 0x72, (byte) 0xa6, (byte) 0x25, (byte) 0xda, (byte) 0x64, - (byte) 0x19, (byte) 0x18, (byte) 0xd2, (byte) 0x31, (byte) 0xe2, (byte) 0x7c, - (byte) 0xf2, (byte) 0x30, (byte) 0x9e, (byte) 0x8d, (byte) 0xc6, (byte) 0x14, - (byte) 0x8a, (byte) 0x38, (byte) 0xf0, (byte) 0x94, (byte) 0xeb, (byte) 0xf4, - (byte) 0x64, (byte) 0x92, (byte) 0x3d, (byte) 0x67, (byte) 0xa6, (byte) 0x2c, - (byte) 0x52, (byte) 0xfc, (byte) 0x60, (byte) 0xca, (byte) 0x2a, (byte) 0xcf, - (byte) 0x24, (byte) 0xd5, (byte) 0x42, (byte) 0x5f, (byte) 0xc7, (byte) 0x9f, - (byte) 0xf3, (byte) 0xb4, (byte) 0xdf, (byte) 0x76, (byte) 0x6e, (byte) 0x53, - (byte) 0xa1, (byte) 0x7b, (byte) 0xae, (byte) 0xa5, (byte) 0x84, (byte) 0x1f, - (byte) 0xfa, (byte) 0xc0, (byte) 0xb4, (byte) 0x6c, (byte) 0xc9, (byte) 0x02, - (byte) 0x81, (byte) 0xc1, (byte) 0x00, (byte) 0xf3, (byte) 0x17, (byte) 0xd9, - (byte) 0x48, (byte) 0x17, (byte) 0x87, (byte) 0x84, (byte) 0x16, (byte) 0xea, - (byte) 0x2d, (byte) 0x31, (byte) 0x1b, (byte) 0xce, (byte) 0xec, (byte) 0xaf, - (byte) 0xdc, (byte) 0x6b, (byte) 0xaf, (byte) 0xc8, (byte) 0xf1, (byte) 0x40, - (byte) 0xa7, (byte) 0x4f, (byte) 0xef, (byte) 0x48, (byte) 0x08, (byte) 0x5e, - (byte) 0x9a, (byte) 0xd1, (byte) 0xc0, (byte) 0xb1, (byte) 0xfe, (byte) 0xe7, - (byte) 0x03, (byte) 0xd5, (byte) 0x96, (byte) 0x01, (byte) 0xe8, (byte) 0x40, - (byte) 0xca, (byte) 0x78, (byte) 0xcb, (byte) 0xb3, (byte) 0x28, (byte) 0x1a, - (byte) 0xf0, (byte) 0xe5, (byte) 0xf6, (byte) 0x46, (byte) 0xef, (byte) 0xcd, - (byte) 0x1a, (byte) 0x0f, (byte) 0x13, (byte) 0x2d, (byte) 0x38, (byte) 0xf8, - (byte) 0xf7, (byte) 0x88, (byte) 0x21, (byte) 0x15, (byte) 0xce, (byte) 0x48, - (byte) 0xf4, (byte) 0x92, (byte) 0x7e, (byte) 0x9b, (byte) 0x2e, (byte) 0x2f, - (byte) 0x22, (byte) 0x3e, (byte) 0x5c, (byte) 0x67, (byte) 0xd7, (byte) 0x58, - (byte) 0xf6, (byte) 0xef, (byte) 0x1f, (byte) 0xb4, (byte) 0x04, (byte) 0xc7, - (byte) 0xfd, (byte) 0x8c, (byte) 0x4e, (byte) 0x27, (byte) 0x9e, (byte) 0xb9, - (byte) 0xef, (byte) 0x0f, (byte) 0xf7, (byte) 0x4a, (byte) 0xc2, (byte) 0xf4, - (byte) 0x64, (byte) 0x6b, (byte) 0xe0, (byte) 0xfb, (byte) 0xe3, (byte) 0x45, - (byte) 0xd5, (byte) 0x37, (byte) 0xa0, (byte) 0x2a, (byte) 0xc6, (byte) 0xf3, - (byte) 0xf6, (byte) 0xcc, (byte) 0xb5, (byte) 0x94, (byte) 0xbf, (byte) 0x56, - (byte) 0xa0, (byte) 0x61, (byte) 0x36, (byte) 0x88, (byte) 0x35, (byte) 0xd5, - (byte) 0xa5, (byte) 0xad, (byte) 0x20, (byte) 0x48, (byte) 0xda, (byte) 0x70, - (byte) 0x35, (byte) 0xd9, (byte) 0x75, (byte) 0x66, (byte) 0xa5, (byte) 0xac, - (byte) 0x86, (byte) 0x7a, (byte) 0x75, (byte) 0x49, (byte) 0x88, (byte) 0x40, - (byte) 0xce, (byte) 0xb0, (byte) 0x6f, (byte) 0x57, (byte) 0x15, (byte) 0x54, - (byte) 0xd3, (byte) 0x2f, (byte) 0x11, (byte) 0x9b, (byte) 0xe3, (byte) 0x87, - (byte) 0xc8, (byte) 0x8d, (byte) 0x98, (byte) 0xc6, (byte) 0xe0, (byte) 0xbc, - (byte) 0x85, (byte) 0xb9, (byte) 0x04, (byte) 0x43, (byte) 0xa9, (byte) 0x41, - (byte) 0xce, (byte) 0x42, (byte) 0x1a, (byte) 0x57, (byte) 0x10, (byte) 0xd8, - (byte) 0xe4, (byte) 0x6a, (byte) 0x51, (byte) 0x10, (byte) 0x0a, (byte) 0xec, - (byte) 0xe4, (byte) 0x57, (byte) 0xc7, (byte) 0xee, (byte) 0xe9, (byte) 0xd6, - (byte) 0xcb, (byte) 0x3e, (byte) 0xba, (byte) 0xfa, (byte) 0xe9, (byte) 0x0e, - (byte) 0xed, (byte) 0x87, (byte) 0x04, (byte) 0x9a, (byte) 0x48, (byte) 0xba, - (byte) 0xaf, (byte) 0x08, (byte) 0xf5, (byte) 0x02, (byte) 0x81, (byte) 0xc1, - (byte) 0x00, (byte) 0xcb, (byte) 0x63, (byte) 0xd6, (byte) 0x54, (byte) 0xb6, - (byte) 0xf3, (byte) 0xf3, (byte) 0x8c, (byte) 0xf8, (byte) 0xd0, (byte) 0xd2, - (byte) 0x84, (byte) 0xc1, (byte) 0xf5, (byte) 0x12, (byte) 0xe0, (byte) 0x02, - (byte) 0x80, (byte) 0x42, (byte) 0x92, (byte) 0x4e, (byte) 0xa4, (byte) 0x5c, - (byte) 0xa5, (byte) 0x64, (byte) 0xec, (byte) 0xb7, (byte) 0xdc, (byte) 0xe0, - (byte) 0x2d, (byte) 0x5d, (byte) 0xac, (byte) 0x0e, (byte) 0x24, (byte) 0x48, - (byte) 0x13, (byte) 0x05, (byte) 0xe8, (byte) 0xff, (byte) 0x96, (byte) 0x93, - (byte) 0xba, (byte) 0x3c, (byte) 0x88, (byte) 0xcc, (byte) 0x80, (byte) 0xf9, - (byte) 0xdb, (byte) 0xa8, (byte) 0x4d, (byte) 0x86, (byte) 0x47, (byte) 0xc8, - (byte) 0xbf, (byte) 0x34, (byte) 0x2d, (byte) 0xda, (byte) 0xb6, (byte) 0x28, - (byte) 0xf0, (byte) 0x1e, (byte) 0xd2, (byte) 0x46, (byte) 0x0d, (byte) 0x6f, - (byte) 0x36, (byte) 0x8e, (byte) 0x84, (byte) 0xd8, (byte) 0xaf, (byte) 0xf7, - (byte) 0x69, (byte) 0x23, (byte) 0x77, (byte) 0xfb, (byte) 0xc5, (byte) 0x04, - (byte) 0x08, (byte) 0x18, (byte) 0xac, (byte) 0x85, (byte) 0x80, (byte) 0x87, - (byte) 0x1c, (byte) 0xfe, (byte) 0x8e, (byte) 0x5d, (byte) 0x00, (byte) 0x7f, - (byte) 0x5b, (byte) 0x33, (byte) 0xf5, (byte) 0xdf, (byte) 0x70, (byte) 0x81, - (byte) 0xad, (byte) 0x81, (byte) 0xf4, (byte) 0x5a, (byte) 0x37, (byte) 0x8a, - (byte) 0x79, (byte) 0x09, (byte) 0xc5, (byte) 0x55, (byte) 0xab, (byte) 0x58, - (byte) 0x7c, (byte) 0x47, (byte) 0xca, (byte) 0xa5, (byte) 0x80, (byte) 0x49, - (byte) 0x5f, (byte) 0x71, (byte) 0x83, (byte) 0xfb, (byte) 0x3b, (byte) 0x06, - (byte) 0xec, (byte) 0x75, (byte) 0x23, (byte) 0xc4, (byte) 0x32, (byte) 0xc7, - (byte) 0x18, (byte) 0xf6, (byte) 0x82, (byte) 0x95, (byte) 0x98, (byte) 0x39, - (byte) 0xf7, (byte) 0x92, (byte) 0x31, (byte) 0xc0, (byte) 0x89, (byte) 0xba, - (byte) 0xd4, (byte) 0xd4, (byte) 0x58, (byte) 0x4e, (byte) 0x38, (byte) 0x35, - (byte) 0x10, (byte) 0xb9, (byte) 0xf1, (byte) 0x27, (byte) 0xdc, (byte) 0xff, - (byte) 0xc7, (byte) 0xb2, (byte) 0xba, (byte) 0x1f, (byte) 0x27, (byte) 0xaf, - (byte) 0x99, (byte) 0xd5, (byte) 0xb0, (byte) 0x39, (byte) 0xe7, (byte) 0x43, - (byte) 0x88, (byte) 0xd3, (byte) 0xce, (byte) 0x38, (byte) 0xc2, (byte) 0x99, - (byte) 0x43, (byte) 0xfc, (byte) 0x8a, (byte) 0xe3, (byte) 0x60, (byte) 0x0d, - (byte) 0x0a, (byte) 0xb8, (byte) 0xc4, (byte) 0x29, (byte) 0xca, (byte) 0x0d, - (byte) 0x30, (byte) 0xaf, (byte) 0xca, (byte) 0xd0, (byte) 0xaa, (byte) 0x67, - (byte) 0xb1, (byte) 0xdd, (byte) 0xdb, (byte) 0x7a, (byte) 0x11, (byte) 0xad, - (byte) 0xeb, (byte) 0x02, (byte) 0x81, (byte) 0xc0, (byte) 0x71, (byte) 0xb8, - (byte) 0xcf, (byte) 0x72, (byte) 0x35, (byte) 0x67, (byte) 0xb5, (byte) 0x38, - (byte) 0x8f, (byte) 0x16, (byte) 0xd3, (byte) 0x29, (byte) 0x82, (byte) 0x35, - (byte) 0x21, (byte) 0xd4, (byte) 0x49, (byte) 0x20, (byte) 0x74, (byte) 0x2d, - (byte) 0xc0, (byte) 0xa4, (byte) 0x44, (byte) 0xf5, (byte) 0xd8, (byte) 0xc9, - (byte) 0xe9, (byte) 0x90, (byte) 0x1d, (byte) 0xde, (byte) 0x3a, (byte) 0xa6, - (byte) 0xd7, (byte) 0xe5, (byte) 0xe8, (byte) 0x4e, (byte) 0x83, (byte) 0xd7, - (byte) 0xe6, (byte) 0x2f, (byte) 0x92, (byte) 0x31, (byte) 0x21, (byte) 0x3f, - (byte) 0xfa, (byte) 0xd2, (byte) 0x85, (byte) 0x92, (byte) 0x1f, (byte) 0xff, - (byte) 0x61, (byte) 0x00, (byte) 0xf6, (byte) 0xda, (byte) 0x6e, (byte) 0xc6, - (byte) 0x7f, (byte) 0x5a, (byte) 0x35, (byte) 0x79, (byte) 0xdc, (byte) 0xdc, - (byte) 0xa3, (byte) 0x2e, (byte) 0x9f, (byte) 0x35, (byte) 0xd1, (byte) 0x5c, - (byte) 0xda, (byte) 0xb9, (byte) 0xf7, (byte) 0x58, (byte) 0x7d, (byte) 0x4f, - (byte) 0xb6, (byte) 0x13, (byte) 0xd7, (byte) 0x2c, (byte) 0x0a, (byte) 0xa8, - (byte) 0x4d, (byte) 0xf2, (byte) 0xe4, (byte) 0x67, (byte) 0x4f, (byte) 0x8b, - (byte) 0xa6, (byte) 0xca, (byte) 0x1a, (byte) 0xbb, (byte) 0x02, (byte) 0x63, - (byte) 0x8f, (byte) 0xb7, (byte) 0x46, (byte) 0xec, (byte) 0x7a, (byte) 0x8a, - (byte) 0x09, (byte) 0x0a, (byte) 0x45, (byte) 0x3a, (byte) 0x8d, (byte) 0xa8, - (byte) 0x83, (byte) 0x4b, (byte) 0x0a, (byte) 0xdb, (byte) 0x4b, (byte) 0x99, - (byte) 0xf3, (byte) 0x69, (byte) 0x95, (byte) 0xf0, (byte) 0xcf, (byte) 0xe9, - (byte) 0xf7, (byte) 0x67, (byte) 0xc9, (byte) 0x45, (byte) 0x18, (byte) 0x2f, - (byte) 0xf0, (byte) 0x5c, (byte) 0x90, (byte) 0xbd, (byte) 0xa6, (byte) 0x66, - (byte) 0x8c, (byte) 0xfe, (byte) 0x60, (byte) 0x5d, (byte) 0x6c, (byte) 0x27, - (byte) 0xec, (byte) 0xc1, (byte) 0x84, (byte) 0xb2, (byte) 0xa1, (byte) 0x97, - (byte) 0x9e, (byte) 0x16, (byte) 0x29, (byte) 0xa7, (byte) 0xe0, (byte) 0x38, - (byte) 0xa2, (byte) 0x36, (byte) 0x05, (byte) 0x5f, (byte) 0xda, (byte) 0x72, - (byte) 0x1a, (byte) 0x5f, (byte) 0xa8, (byte) 0x7d, (byte) 0x41, (byte) 0x35, - (byte) 0xf6, (byte) 0x4e, (byte) 0x0a, (byte) 0x88, (byte) 0x8e, (byte) 0x00, - (byte) 0x98, (byte) 0xa6, (byte) 0xca, (byte) 0xc1, (byte) 0xdf, (byte) 0x72, - (byte) 0x6c, (byte) 0xfe, (byte) 0x29, (byte) 0xbe, (byte) 0xa3, (byte) 0x9b, - (byte) 0x0b, (byte) 0x5c, (byte) 0x0b, (byte) 0x9d, (byte) 0xa7, (byte) 0x71, - (byte) 0xce, (byte) 0x04, (byte) 0xfa, (byte) 0xac, (byte) 0x01, (byte) 0x8d, - (byte) 0x52, (byte) 0xa0, (byte) 0x3d, (byte) 0xdd, (byte) 0x02, (byte) 0x81, - (byte) 0xc1, (byte) 0x00, (byte) 0xc1, (byte) 0xc0, (byte) 0x2e, (byte) 0xa9, - (byte) 0xee, (byte) 0xca, (byte) 0xff, (byte) 0xe4, (byte) 0xf8, (byte) 0x15, - (byte) 0xfd, (byte) 0xa5, (byte) 0x68, (byte) 0x1b, (byte) 0x2d, (byte) 0x4a, - (byte) 0xe6, (byte) 0x37, (byte) 0x06, (byte) 0xb3, (byte) 0xd7, (byte) 0x64, - (byte) 0xad, (byte) 0xb9, (byte) 0x05, (byte) 0x26, (byte) 0x97, (byte) 0x94, - (byte) 0x3a, (byte) 0x9e, (byte) 0x1c, (byte) 0xd0, (byte) 0xcd, (byte) 0x7b, - (byte) 0xf4, (byte) 0x88, (byte) 0xe2, (byte) 0xa5, (byte) 0x6d, (byte) 0xed, - (byte) 0x24, (byte) 0x77, (byte) 0x52, (byte) 0x39, (byte) 0x43, (byte) 0x0f, - (byte) 0x4e, (byte) 0x75, (byte) 0xd8, (byte) 0xa3, (byte) 0x59, (byte) 0x5a, - (byte) 0xc2, (byte) 0xba, (byte) 0x9a, (byte) 0x5b, (byte) 0x60, (byte) 0x31, - (byte) 0x0d, (byte) 0x58, (byte) 0x89, (byte) 0x13, (byte) 0xe8, (byte) 0x95, - (byte) 0xdd, (byte) 0xae, (byte) 0xcc, (byte) 0x1f, (byte) 0x73, (byte) 0x48, - (byte) 0x55, (byte) 0xd8, (byte) 0xfb, (byte) 0x67, (byte) 0xce, (byte) 0x18, - (byte) 0x85, (byte) 0x59, (byte) 0xad, (byte) 0x1f, (byte) 0x93, (byte) 0xe1, - (byte) 0xb7, (byte) 0x54, (byte) 0x80, (byte) 0x8e, (byte) 0x5f, (byte) 0xbc, - (byte) 0x1c, (byte) 0x96, (byte) 0x66, (byte) 0x2e, (byte) 0x40, (byte) 0x17, - (byte) 0x2e, (byte) 0x01, (byte) 0x7a, (byte) 0x7d, (byte) 0xaa, (byte) 0xff, - (byte) 0xa3, (byte) 0xd2, (byte) 0xdf, (byte) 0xe2, (byte) 0xf3, (byte) 0x54, - (byte) 0x51, (byte) 0xeb, (byte) 0xba, (byte) 0x7c, (byte) 0x2a, (byte) 0x22, - (byte) 0xc6, (byte) 0x42, (byte) 0xbc, (byte) 0xa1, (byte) 0x6c, (byte) 0xcf, - (byte) 0x73, (byte) 0x2e, (byte) 0x07, (byte) 0xfc, (byte) 0xf5, (byte) 0x67, - (byte) 0x25, (byte) 0xd0, (byte) 0xfa, (byte) 0xeb, (byte) 0xb4, (byte) 0xd4, - (byte) 0x19, (byte) 0xcc, (byte) 0x64, (byte) 0xa1, (byte) 0x2e, (byte) 0x78, - (byte) 0x45, (byte) 0xd9, (byte) 0x7f, (byte) 0x1b, (byte) 0x4c, (byte) 0x10, - (byte) 0x31, (byte) 0x44, (byte) 0xe8, (byte) 0xcc, (byte) 0xf9, (byte) 0x1b, - (byte) 0x87, (byte) 0x31, (byte) 0xd6, (byte) 0x69, (byte) 0x85, (byte) 0x4a, - (byte) 0x49, (byte) 0xf6, (byte) 0xb2, (byte) 0xe0, (byte) 0xb8, (byte) 0x98, - (byte) 0x3c, (byte) 0xf6, (byte) 0x78, (byte) 0x46, (byte) 0xc8, (byte) 0x3d, - (byte) 0x60, (byte) 0xc1, (byte) 0xaa, (byte) 0x2f, (byte) 0x28, (byte) 0xa1, - (byte) 0x14, (byte) 0x6b, (byte) 0x75, (byte) 0x4d, (byte) 0xb1, (byte) 0x3d, - (byte) 0x80, (byte) 0x49, (byte) 0x33, (byte) 0xfd, (byte) 0x71, (byte) 0xc0, - (byte) 0x13, (byte) 0x1e, (byte) 0x16, (byte) 0x69, (byte) 0x80, (byte) 0xa4, - (byte) 0x9c, (byte) 0xd7, (byte) 0x02, (byte) 0x81, (byte) 0xc1, (byte) 0x00, - (byte) 0x8c, (byte) 0x33, (byte) 0x2d, (byte) 0xd9, (byte) 0xf3, (byte) 0x42, - (byte) 0x4d, (byte) 0xca, (byte) 0x5e, (byte) 0x60, (byte) 0x14, (byte) 0x10, - (byte) 0xf6, (byte) 0xf3, (byte) 0x71, (byte) 0x15, (byte) 0x88, (byte) 0x54, - (byte) 0x84, (byte) 0x21, (byte) 0x04, (byte) 0xb1, (byte) 0xaf, (byte) 0x02, - (byte) 0x11, (byte) 0x7f, (byte) 0x42, (byte) 0x3e, (byte) 0x86, (byte) 0xcb, - (byte) 0x6c, (byte) 0xf5, (byte) 0x57, (byte) 0x78, (byte) 0x4a, (byte) 0x03, - (byte) 0x9b, (byte) 0x80, (byte) 0xc2, (byte) 0x04, (byte) 0x3a, (byte) 0x6b, - (byte) 0xb3, (byte) 0x30, (byte) 0x31, (byte) 0x7e, (byte) 0xc3, (byte) 0x89, - (byte) 0x09, (byte) 0x4e, (byte) 0x86, (byte) 0x59, (byte) 0x41, (byte) 0xb5, - (byte) 0xae, (byte) 0xd5, (byte) 0xc6, (byte) 0x38, (byte) 0xbc, (byte) 0xd7, - (byte) 0xd7, (byte) 0x8e, (byte) 0xa3, (byte) 0x1a, (byte) 0xde, (byte) 0x32, - (byte) 0xad, (byte) 0x8d, (byte) 0x15, (byte) 0x81, (byte) 0xfe, (byte) 0xac, - (byte) 0xbd, (byte) 0xd0, (byte) 0xca, (byte) 0xbc, (byte) 0xd8, (byte) 0x6a, - (byte) 0xe1, (byte) 0xfe, (byte) 0xda, (byte) 0xc4, (byte) 0xd8, (byte) 0x62, - (byte) 0x71, (byte) 0x20, (byte) 0xa3, (byte) 0xd3, (byte) 0x06, (byte) 0x11, - (byte) 0xa9, (byte) 0x53, (byte) 0x7a, (byte) 0x44, (byte) 0x89, (byte) 0x3d, - (byte) 0x28, (byte) 0x5e, (byte) 0x7d, (byte) 0xf0, (byte) 0x60, (byte) 0xeb, - (byte) 0xb5, (byte) 0xdf, (byte) 0xed, (byte) 0x4f, (byte) 0x6d, (byte) 0x05, - (byte) 0x59, (byte) 0x06, (byte) 0xb0, (byte) 0x62, (byte) 0x50, (byte) 0x1c, - (byte) 0xb7, (byte) 0x2c, (byte) 0x44, (byte) 0xa4, (byte) 0x49, (byte) 0xf8, - (byte) 0x4f, (byte) 0x4b, (byte) 0xab, (byte) 0x71, (byte) 0x5b, (byte) 0xcb, - (byte) 0x31, (byte) 0x10, (byte) 0x41, (byte) 0xe0, (byte) 0x1a, (byte) 0x15, - (byte) 0xdc, (byte) 0x4c, (byte) 0x5d, (byte) 0x4f, (byte) 0x62, (byte) 0x83, - (byte) 0xa4, (byte) 0x80, (byte) 0x06, (byte) 0x36, (byte) 0xba, (byte) 0xc9, - (byte) 0xe2, (byte) 0xa4, (byte) 0x11, (byte) 0x98, (byte) 0x6b, (byte) 0x4c, - (byte) 0xe9, (byte) 0x90, (byte) 0x55, (byte) 0x18, (byte) 0xde, (byte) 0xe1, - (byte) 0x42, (byte) 0x38, (byte) 0x28, (byte) 0xa3, (byte) 0x54, (byte) 0x56, - (byte) 0x31, (byte) 0xaf, (byte) 0x5a, (byte) 0xd6, (byte) 0xf0, (byte) 0x26, - (byte) 0xe0, (byte) 0x7a, (byte) 0xd9, (byte) 0x6c, (byte) 0x64, (byte) 0xca, - (byte) 0x5d, (byte) 0x6d, (byte) 0x3d, (byte) 0x9a, (byte) 0xfe, (byte) 0x36, - (byte) 0x93, (byte) 0x9e, (byte) 0x62, (byte) 0x94, (byte) 0xc6, (byte) 0x07, - (byte) 0x83, (byte) 0x96, (byte) 0xd6, (byte) 0x27, (byte) 0xa6, (byte) 0xd8 - }; - public static final PrivateKey CLIENT_SUITE_B_RSA3072_KEY = - loadPrivateKey("RSA", CLIENT_SUITE_B_RSA3072_KEY_DATA); - - private static final String CLIENT_SUITE_B_ECDSA_CERT_STRING = - "-----BEGIN CERTIFICATE-----\n" - + "MIIB9zCCAX4CFDpfSZh3AH07BEfGWuMDa7Ynz6y+MAoGCCqGSM49BAMDMF4xCzAJ\n" - + "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQKDAdB\n" - + "bmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4XDTIw\n" - + "MDcyMTAyMjk1MFoXDTMwMDUzMDAyMjk1MFowYjELMAkGA1UEBhMCVVMxCzAJBgNV\n" - + "BAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsM\n" - + "BVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MHYwEAYHKoZIzj0CAQYFK4EE\n" - + "ACIDYgAEhxhVJ7dcSqrto0X+dgRxtd8BWG8cWmPjBji3MIxDLfpcMDoIB84ae1Ew\n" - + "gJn4YUYHrWsUDiVNihv8j7a/Ol1qcIY2ybH7tbezefLmagqA4vXEUXZXoUyL4ZNC\n" - + "DWcdw6LrMAoGCCqGSM49BAMDA2cAMGQCMH4aP73HrriRUJRguiuRic+X4Cqj/7YQ\n" - + "ueJmP87KF92/thhoQ9OrRo8uJITPmNDswwIwP2Q1AZCSL4BI9dYrqu07Ar+pSkXE\n" - + "R7oOqGdZR+d/MvXcFSrbIaLKEoHXmQamIHLe\n" - + "-----END CERTIFICATE-----\n"; - public static final X509Certificate CLIENT_SUITE_B_ECDSA_CERT = - loadCertificate(CLIENT_SUITE_B_ECDSA_CERT_STRING); - - private static final byte[] CLIENT_SUITE_B_ECC_KEY_DATA = new byte[]{ - (byte) 0x30, (byte) 0x81, (byte) 0xb6, (byte) 0x02, (byte) 0x01, (byte) 0x00, - (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06, - (byte) 0x05, (byte) 0x2b, (byte) 0x81, (byte) 0x04, (byte) 0x00, (byte) 0x22, - (byte) 0x04, (byte) 0x81, (byte) 0x9e, (byte) 0x30, (byte) 0x81, (byte) 0x9b, - (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x30, (byte) 0xea, - (byte) 0x6c, (byte) 0x4b, (byte) 0x6d, (byte) 0x43, (byte) 0xf9, (byte) 0x6c, - (byte) 0x91, (byte) 0xdc, (byte) 0x2d, (byte) 0x6e, (byte) 0x87, (byte) 0x4f, - (byte) 0x0a, (byte) 0x0b, (byte) 0x97, (byte) 0x25, (byte) 0x1c, (byte) 0x79, - (byte) 0xa2, (byte) 0x07, (byte) 0xdc, (byte) 0x94, (byte) 0xc2, (byte) 0xee, - (byte) 0x64, (byte) 0x51, (byte) 0x6d, (byte) 0x4e, (byte) 0x35, (byte) 0x1c, - (byte) 0x22, (byte) 0x2f, (byte) 0xc0, (byte) 0xea, (byte) 0x09, (byte) 0x47, - (byte) 0x3e, (byte) 0xb9, (byte) 0xb6, (byte) 0xb8, (byte) 0x83, (byte) 0x9e, - (byte) 0xed, (byte) 0x59, (byte) 0xe5, (byte) 0xe7, (byte) 0x0f, (byte) 0xa1, - (byte) 0x64, (byte) 0x03, (byte) 0x62, (byte) 0x00, (byte) 0x04, (byte) 0x87, - (byte) 0x18, (byte) 0x55, (byte) 0x27, (byte) 0xb7, (byte) 0x5c, (byte) 0x4a, - (byte) 0xaa, (byte) 0xed, (byte) 0xa3, (byte) 0x45, (byte) 0xfe, (byte) 0x76, - (byte) 0x04, (byte) 0x71, (byte) 0xb5, (byte) 0xdf, (byte) 0x01, (byte) 0x58, - (byte) 0x6f, (byte) 0x1c, (byte) 0x5a, (byte) 0x63, (byte) 0xe3, (byte) 0x06, - (byte) 0x38, (byte) 0xb7, (byte) 0x30, (byte) 0x8c, (byte) 0x43, (byte) 0x2d, - (byte) 0xfa, (byte) 0x5c, (byte) 0x30, (byte) 0x3a, (byte) 0x08, (byte) 0x07, - (byte) 0xce, (byte) 0x1a, (byte) 0x7b, (byte) 0x51, (byte) 0x30, (byte) 0x80, - (byte) 0x99, (byte) 0xf8, (byte) 0x61, (byte) 0x46, (byte) 0x07, (byte) 0xad, - (byte) 0x6b, (byte) 0x14, (byte) 0x0e, (byte) 0x25, (byte) 0x4d, (byte) 0x8a, - (byte) 0x1b, (byte) 0xfc, (byte) 0x8f, (byte) 0xb6, (byte) 0xbf, (byte) 0x3a, - (byte) 0x5d, (byte) 0x6a, (byte) 0x70, (byte) 0x86, (byte) 0x36, (byte) 0xc9, - (byte) 0xb1, (byte) 0xfb, (byte) 0xb5, (byte) 0xb7, (byte) 0xb3, (byte) 0x79, - (byte) 0xf2, (byte) 0xe6, (byte) 0x6a, (byte) 0x0a, (byte) 0x80, (byte) 0xe2, - (byte) 0xf5, (byte) 0xc4, (byte) 0x51, (byte) 0x76, (byte) 0x57, (byte) 0xa1, - (byte) 0x4c, (byte) 0x8b, (byte) 0xe1, (byte) 0x93, (byte) 0x42, (byte) 0x0d, - (byte) 0x67, (byte) 0x1d, (byte) 0xc3, (byte) 0xa2, (byte) 0xeb - }; - public static final PrivateKey CLIENT_SUITE_B_ECC_KEY = - loadPrivateKey("EC", CLIENT_SUITE_B_ECC_KEY_DATA); - private static X509Certificate loadCertificate(String blob) { try { final CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); @@ -662,9 +255,9 @@ public class FakeKeys { } } - private static PrivateKey loadPrivateKey(String algorithm, byte[] fakeKey) { + private static PrivateKey loadPrivateRSAKey(byte[] fakeKey) { try { - KeyFactory kf = KeyFactory.getInstance(algorithm); + KeyFactory kf = KeyFactory.getInstance("RSA"); return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey)); } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { return null; diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java index 6f47f3da710f..fc0ef469ad80 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java @@ -22,8 +22,6 @@ import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.net.MacAddress; @@ -37,8 +35,6 @@ import androidx.test.filters.SmallTest; import org.junit.Test; -import java.security.cert.X509Certificate; - /** * Unit tests for {@link android.net.wifi.WifiNetworkSpecifier}. */ @@ -49,7 +45,6 @@ public class WifiNetworkSpecifierTest { private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00"; private static final String TEST_BSSID = "12:12:12:12:12:12"; private static final String TEST_PRESHARED_KEY = "\"Test123\""; - private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch"; /** * Validate correctness of WifiNetworkSpecifier object created by @@ -140,106 +135,6 @@ public class WifiNetworkSpecifierTest { wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getPhase2Method()); } - /** - * Validate correctness of WifiNetworkSuggestion object created by - * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise network. - */ - @Test - public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() { - WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); - enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); - enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0); - enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); - - NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder() - .setSsid(TEST_SSID) - .setWpa3EnterpriseConfig(enterpriseConfig) - .build(); - - assertTrue(specifier instanceof WifiNetworkSpecifier); - WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier; - - assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement - .get(WifiConfiguration.KeyMgmt.IEEE8021X)); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement - .get(WifiConfiguration.KeyMgmt.WPA_EAP)); - assertFalse(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement - .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers - .get(WifiConfiguration.GroupCipher.CCMP)); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf); - assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey); - assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig); - } - - /** - * Validate correctness of WifiNetworkSuggestion object created by - * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit RSA SuiteB network. - */ - @Test - public void testWifiNetworkSuggestionBuilderForWpa3SuiteBRsaEapNetwork() { - WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); - enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); - enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_RSA3072_CERT); - enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_RSA3072_KEY, - new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_RSA3072_CERT}); - - enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); - - NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder() - .setSsid(TEST_SSID) - .setWpa3EnterpriseConfig(enterpriseConfig) - .build(); - - assertTrue(specifier instanceof WifiNetworkSpecifier); - WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier; - - assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement - .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers - .get(WifiConfiguration.GroupCipher.GCMP_256)); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupManagementCiphers - .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf); - assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey); - assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig); - } - - /** - * Validate correctness of WifiNetworkSuggestion object created by - * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit ECC SuiteB network. - */ - @Test - public void testWifiNetworkSuggestionBuilderForWpa3SuiteBEccEapNetwork() { - WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); - enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); - enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_ECDSA_CERT); - enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_ECC_KEY, - new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_ECDSA_CERT}); - - enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); - - NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder() - .setSsid(TEST_SSID) - .setWpa3EnterpriseConfig(enterpriseConfig) - .build(); - - assertTrue(specifier instanceof WifiNetworkSpecifier); - WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier; - - assertEquals("\"" + TEST_SSID + "\"", wifiNetworkSpecifier.wifiConfiguration.SSID); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement - .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers - .get(WifiConfiguration.GroupCipher.GCMP_256)); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupManagementCiphers - .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); - assertTrue(wifiNetworkSpecifier.wifiConfiguration.requirePmf); - assertNull(wifiNetworkSpecifier.wifiConfiguration.preSharedKey); - assertNotNull(wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig); - } /** * Ensure {@link WifiNetworkSpecifier.Builder#setSsid(String)} throws an exception diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index 00a044269db3..16b4ad08a830 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -27,8 +27,6 @@ import androidx.test.filters.SmallTest; import org.junit.Test; -import java.security.cert.X509Certificate; - /** * Unit tests for {@link android.net.wifi.WifiNetworkSuggestion}. */ @@ -201,89 +199,19 @@ public class WifiNetworkSuggestionTest { assertFalse(suggestion.isInitialAutoJoinEnabled); } + /** * Validate correctness of WifiNetworkSuggestion object created by - * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise network. + * {@link WifiNetworkSuggestion.Builder#build()} for SuiteB network. */ @Test public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() { WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); + enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0); enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); - WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() - .setSsid(TEST_SSID) - .setWpa3EnterpriseConfig(enterpriseConfig) - .build(); - - assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); - assertTrue(suggestion.wifiConfiguration.allowedKeyManagement - .get(WifiConfiguration.KeyMgmt.IEEE8021X)); - assertTrue(suggestion.wifiConfiguration.allowedKeyManagement - .get(WifiConfiguration.KeyMgmt.WPA_EAP)); - assertFalse(suggestion.wifiConfiguration.allowedKeyManagement - .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); - assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers - .get(WifiConfiguration.GroupCipher.CCMP)); - assertTrue(suggestion.wifiConfiguration.requirePmf); - assertNull(suggestion.wifiConfiguration.preSharedKey); - // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested - // here. - assertTrue(suggestion.isUserAllowedToManuallyConnect); - assertTrue(suggestion.isInitialAutoJoinEnabled); - assertNotNull(suggestion.getEnterpriseConfig()); - } - - /** - * Validate correctness of WifiNetworkSuggestion object created by - * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit RSA SuiteB network. - */ - @Test - public void testWifiNetworkSuggestionBuilderForWpa3SuiteBRsaEapNetwork() { - WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); - enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); - enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_RSA3072_CERT); - enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_RSA3072_KEY, - new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_RSA3072_CERT}); - - enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); - - WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() - .setSsid(TEST_SSID) - .setWpa3EnterpriseConfig(enterpriseConfig) - .build(); - - assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); - assertTrue(suggestion.wifiConfiguration.allowedKeyManagement - .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); - assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers - .get(WifiConfiguration.GroupCipher.GCMP_256)); - assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers - .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); - assertTrue(suggestion.wifiConfiguration.requirePmf); - assertNull(suggestion.wifiConfiguration.preSharedKey); - // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested - // here. - assertTrue(suggestion.isUserAllowedToManuallyConnect); - assertTrue(suggestion.isInitialAutoJoinEnabled); - assertNotNull(suggestion.getEnterpriseConfig()); - } - - /** - * Validate correctness of WifiNetworkSuggestion object created by - * {@link WifiNetworkSuggestion.Builder#build()} for WPA3-Enterprise 192-bit ECC SuiteB network. - */ - @Test - public void testWifiNetworkSuggestionBuilderForWpa3SuiteBEccEapNetwork() { - WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); - enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); - enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_ECDSA_CERT); - enterpriseConfig.setClientKeyEntryWithCertificateChain(FakeKeys.CLIENT_SUITE_B_ECC_KEY, - new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_ECDSA_CERT}); - - enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); - WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) .setWpa3EnterpriseConfig(enterpriseConfig) -- GitLab From d9d3ada81894c7fa6888aa1214ad142f79392033 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 10 Sep 2020 03:20:12 +0000 Subject: [PATCH 384/536] Remove unit test changes in "[Passpoint] Changes to Unique ID" This partially reverts commit c527eed1235d0fa81286e08d857e5b31a7d265c8. Reason for revert: Unit tests are out of sync with prebuilt Wifi mainline module Bug: 168158154 Change-Id: Ia5e9ae3bcadace1a1c2ae53a56c67343db4bef71 Test: Treehugger Merged-In: Ice11158078b5b86c721747b0d67ecfb09731a3c5 --- wifi/tests/src/android/net/wifi/FakeKeys.java | 29 --- .../hotspot2/PasspointConfigurationTest.java | 192 +----------------- .../net/wifi/hotspot2/pps/CredentialTest.java | 23 +-- 3 files changed, 10 insertions(+), 234 deletions(-) diff --git a/wifi/tests/src/android/net/wifi/FakeKeys.java b/wifi/tests/src/android/net/wifi/FakeKeys.java index 641b891a1f4d..c0d60c33f99c 100644 --- a/wifi/tests/src/android/net/wifi/FakeKeys.java +++ b/wifi/tests/src/android/net/wifi/FakeKeys.java @@ -214,35 +214,6 @@ public class FakeKeys { }; public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1); - private static final String CLIENT_SUITE_B_RSA3072_CERT_STRING = - "-----BEGIN CERTIFICATE-----\n" - + "MIIERzCCAq8CFDopjyNgaj+c2TN2k06h7okEWpHJMA0GCSqGSIb3DQEBDAUAMF4x\n" - + "CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQK\n" - + "DAdBbmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4X\n" - + "DTIwMDcyMTAyMjkxMVoXDTMwMDUzMDAyMjkxMVowYjELMAkGA1UEBhMCVVMxCzAJ\n" - + "BgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNV\n" - + "BAsMBVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MIIBojANBgkqhkiG9w0B\n" - + "AQEFAAOCAY8AMIIBigKCAYEAwSK3C5K5udtCKTnE14e8z2cZvwmB4Xe+a8+7QLud\n" - + "Hooc/lQzClgK4MbVUC0D3FE+U32C78SxKoTaRWtvPmNm+UaFT8KkwyUno/dv+2XD\n" - + "pd/zARQ+3FwAfWopAhEyCVSxwsCa+slQ4juRIMIuUC1Mm0NaptZyM3Tj/ICQEfpk\n" - + "o9qVIbiK6eoJMTkY8EWfAn7RTFdfR1OLuO0mVOjgLW9/+upYv6hZ19nAMAxw4QTJ\n" - + "x7lLwALX7B+tDYNEZHDqYL2zyvQWAj2HClere8QYILxkvktgBg2crEJJe4XbDH7L\n" - + "A3rrXmsiqf1ZbfFFEzK9NFqovL+qGh+zIP+588ShJFO9H/RDnDpiTnAFTWXQdTwg\n" - + "szSS0Vw2PB+JqEABAa9DeMvXT1Oy+NY3ItPHyy63nQZVI2rXANw4NhwS0Z6DF+Qs\n" - + "TNrj+GU7e4SG/EGR8SvldjYfQTWFLg1l/UT1hOOkQZwdsaW1zgKyeuiFB2KdMmbA\n" - + "Sq+Ux1L1KICo0IglwWcB/8nnAgMBAAEwDQYJKoZIhvcNAQEMBQADggGBAMYwJkNw\n" - + "BaCviKFmReDTMwWPRy4AMNViEeqAXgERwDEKwM7efjsaj5gctWfKsxX6UdLzkhgg\n" - + "6S/T6PxVWKzJ6l7SoOuTa6tMQOZp+h3R1mdfEQbw8B5cXBxZ+batzAai6Fiy1FKS\n" - + "/ka3INbcGfYuIYghfTrb4/NJKN06ZaQ1bpPwq0e4gN7800T2nbawvSf7r+8ZLcG3\n" - + "6bGCjRMwDSIipNvOwoj3TG315XC7TccX5difQ4sKOY+d2MkVJ3RiO0Ciw2ZbEW8d\n" - + "1FH5vUQJWnBUfSFznosGzLwH3iWfqlP+27jNE+qB2igEwCRFgVAouURx5ou43xuX\n" - + "qf6JkdI3HTJGLIWxkp7gOeln4dEaYzKjYw+P0VqJvKVqQ0IXiLjHgE0J9p0vgyD6\n" - + "HVVcP7U8RgqrbIjL1QgHU4KBhGi+WSUh/mRplUCNvHgcYdcHi/gHpj/j6ubwqIGV\n" - + "z4iSolAHYTmBWcLyE0NgpzE6ntp+53r2KaUJA99l2iGVzbWTwqPSm0XAVw==\n" - + "-----END CERTIFICATE-----\n"; - public static final X509Certificate CLIENT_SUITE_B_RSA3072_CERT = - loadCertificate(CLIENT_SUITE_B_RSA3072_CERT_STRING); - private static X509Certificate loadCertificate(String blob) { try { final CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index 8270d643ca65..638efb9f14ee 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -23,8 +23,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; -import android.net.wifi.EAPConstants; -import android.net.wifi.FakeKeys; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSp; import android.os.Parcel; @@ -34,11 +32,6 @@ import androidx.test.filters.SmallTest; import org.junit.Test; import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -390,39 +383,19 @@ public class PasspointConfigurationTest { } /** - * Verify that the unique identifier generated is the same for two instances with different - * HomeSp node but same FQDN + * Verify that the unique identifier generated is different for two instances with different + * HomeSp node * * @throws Exception */ @Test - public void validateUniqueIdDifferentHomeSpSameFqdn() throws Exception { + public void validateUniqueIdDifferentHomeSp() throws Exception { PasspointConfiguration config1 = PasspointTestUtils.createConfig(); - // Modify config2's RCOIs and friendly name to a different set of values + // Modify config2's RCOIs to a different set of values PasspointConfiguration config2 = PasspointTestUtils.createConfig(); HomeSp homeSp = config2.getHomeSp(); homeSp.setRoamingConsortiumOis(new long[] {0xaa, 0xbb}); - homeSp.setFriendlyName("Some other name"); - config2.setHomeSp(homeSp); - - assertEquals(config1.getUniqueId(), config2.getUniqueId()); - } - - /** - * Verify that the unique identifier generated is different for two instances with the same - * HomeSp node but different FQDN - * - * @throws Exception - */ - @Test - public void validateUniqueIdSameHomeSpDifferentFqdn() throws Exception { - PasspointConfiguration config1 = PasspointTestUtils.createConfig(); - - // Modify config2's FQDN to a different value - PasspointConfiguration config2 = PasspointTestUtils.createConfig(); - HomeSp homeSp = config2.getHomeSp(); - homeSp.setFqdn("fqdn2.com"); config2.setHomeSp(homeSp); assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); @@ -430,15 +403,15 @@ public class PasspointConfigurationTest { /** * Verify that the unique identifier generated is different for two instances with different - * SIM Credential node + * Credential node * * @throws Exception */ @Test - public void validateUniqueIdDifferentSimCredential() throws Exception { + public void validateUniqueIdDifferentCredential() throws Exception { PasspointConfiguration config1 = PasspointTestUtils.createConfig(); - // Modify config2's realm and SIM credential to a different set of values + // Modify config2's RCOIs to a different set of values PasspointConfiguration config2 = PasspointTestUtils.createConfig(); Credential credential = config2.getCredential(); credential.setRealm("realm2.example.com"); @@ -448,157 +421,6 @@ public class PasspointConfigurationTest { assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); } - /** - * Verify that the unique identifier generated is different for two instances with different - * Realm in the Credential node - * - * @throws Exception - */ - @Test - public void validateUniqueIdDifferentRealm() throws Exception { - PasspointConfiguration config1 = PasspointTestUtils.createConfig(); - - // Modify config2's realm to a different set of values - PasspointConfiguration config2 = PasspointTestUtils.createConfig(); - Credential credential = config2.getCredential(); - credential.setRealm("realm2.example.com"); - config2.setCredential(credential); - - assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); - } - - /** - * Verify that the unique identifier generated is the same for two instances with different - * password and same username in the User Credential node - * - * @throws Exception - */ - @Test - public void validateUniqueIdSameUserInUserCredential() throws Exception { - PasspointConfiguration config1 = PasspointTestUtils.createConfig(); - Credential credential = createCredentialWithUserCredential("user", "passwd"); - config1.setCredential(credential); - - // Modify config2's Passpowrd to a different set of values - PasspointConfiguration config2 = PasspointTestUtils.createConfig(); - credential = createCredentialWithUserCredential("user", "newpasswd"); - config2.setCredential(credential); - - assertEquals(config1.getUniqueId(), config2.getUniqueId()); - } - - /** - * Verify that the unique identifier generated is different for two instances with different - * username in the User Credential node - * - * @throws Exception - */ - @Test - public void validateUniqueIdDifferentUserCredential() throws Exception { - PasspointConfiguration config1 = PasspointTestUtils.createConfig(); - Credential credential = createCredentialWithUserCredential("user", "passwd"); - config1.setCredential(credential); - - // Modify config2's username to a different value - PasspointConfiguration config2 = PasspointTestUtils.createConfig(); - credential = createCredentialWithUserCredential("user2", "passwd"); - config2.setCredential(credential); - - assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); - } - - /** - * Verify that the unique identifier generated is different for two instances with different - * Cert Credential node - * - * @throws Exception - */ - @Test - public void validateUniqueIdDifferentCertCredential() throws Exception { - PasspointConfiguration config1 = PasspointTestUtils.createConfig(); - Credential credential = createCredentialWithCertificateCredential(true, true); - config1.setCredential(credential); - - // Modify config2's cert credential to a different set of values - PasspointConfiguration config2 = PasspointTestUtils.createConfig(); - credential = createCredentialWithCertificateCredential(false, false); - config2.setCredential(credential); - - assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); - } - - /** - * Helper function for generating certificate credential for testing. - * - * @return {@link Credential} - */ - private static Credential createCredentialWithCertificateCredential(Boolean useCaCert0, - Boolean useCert0) - throws NoSuchAlgorithmException, CertificateEncodingException { - Credential.CertificateCredential certCred = new Credential.CertificateCredential(); - certCred.setCertType("x509v3"); - if (useCert0) { - certCred.setCertSha256Fingerprint( - MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded())); - } else { - certCred.setCertSha256Fingerprint(MessageDigest.getInstance("SHA-256") - .digest(FakeKeys.CLIENT_SUITE_B_RSA3072_CERT.getEncoded())); - } - return createCredential(null, certCred, null, new X509Certificate[] {FakeKeys.CLIENT_CERT}, - FakeKeys.RSA_KEY1, useCaCert0 ? FakeKeys.CA_CERT0 : FakeKeys.CA_CERT1); - } - - /** - * Helper function for generating user credential for testing. - * - * @return {@link Credential} - */ - private static Credential createCredentialWithUserCredential(String username, String password) { - Credential.UserCredential userCred = new Credential.UserCredential(); - userCred.setUsername(username); - userCred.setPassword(password); - userCred.setMachineManaged(true); - userCred.setAbleToShare(true); - userCred.setSoftTokenApp("TestApp"); - userCred.setEapType(EAPConstants.EAP_TTLS); - userCred.setNonEapInnerMethod("MS-CHAP"); - return createCredential(userCred, null, null, null, null, FakeKeys.CA_CERT0); - } - - /** - * Helper function for generating Credential for testing. - * - * @param userCred Instance of UserCredential - * @param certCred Instance of CertificateCredential - * @param simCred Instance of SimCredential - * @param clientCertificateChain Chain of client certificates - * @param clientPrivateKey Client private key - * @param caCerts CA certificates - * @return {@link Credential} - */ - private static Credential createCredential(Credential.UserCredential userCred, - Credential.CertificateCredential certCred, - Credential.SimCredential simCred, - X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey, - X509Certificate... caCerts) { - Credential cred = new Credential(); - cred.setCreationTimeInMillis(123455L); - cred.setExpirationTimeInMillis(2310093L); - cred.setRealm("realm"); - cred.setCheckAaaServerCertStatus(true); - cred.setUserCredential(userCred); - cred.setCertCredential(certCred); - cred.setSimCredential(simCred); - if (caCerts != null && caCerts.length == 1) { - cred.setCaCertificate(caCerts[0]); - } else { - cred.setCaCertificates(caCerts); - } - cred.setClientCertificateChain(clientCertificateChain); - cred.setClientPrivateKey(clientPrivateKey); - return cred; - } - /** * Verify that the unique identifier API generates an exception if HomeSP is not initialized. * diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java index a44df40a8e97..829d8f0a9a3a 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java @@ -593,10 +593,10 @@ public class CredentialTest { } /** - * Verify that unique identifiers are different for a credential with different username + * Verify that unique identifiers are different for a credential with different values */ @Test - public void testUniqueIdDifferentForUserCredentialsWithDifferentUsername() throws Exception { + public void testUniqueIdDifferentForUserCredentialsWithDifferentValues() throws Exception { Credential userCred1 = createCredentialWithUserCredential(); Credential userCred2 = createCredentialWithUserCredential(); userCred2.getUserCredential().setUsername("anotheruser"); @@ -605,24 +605,7 @@ public class CredentialTest { } /** - * Verify that unique identifiers are different for a credential with different password and - * other values other than username - */ - @Test - public void testUniqueIdSameForUserCredentialsWithDifferentPassword() throws Exception { - Credential userCred1 = createCredentialWithUserCredential(); - Credential userCred2 = createCredentialWithUserCredential(); - userCred2.getUserCredential().setPassword("someotherpassword!"); - userCred2.getUserCredential().setMachineManaged(false); - userCred2.getUserCredential().setAbleToShare(false); - userCred2.getUserCredential().setSoftTokenApp("TestApp2"); - userCred2.getUserCredential().setNonEapInnerMethod("PAP"); - - assertEquals(userCred1.getUniqueId(), userCred2.getUniqueId()); - } - - /** - * Verify that unique identifiers are different for a cert credential with different values + * Verify that unique identifiers are different for a credential with different values */ @Test public void testUniqueIdDifferentForCertCredentialsWithDifferentValues() throws Exception { -- GitLab From be864d350079a5c66dab316b46de4295ad5c8eb2 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 10 Sep 2020 03:23:04 +0000 Subject: [PATCH 385/536] Remove unit test changes in "wifi: Support SAE_TRANSITION when converting to WifiConfiguration" This partially reverts commit 43a326cdb364a01a0bb2ab4d5076b3e6fe87a8bd. Reason for revert: Unit tests are out of sync with prebuilt Wifi mainline module Bug: 168158154 Test: Treehugger Change-Id: I8add72b6de6e470a09a745c32b3e2fea764fc692 Merged-In: I6afba22e4081ba58884ffd1b560b81b1e9960132 --- .../net/wifi/SoftApConfigurationTest.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index d78c942d55e2..1a4427034756 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -282,6 +282,12 @@ public class SoftApConfigurationTest { .build(); assertNull(band_6g_config.toWifiConfiguration()); + SoftApConfiguration sae_transition_config = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) + .build(); + + assertNull(sae_transition_config.toWifiConfiguration()); } @Test @@ -324,16 +330,5 @@ public class SoftApConfigurationTest { assertThat(wifiConfig_2g5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_ANY); assertThat(wifiConfig_2g5g.apChannel).isEqualTo(0); assertThat(wifiConfig_2g5g.hiddenSSID).isEqualTo(true); - - SoftApConfiguration softApConfig_sae_transition = new SoftApConfiguration.Builder() - .setPassphrase("secretsecret", - SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) - .build(); - - WifiConfiguration wifiConfig_sae_transition = - softApConfig_sae_transition.toWifiConfiguration(); - assertThat(wifiConfig_sae_transition.getAuthType()) - .isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); - assertThat(wifiConfig_sae_transition.preSharedKey).isEqualTo("secretsecret"); } } -- GitLab From 152d0e6bc2031e9c5d635c05af9087a550aa9ef5 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Fri, 4 Sep 2020 18:53:56 +0800 Subject: [PATCH 386/536] Fix gesture exclusion limit for sticky-hide nav bar If a window hides navigation bar by using WindowInsetsController with BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE, there should not be limit about system gesture exclusion. Fix: 167782678 Test: SystemGestureExclusionRectsTest Change-Id: I1573e9ee1976108b41d2cfa827dc599fcae3b6d1 --- .../com/android/server/wm/DisplayContent.java | 30 +++++++++++-------- .../server/wm/InsetsStateController.java | 1 + 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 0363ea0e7512..abfb9c99de6b 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -43,14 +43,14 @@ import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_LEFT_GESTURES; +import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_RIGHT_GESTURES; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static android.view.View.GONE; -import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; -import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; +import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; @@ -4983,7 +4983,7 @@ class DisplayContent extends WindowContainer Date: Tue, 8 Sep 2020 18:07:43 -0700 Subject: [PATCH 387/536] Block offset requests prior to entering PiP When entering PiP directly requested by Activity#enterPictureInPictureMode in gesture nav mode, there is chance that offsetPip is scheduled ahead of the actual entering PiP alpha animation. Fixed by migrating the mExitingPip and mInPip to a more meaningful internal State enum and blocks resize requests till the animation is kicked off. Bug: 166084738 Test: See reproduce step in b/166084738#comment10 Merged-In: Ie78c9892c29423f10b001bb3d28549ac176cd1c3 Change-Id: Ie78c9892c29423f10b001bb3d28549ac176cd1c3 --- .../systemui/pip/PipTaskOrganizer.java | 92 +++++++++++-------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 8d4ca5e46fae..e6abea72da62 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -94,6 +94,36 @@ public class PipTaskOrganizer extends TaskOrganizer implements private static final int MSG_FINISH_RESIZE = 4; private static final int MSG_RESIZE_USER = 5; + // Not a complete set of states but serves what we want right now. + private enum State { + UNDEFINED(0), + TASK_APPEARED(1), + ENTERING_PIP(2), + EXITING_PIP(3); + + private final int mStateValue; + + State(int value) { + mStateValue = value; + } + + private boolean isInPip() { + return mStateValue >= TASK_APPEARED.mStateValue + && mStateValue != EXITING_PIP.mStateValue; + } + + /** + * Resize request can be initiated in other component, ignore if we are no longer in PIP, + * still waiting for animation or we're exiting from it. + * + * @return {@code true} if the resize request should be blocked/ignored. + */ + private boolean shouldBlockResizeRequest() { + return mStateValue < ENTERING_PIP.mStateValue + || mStateValue == EXITING_PIP.mStateValue; + } + } + private final Handler mMainHandler; private final Handler mUpdateHandler; private final PipBoundsHandler mPipBoundsHandler; @@ -188,8 +218,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements private ActivityManager.RunningTaskInfo mTaskInfo; private WindowContainerToken mToken; private SurfaceControl mLeash; - private boolean mInPip; - private boolean mExitingPip; + private State mState = State.UNDEFINED; private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; @@ -241,11 +270,11 @@ public class PipTaskOrganizer extends TaskOrganizer implements } public boolean isInPip() { - return mInPip; + return mState.isInPip(); } public boolean isDeferringEnterPipAnimation() { - return mInPip && mShouldDeferEnteringPip; + return mState.isInPip() && mShouldDeferEnteringPip; } /** @@ -274,9 +303,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements * @param animationDurationMs duration in millisecond for the exiting PiP transition */ public void exitPip(int animationDurationMs) { - if (!mInPip || mExitingPip || mToken == null) { + if (!mState.isInPip() || mState == State.EXITING_PIP || mToken == null) { Log.wtf(TAG, "Not allowed to exitPip in current state" - + " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken); + + " mState=" + mState + " mToken=" + mToken); return; } @@ -293,6 +322,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN : TRANSITION_DIRECTION_TO_FULLSCREEN; if (orientationDiffers) { + mState = State.EXITING_PIP; // Send started callback though animation is ignored. sendOnPipTransitionStarted(direction); // Don't bother doing an animation if the display rotation differs or if it's in @@ -301,7 +331,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements WindowOrganizer.applyTransaction(wct); // Send finished callback though animation is ignored. sendOnPipTransitionFinished(direction); - mInPip = false; } else { final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); @@ -320,11 +349,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements scheduleAnimateResizePip(mLastReportedBounds, destinationBounds, null /* sourceHintRect */, direction, animationDurationMs, null /* updateBoundsCallback */); - mInPip = false; + mState = State.EXITING_PIP; } }); } - mExitingPip = true; } private void applyWindowingModeChangeOnExit(WindowContainerTransaction wct, int direction) { @@ -341,9 +369,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements * Removes PiP immediately. */ public void removePip() { - if (!mInPip || mExitingPip || mToken == null) { + if (!mState.isInPip() || mToken == null) { Log.wtf(TAG, "Not allowed to removePip in current state" - + " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken); + + " mState=" + mState + " mToken=" + mToken); return; } @@ -355,7 +383,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements .setDuration(mEnterExitAnimationDuration) .start()); mCompactState.remove(mToken.asBinder()); - mExitingPip = true; + mState = State.EXITING_PIP; } private void removePipImmediately() { @@ -377,8 +405,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements Objects.requireNonNull(info, "Requires RunningTaskInfo"); mTaskInfo = info; mToken = mTaskInfo.token; - mInPip = true; - mExitingPip = false; + mState = State.TASK_APPEARED; mLeash = leash; mCompactState.put(mToken.asBinder(), new PipWindowConfigurationCompact(mTaskInfo.configuration.windowConfiguration)); @@ -410,6 +437,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements scheduleAnimateResizePip(currentBounds, destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration, null /* updateBoundsCallback */); + mState = State.ENTERING_PIP; } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) { enterPipWithAlphaAnimation(destinationBounds, mEnterExitAnimationDuration); mOneShotAnimationType = ANIM_TYPE_BOUNDS; @@ -455,6 +483,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements .setPipAnimationCallback(mPipAnimationCallback) .setDuration(durationMs) .start()); + // mState is set right after the animation is kicked off to block any resize + // requests such as offsetPip that may have been called prior to the transition. + mState = State.ENTERING_PIP; } }); } @@ -507,7 +538,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements */ @Override public void onTaskVanished(ActivityManager.RunningTaskInfo info) { - if (!mInPip) { + if (!mState.isInPip()) { return; } final WindowContainerToken token = info.token; @@ -518,8 +549,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements } mShouldDeferEnteringPip = false; mPictureInPictureParams = null; - mInPip = false; - mExitingPip = false; + mState = State.UNDEFINED; mPipUiEventLoggerLogger.setTaskInfo(null); } @@ -554,7 +584,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements @Override public void onFixedRotationFinished(int displayId) { - if (mShouldDeferEnteringPip && mInPip) { + if (mShouldDeferEnteringPip && mState.isInPip()) { final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams), null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo)); @@ -575,7 +605,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements mPipAnimationController.getCurrentAnimator(); if (animator == null || !animator.isRunning() || animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) { - if (mInPip && fromRotation) { + if (mState.isInPip() && fromRotation) { // If we are rotating while there is a current animation, immediately cancel the // animation (remove the listeners so we don't trigger the normal finish resize // call that should only happen on the update thread) @@ -661,10 +691,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements private void scheduleAnimateResizePip(Rect currentBounds, Rect destinationBounds, Rect sourceHintRect, @PipAnimationController.TransitionDirection int direction, int durationMs, Consumer updateBoundsCallback) { - if (!mInPip) { + if (!mState.isInPip()) { // TODO: tend to use shouldBlockResizeRequest here as well but need to consider // the fact that when in exitPip, scheduleAnimateResizePip is executed in the window - // container transaction callback and we want to set the mExitingPip immediately. + // container transaction callback and we want to set the mState immediately. return; } @@ -721,7 +751,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements private void scheduleFinishResizePip(Rect destinationBounds, @PipAnimationController.TransitionDirection int direction, Consumer updateBoundsCallback) { - if (shouldBlockResizeRequest()) { + if (mState.shouldBlockResizeRequest()) { return; } @@ -740,7 +770,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements mSurfaceTransactionHelper .crop(tx, mLeash, destinationBounds) .resetScale(tx, mLeash, destinationBounds) - .round(tx, mLeash, mInPip); + .round(tx, mLeash, mState.isInPip()); return tx; } @@ -749,7 +779,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements */ public void scheduleOffsetPip(Rect originalBounds, int offset, int duration, Consumer updateBoundsCallback) { - if (shouldBlockResizeRequest()) { + if (mState.shouldBlockResizeRequest()) { return; } if (mShouldDeferEnteringPip) { @@ -794,7 +824,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); mSurfaceTransactionHelper .crop(tx, mLeash, destinationBounds) - .round(tx, mLeash, mInPip); + .round(tx, mLeash, mState.isInPip()); tx.apply(); } @@ -925,16 +955,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements : params.getAspectRatio(); } - /** - * Resize request can be initiated in other component, ignore if we are no longer in PIP - * or we're exiting from it. - * - * @return {@code true} if the resize request should be blocked/ignored. - */ - private boolean shouldBlockResizeRequest() { - return !mInPip || mExitingPip; - } - /** * Sync with {@link #mSplitDivider} on destination bounds if PiP is going to split screen. * @@ -963,7 +983,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements pw.println(innerPrefix + "mToken=" + mToken + " binder=" + (mToken != null ? mToken.asBinder() : null)); pw.println(innerPrefix + "mLeash=" + mLeash); - pw.println(innerPrefix + "mInPip=" + mInPip); + pw.println(innerPrefix + "mState=" + mState); pw.println(innerPrefix + "mOneShotAnimationType=" + mOneShotAnimationType); pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams); pw.println(innerPrefix + "mLastReportedBounds=" + mLastReportedBounds); -- GitLab From f0c57b71eca299bf520c350b3921b7f0899da7e3 Mon Sep 17 00:00:00 2001 From: Beverly Date: Thu, 10 Sep 2020 10:14:27 -0400 Subject: [PATCH 388/536] Update notif ranking on consolidated policy change Test: manual 1. Turn on DND that doesn't suppress vis effects 2. Turn on Bedtime Mode Observe: notifications are hidden from Bedtime mode Fixes: 167011205 Change-Id: I7e383182e14a26830d185d3a233518ee7aecda24 --- .../server/notification/NotificationManagerService.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index f8d54adbeb5b..e42dd359dad1 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1938,6 +1938,13 @@ public class NotificationManagerService extends SystemService { }); } + @Override + void onConsolidatedPolicyChanged() { + Binder.withCleanCallingIdentity(() -> { + mRankingHandler.requestSort(); + }); + } + @Override void onAutomaticRuleStatusChanged(int userId, String pkg, String id, int status) { Binder.withCleanCallingIdentity(() -> { -- GitLab From 36f1f61ea0ebb5053f39ca596c034ff7312e1780 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 10 Sep 2020 16:53:04 +0000 Subject: [PATCH 389/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Iff11762acd8e5caa87301f36591d7b4b792010ed --- packages/SystemUI/res/values-es/strings.xml | 4 ++-- packages/SystemUI/res/values-nl/strings.xml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 135bfaa71349..aa4adaaf2fc5 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -395,7 +395,7 @@ "Conectado (%1$s de batería)" "Conectando..." "Compartir conexión" - "Zona Wi-Fi" + "Punto de acceso" "Activando…" "Ahorro de datos activado" @@ -660,7 +660,7 @@ "a las %1$s" "el %1$s" "Ajustes rápidos, %s." - "Zona Wi-Fi" + "Punto de acceso" "Perfil de trabajo" "Diversión solo para algunos" "El configurador de UI del sistema te ofrece otras formas de modificar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado." diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 679be33181ba..4631559ad5f8 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -390,7 +390,7 @@ "Kleuren omkeren" "Modus voor kleurcorrectie" "Meer instellingen" - "Gereed" + "Klaar" "Verbonden" "Verbonden, batterij %1$s" "Verbinding maken…" @@ -692,7 +692,7 @@ "Deze meldingen worden zonder geluid weergegeven" "Deze meldingen stellen je op de hoogte" "Meestal sluit je deze meldingen. \nWil je ze blijven weergeven?" - "Gereed" + "Klaar" "Toepassen" "Deze meldingen blijven weergeven?" "Meldingen stoppen" @@ -739,7 +739,7 @@ "Meldingen van dit kanaal toestaan" "Meer instellingen" "Aanpassen" - "Gereed" + "Klaar" "Ongedaan maken" "Deze melding markeren als geen gesprek" "Belangrijk gesprek" -- GitLab From b4908e9b881f92aba788262c8c54ec57dd8fba4d Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Tue, 8 Sep 2020 13:41:03 -0400 Subject: [PATCH 390/536] Enable mic & camera by default This CL sets the default value of device config for camera and mic (when the setting hasn't been set before) as true. Test: atest com.android.systemui.privacy Test: manual Bug: 168209929 Change-Id: I71107c692e1e7e6beea355ffa51317584f2b6e7c Merged-In: I71107c692e1e7e6beea355ffa51317584f2b6e7c (cherry picked from commit 22e8b46aae0949f5b89f43746a8c4f4a5a748654) --- .../systemui/privacy/PrivacyItemController.kt | 11 ++++-- .../privacy/PrivacyItemControllerFlagsTest.kt | 39 ++++++++----------- .../privacy/PrivacyItemControllerTest.kt | 1 + 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt index 59118bf3534e..a46ecaff7719 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt @@ -72,6 +72,8 @@ class PrivacyItemController @Inject constructor( private const val ALL_INDICATORS = SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED + private const val DEFAULT_ALL_INDICATORS = false + private const val DEFAULT_MIC_CAMERA = true } @VisibleForTesting @@ -81,12 +83,12 @@ class PrivacyItemController @Inject constructor( fun isAllIndicatorsEnabled(): Boolean { return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, - ALL_INDICATORS, false) + ALL_INDICATORS, DEFAULT_ALL_INDICATORS) } private fun isMicCameraEnabled(): Boolean { return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, - MIC_CAMERA, false) + MIC_CAMERA, DEFAULT_MIC_CAMERA) } private var currentUserIds = emptyList() @@ -118,12 +120,13 @@ class PrivacyItemController @Inject constructor( // Running on the ui executor so can iterate on callbacks if (properties.keyset.contains(ALL_INDICATORS)) { - allIndicatorsAvailable = properties.getBoolean(ALL_INDICATORS, false) + allIndicatorsAvailable = properties.getBoolean(ALL_INDICATORS, + DEFAULT_ALL_INDICATORS) callbacks.forEach { it.get()?.onFlagAllChanged(allIndicatorsAvailable) } } if (properties.keyset.contains(MIC_CAMERA)) { - micCameraAvailable = properties.getBoolean(MIC_CAMERA, false) + micCameraAvailable = properties.getBoolean(MIC_CAMERA, DEFAULT_MIC_CAMERA) callbacks.forEach { it.get()?.onFlagMicCameraChanged(micCameraAvailable) } } internalUiExecutor.updateListeningState() diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt index 4ba29e6e02a6..25fb7d300b8f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt @@ -96,22 +96,24 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { } @Test - fun testNotListeningByDefault() { + fun testNotListeningAllByDefault() { assertFalse(privacyItemController.allIndicatorsAvailable) - assertFalse(privacyItemController.micCameraAvailable) + } - verify(appOpsController, never()).addCallback(any(), any()) + @Test + fun testMicCameraListeningByDefault() { + assertTrue(privacyItemController.micCameraAvailable) } @Test fun testMicCameraChanged() { - changeMicCamera(true) + changeMicCamera(false) // default is true executor.runAllReady() - verify(callback).onFlagMicCameraChanged(true) + verify(callback).onFlagMicCameraChanged(false) verify(callback, never()).onFlagAllChanged(anyBoolean()) - assertTrue(privacyItemController.micCameraAvailable) + assertFalse(privacyItemController.micCameraAvailable) assertFalse(privacyItemController.allIndicatorsAvailable) } @@ -124,20 +126,19 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { verify(callback, never()).onFlagMicCameraChanged(anyBoolean()) assertTrue(privacyItemController.allIndicatorsAvailable) - assertFalse(privacyItemController.micCameraAvailable) } @Test fun testBothChanged() { changeAll(true) - changeMicCamera(true) + changeMicCamera(false) executor.runAllReady() verify(callback, atLeastOnce()).onFlagAllChanged(true) - verify(callback, atLeastOnce()).onFlagMicCameraChanged(true) + verify(callback, atLeastOnce()).onFlagMicCameraChanged(false) assertTrue(privacyItemController.allIndicatorsAvailable) - assertTrue(privacyItemController.micCameraAvailable) + assertFalse(privacyItemController.micCameraAvailable) } @Test @@ -156,19 +157,12 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { verify(appOpsController).addCallback(eq(PrivacyItemController.OPS), any()) } - @Test - fun testAll_listening() { - changeAll(true) - executor.runAllReady() - - verify(appOpsController).addCallback(eq(PrivacyItemController.OPS), any()) - } - @Test fun testAllFalse_notListening() { changeAll(true) executor.runAllReady() changeAll(false) + changeMicCamera(false) executor.runAllReady() verify(appOpsController).removeCallback(any(), any()) @@ -176,8 +170,8 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { @Test fun testSomeListening_stillListening() { + // Mic and camera are true by default changeAll(true) - changeMicCamera(true) executor.runAllReady() changeAll(false) executor.runAllReady() @@ -186,7 +180,8 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { } @Test - fun testAllDeleted_stopListening() { + fun testAllDeleted_micCameraFalse_stopListening() { + changeMicCamera(false) changeAll(true) executor.runAllReady() changeAll(null) @@ -196,13 +191,13 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { } @Test - fun testMicDeleted_stopListening() { + fun testMicDeleted_stillListening() { changeMicCamera(true) executor.runAllReady() changeMicCamera(null) executor.runAllReady() - verify(appOpsController).removeCallback(any(), any()) + verify(appOpsController, never()).removeCallback(any(), any()) } private fun changeMicCamera(value: Boolean?) = changeProperty(MIC_CAMERA, value) diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt index 5c5df2639cdd..38e8823adfbb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt @@ -272,6 +272,7 @@ class PrivacyItemControllerTest : SysuiTestCase() { @Test fun testNotListeningWhenIndicatorsDisabled() { changeAll(false) + changeMicCamera(false) privacyItemController.addCallback(callback) executor.runAllReady() verify(appOpsController, never()).addCallback(eq(PrivacyItemController.OPS), -- GitLab From f29300878346146e652b748bd8783f94e89cca6e Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 12 Sep 2020 16:02:51 +0000 Subject: [PATCH 391/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I572d1eae3ec8211183a99dc9cc4d6703408dba83 --- packages/SystemUI/res/values-gl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index fe50a97943ae..539da14d8e52 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -784,7 +784,7 @@ "Deter" "Seguinte" "Anterior" - "Rebobinar" + "Retroceder" "Avance rápido" "Re Páx" "Av Páx" -- GitLab From 1168b0b70b5dc0d6229f3517e5c09947bd27ef05 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 13 Sep 2020 17:25:19 +0000 Subject: [PATCH 392/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I2af3829dc86d8546f811370077bce5c8f561787a --- packages/SettingsLib/res/values-ar/strings.xml | 6 +++--- packages/SettingsLib/res/values-be/strings.xml | 2 +- packages/SettingsLib/res/values-bs/arrays.xml | 2 +- packages/SettingsLib/res/values-eu/strings.xml | 2 +- packages/SettingsLib/res/values-ja/arrays.xml | 2 +- packages/SettingsLib/res/values-ky/strings.xml | 4 ++-- packages/SettingsLib/res/values-mk/strings.xml | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 9acfa0da7747..9ca1814783b5 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -25,7 +25,7 @@ "تم الحفظ" "غير متصلة" "غير مفعّلة" - "‏تعذّرت تهيئة عنوان IP" + "‏تعذّر إعداد عنوان IP" "الجهاز غير متصل بسبب انخفاض جودة الشبكة" "‏تعذّر اتصال WiFi" "حدثت مشكلة في المصادقة" @@ -292,8 +292,8 @@ "عندما نتوقف عن رصد أي أخطاء باستخدام المسجِّل الدائم مرة أخرى، يتعين علينا محو بيانات المسجِّل الموجودة على جهازك." "تخزين بيانات المسجِّل باستمرار على الجهاز" "تحديد مخازن السجلات المؤقتة المراد تخزينها باستمرار على الجهاز" - "‏حدد تهيئة USB" - "‏حدد تهيئة USB" + "‏حدد إعداد USB" + "‏حدد إعداد USB" "السماح بمواقع وهمية" "السماح بمواقع وهمية" "تفعيل فحص سمة العرض" diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 8f71509772fc..7f6237da9ee0 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -212,7 +212,7 @@ "Адладка па Wi-Fi" "Каб праглядаць і выкарыстоўваць даступныя прылады, уключыце адладку па Wi-Fi" "Спалучыць прыладу з дапамогай QR-кода" - "Спалучаць новыя прылады з дапамогай сканера QR-кода" + "Спалучаць новыя прылады з дапамогай сканера QR-кодаў" "Спалучыць прыладу з дапамогай кода спалучэння" "Спалучаць новыя прылады з дапамогай шасцізначнага кода" "Спалучаныя прылады" diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml index 7c2a0fd0c8e4..775cd15edc0b 100644 --- a/packages/SettingsLib/res/values-bs/arrays.xml +++ b/packages/SettingsLib/res/values-bs/arrays.xml @@ -187,7 +187,7 @@ "Isključeno" "Međuspremnici svih zapisnika" "Međuspremnici svih zapisnika osim radija" - "samo međuspremnik zapisnika kernela" + "samo međumemorija zapisnika kernela" "Animacija isključena" diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index dcdadbdf3454..4a11aa77c7fc 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -400,7 +400,7 @@ "Aktibo. Aldatzeko, sakatu hau." "Egonean moduko aplikazioaren egoera: %s" "Abian diren zerbitzuak" - "Ikusi eta kontrolatu unean abian diren zerbitzuak" + "Ikusi eta kontrolatu une honetan abian diren zerbitzuak" "WebView inplementazioa" "Ezarri WebView inplementazioa" "Jada ez dago erabilgarri aukera hori. Saiatu berriro." diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml index 743017c82e3a..7a4e71b18ec0 100644 --- a/packages/SettingsLib/res/values-ja/arrays.xml +++ b/packages/SettingsLib/res/values-ja/arrays.xml @@ -243,7 +243,7 @@ "OFF" - "バーとして画面に表示" + "棒グラフとして画面に表示" "adb shell dumpsys gfxinfo 内" diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index c4b5f7e7477f..419c18f3b8c6 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -396,8 +396,8 @@ "Санарип мазмун үчүн оптималдаштырылган түстөр" "Көшүү режиминдеги колдонмолор" - "Иштеген жок. Которуштуруу үчүн таптап коюңуз." - "Иштеп турат. Которуштуруу үчүн таптап коюңуз." + "Иштеген жок. Күйгүзүү үчүн басып коюңуз." + "Иштеп турат. Өчүрүү үчүн басып коюңуз." "Көшүү режиминдеги колдонмонун абалы: %s" "Иштеп жаткан кызматтар" "Учурда иштеп жаткан кызматтарды көрүп, көзөмөлдөп турасыз" diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index fb7b63410a5f..58d4af1c2c64 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -204,10 +204,10 @@ "Поставките за спојување не се достапни за овој корисник" "Поставките за името на пристапната точка не се достапни за овој корисник" "Отстранување грешки на USB" - "Режим на отстранување грешки кога е поврзано USB" + "Режим за отстранување грешки кога е поврзано USB" "Отповикај овластувања за отстранување грешки од USB" "Безжично отстранување грешки" - "Режим на отстранување грешки кога е поврзано Wi‑Fi" + "Режим за отстранување грешки кога е поврзано Wi‑Fi" "Грешка" "Безжично отстранување грешки" "За да ги гледате и користите достапните уреди, вклучете го безжичното отстранување грешки" -- GitLab From 75cf7679c6c09caebfa50b7d2cda0f1dd96aef7a Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Mon, 24 Aug 2020 08:39:55 +0800 Subject: [PATCH 393/536] Fix NPE when starting activity while no focused task NexusLauncher was not started when FallbackHome finished itself because activities was prevented to be resumed while display is sleeping. So, NPE was thrown while starting an activity because there was no focused task in the display since FallbackHome activity was removed from the task and all tasks were also removed. The activities should still be able to be resumed when calling resumeTop methods explicitly (even when display is sleeping). For the original issue of bubble activities, the activities in secondary display can be prevented from starting by evaluating keyguard-going-away state for default display only. Bug: 164572568 Bug: 160338354 Bug: 168424696 Test: atest ActivityStackTests Change-Id: Ica58b7e8c93e7aa688b335d1ecf7464bc8450e30 Merged-In: Ica58b7e8c93e7aa688b335d1ecf7464bc8450e30 --- .../com/android/server/wm/ActivityStack.java | 8 ++++++-- .../com/android/server/wm/ActivityStarter.java | 5 +++-- .../android/server/wm/RootWindowContainer.java | 4 ---- .../android/server/wm/ActivityStackTests.java | 17 +++++++++++------ .../server/wm/RootActivityContainerTests.java | 18 ------------------ 5 files changed, 20 insertions(+), 32 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index cd508d0e1860..959aedcd1e4a 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -1990,7 +1990,7 @@ class ActivityStack extends Task { return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea()); } - void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity, + void startActivityLocked(ActivityRecord r, @Nullable ActivityRecord focusedTopActivity, boolean newTask, boolean keepCurTransition, ActivityOptions options) { Task rTask = r.getTask(); final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront(); @@ -3336,7 +3336,11 @@ class ActivityStack extends Task { // Do not sleep activities in this stack if we're marked as focused and the keyguard // is in the process of going away. if (isFocusedStackOnDisplay() - && mStackSupervisor.getKeyguardController().isKeyguardGoingAway()) { + && mStackSupervisor.getKeyguardController().isKeyguardGoingAway() + // Avoid resuming activities on secondary displays since we don't want bubble + // activities to be resumed while bubble is still collapsed. + // TODO(b/113840485): Having keyguard going away state for secondary displays. + && display.isDefaultDisplay) { return false; } diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index b869eb56f536..a78232c05397 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1697,8 +1697,9 @@ class ActivityStarter { mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded( false /* forceSend */, mStartActivity); - mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(), - newTask, mKeepCurTransition, mOptions); + mTargetStack.startActivityLocked(mStartActivity, + topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask, + mKeepCurTransition, mOptions); if (mDoResume) { final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked(); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 049e46fb6cef..f57c9164a610 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2305,10 +2305,6 @@ class RootWindowContainer extends WindowContainer for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { final DisplayContent display = getChildAt(displayNdx); - if (display.shouldSleep()) { - continue; - } - boolean resumedOnDisplay = false; for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index 1b42a0466cf7..e898c2573315 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -1206,19 +1206,22 @@ public class ActivityStackTests extends ActivityTestsBase { @Test public void testShouldSleepActivities() { // When focused activity and keyguard is going away, we should not sleep regardless - // of the display state + // of the display state, but keyguard-going-away should only take effects on default + // display since there is no keyguard on secondary displays (yet). verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/, - true /* displaySleeping */, false /* expected*/); + true /* displaySleeping */, true /* isDefaultDisplay */, false /* expected */); + verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/, + true /* displaySleeping */, false /* isDefaultDisplay */, true /* expected */); // When not the focused stack, defer to display sleeping state. verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/, - true /* displaySleeping */, true /* expected*/); + true /* displaySleeping */, true /* isDefaultDisplay */, true /* expected */); // If keyguard is going away, defer to the display sleeping state. verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/, - true /* displaySleeping */, true /* expected*/); + true /* displaySleeping */, true /* isDefaultDisplay */, true /* expected */); verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/, - false /* displaySleeping */, false /* expected*/); + false /* displaySleeping */, true /* isDefaultDisplay */, false /* expected */); } @Test @@ -1428,9 +1431,11 @@ public class ActivityStackTests extends ActivityTestsBase { } private void verifyShouldSleepActivities(boolean focusedStack, - boolean keyguardGoingAway, boolean displaySleeping, boolean expected) { + boolean keyguardGoingAway, boolean displaySleeping, boolean isDefaultDisplay, + boolean expected) { final DisplayContent display = mock(DisplayContent.class); final KeyguardController keyguardController = mSupervisor.getKeyguardController(); + display.isDefaultDisplay = isDefaultDisplay; doReturn(display).when(mStack).getDisplay(); doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway(); diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java index c848736a64c2..51db099676b0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java @@ -896,24 +896,6 @@ public class RootActivityContainerTests extends ActivityTestsBase { assertEquals(taskDisplayArea.getTopStack(), taskDisplayArea.getRootHomeTask()); } - @Test - public void testResumeFocusedStackOnSleepingDisplay() { - // Create an activity on secondary display. - final TestDisplayContent secondDisplay = addNewDisplayContentAt( - DisplayContent.POSITION_TOP); - final ActivityStack stack = secondDisplay.getDefaultTaskDisplayArea() - .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityRecord activity = new ActivityBuilder(mService).setStack(stack).build(); - spyOn(activity); - spyOn(stack); - - // Cannot resumed activities on secondary display if the display should sleep. - doReturn(true).when(secondDisplay).shouldSleep(); - mRootWindowContainer.resumeFocusedStacksTopActivities(); - verify(stack, never()).resumeTopActivityUncheckedLocked(any(), any()); - verify(activity, never()).makeActiveIfNeeded(any()); - } - /** * Mock {@link RootWindowContainer#resolveHomeActivity} for returning consistent activity * info for test cases. -- GitLab From eba59d16f033faff64c54d325a74f17e45909113 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 14 Sep 2020 09:00:41 +0000 Subject: [PATCH 394/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I56c3b73c881bae6f51565f987fd2ea877c61d031 --- core/res/res/values-ar/strings.xml | 20 ++++++++++---------- core/res/res/values-bs/strings.xml | 4 ++-- core/res/res/values-es-rUS/strings.xml | 2 +- core/res/res/values-gl/strings.xml | 2 +- core/res/res/values-hu/strings.xml | 6 +++--- core/res/res/values-hy/strings.xml | 2 +- core/res/res/values-ky/strings.xml | 2 +- core/res/res/values-mn/strings.xml | 2 +- core/res/res/values-nl/strings.xml | 16 ++++++++-------- core/res/res/values-sv/strings.xml | 2 +- core/res/res/values-sw/strings.xml | 2 +- 11 files changed, 30 insertions(+), 30 deletions(-) diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 6978a9aefb17..f5001472e74a 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -270,9 +270,9 @@ "وضع صامت" "الصوت متوقف" "الصوت قيد التفعيل" - "وضع الطائرة" - "وضع الطائرة قيد التفعيل" - "وضع الطائرة متوقف" + "وضع الطيران" + "وضع الطيران قيد التفعيل" + "وضع الطيران متوقف" "الإعدادات" "مساعدة" "المساعد الصوتي" @@ -398,7 +398,7 @@ "قياس مساحة تخزين التطبيق" "للسماح للتطبيق باسترداد شفرته وبياناته وأحجام ذاكرات التخزين المؤقت" "تعديل إعدادات النظام" - "للسماح للتطبيق بتعديل بيانات إعدادات النظام. يمكن أن تتلف التطبيقات الضارة تهيئة نظامك." + "للسماح للتطبيق بتعديل بيانات إعدادات النظام. يمكن أن تتلف التطبيقات الضارة إعداد نظامك." "العمل عند بدء التشغيل" "للسماح للتطبيق ببدء تشغيل نفسه عقب انتهاء النظام من التشغيل. قد يؤدي ذلك إلى استغراق المزيد من الوقت عند بدء الجهاز اللوحي والسماح للتطبيق بإبطاء الأداء الإجمالي للجهاز اللوحي من خلال تشغيله دائمًا." "‏للسماح بتشغيل التطبيق تلقائيًا بعد الانتهاء من بدء تشغيل النظام. وقد يؤدي ذلك إلى إطالة فترة بدء تشغيل جهاز Android TV، بالإضافة إلى أنه يسمح للتطبيق بإبطاء أداء الجهاز بشكل عام لأنه يتم تشغيله بشكل دائم." @@ -507,7 +507,7 @@ "‏عرض اتصالات Wi-Fi" "‏للسماح للتطبيق بعرض معلومات حول شبكات Wi-Fi، كعرض معلومات حول ما إذا تم تفعيل Wi-Fi واسم أجهزة Wi-Fi المتصلة." "‏التوصيل والفصل من Wi-Fi" - "‏للسماح للتطبيق بالاتصال بنقاط الوصول إلى Wi-Fi وقطع الاتصال بها، وإجراء تغييرات على تهيئة الجهاز لشبكات Wi-Fi." + "‏للسماح للتطبيق بالاتصال بنقاط الوصول إلى Wi-Fi وقطع الاتصال بها، وإجراء تغييرات على إعداد الجهاز لشبكات Wi-Fi." "‏السماح باستقبال بث Wi-Fi متعدد" "‏للسماح للتطبيق بتلقي الحزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام جهازك اللوحي فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق وضع البث غير المتعدد." "‏للسماح للتطبيق بتلقّي الحِزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام جهاز Android TV فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق ما يتم استهلاكه في وضع البث غير المتعدد." @@ -661,8 +661,8 @@ "للسماح للمالك بالربط بواجهة المستوى العلوي لخدمة موفر الحالة. لن تكون هناك حاجة إلى هذا الإعداد مطلقًا مع التطبيقات العادية." "‏الالتزام بخدمة dream" "‏للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة dream. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية." - "استدعاء تطبيق التهيئة الذي يوفره مشغل شبكة الجوال" - "للسماح للمالك باستدعاء تطبيق التهيئة الذي يوفره مشغل شبكة الجوال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية." + "استدعاء تطبيق الإعداد الذي يوفره مشغل شبكة الجوال" + "للسماح للمالك باستدعاء تطبيق الإعداد الذي يوفره مشغل شبكة الجوال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية." "الاستماع إلى ملاحظات حول أحوال الشبكة" "للسماح للتطبيق بالاستماع إلى ملاحظات حول أحوال الشبكة. لا حاجة إلى هذا مع التطبيقات العادية." "تغيير معايرة أجهزة الإدخال" @@ -678,7 +678,7 @@ "الالتزام بخدمات مشغل شبكة الجوال" "للسماح للمالك بالالتزام بخدمات مشغل شبكة الجوال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية." "الوصول إلى إعداد \"عدم الإزعاج\"" - "للسماح للتطبيق بقراءة تهيئة \"عدم الإزعاج\" وكتابتها." + "للسماح للتطبيق بقراءة إعداد \"عدم الإزعاج\" وكتابتها." "بدء استخدام إذن العرض" "للسماح للمالك ببدء استخدام الإذن لأحد التطبيقات. ولن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية." "تعيين قواعد كلمة المرور" @@ -1462,7 +1462,7 @@ "تالف" "غير متوافق" "جارٍ إنهاء التحميل…" - "جارٍ التهيئة…" + "تجري التهيئة..." "لم يتم الإدخال" "لم يتم العثور على أي أنشطة متطابقة." "توجيه إخراج الوسائط" @@ -2155,7 +2155,7 @@ "جدول بيانات: %1$s" "عرض تقديمي" "عرض تقديمي: %1$s" - "سيظل البلوتوث مفعَّلاً أثناء استخدام \"وضع الطائرة\"." + "سيظل البلوتوث مفعَّلاً أثناء استخدام \"وضع الطيران\"." "جارٍ التحميل" %s و%d ملف diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 02dd4f2bfe3c..32495371ad01 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -970,7 +970,7 @@ "Zapamti" "Nikad" "Nemate odobrenje za otvaranje ove stranice." - "Tekst kopiran u međuspremnik." + "Tekst kopiran u međumemoriju." "Kopirano" "Više" "Meni+" @@ -1280,7 +1280,7 @@ "nepoznata vrsta mreže" "Prihvati" "Odbijte" - "Umetni karakter" + "Umetni znak" "Slanje SMS poruka" "<b>%1$s</b> šalje veliki broj SMS poruka. Da li želite dozvoliti ovoj aplikaciji da nastavi slanje poruka?" "Dozvoli" diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index b8c00d049721..1024729b53fe 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -421,7 +421,7 @@ "Esta app puede agregar, quitar o cambiar eventos del calendario en tu teléfono. Puede enviar mensajes que parecen proceder de propietarios del calendario o cambiar eventos sin notificarlos." "acceder a comandos adicionales del proveedor del lugar" "Permite que la aplicación acceda a comandos adicionales del proveedor de ubicación. Esto puede permitirle a la aplicación interferir con el funcionamiento del GPS o de otras fuentes de ubicación." - "acceder a la ubicación exacta solo en primer plano" + "acceder a la ubicación precisa solo en primer plano" "Mientras la usas, esta app puede obtener tu ubicación exacta mediante los Servicios de ubicación, siempre y cuando el dispositivo los tenga activados. Es posible que esto aumente el uso de batería." "acceder a la ubicación aproximada solo en primer plano" "Mientras la usas, esta app puede obtener tu ubicación aproximada mediante los Servicios de ubicación, siempre y cuando el dispositivo los tenga activados." diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index e5600b0e414d..b7a332efed21 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -849,7 +849,7 @@ "Pausar" "Reproducir" "Deter" - "Rebobinar" + "Retroceder" "Avance rápido" "Só chamadas de emerxencia" "Bloqueada pola rede" diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index b66d7cb3136e..34e1db5ef4ce 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -307,7 +307,7 @@ "hanganyag rögzítése" "Testmozgás" "hozzáférés a testmozgási adatokhoz" - "Fényképezőgép" + "Kamera" "fotók és videók készítése" "Hívásnaplók" "hívásnapló olvasása és írása" @@ -1900,8 +1900,8 @@ "A feloldáshoz koppintson rá" "Csatlakoztatva a(z) %1$s eszközhöz" "Koppintson ide a fájlok megtekintéséhez" - "Rögzítés" - "%1$s rögzítése" + "Kitűzés" + "%1$s kitűzése" "Feloldás" "%1$s rögzítésének feloldása" "Alkalmazásinformáció" diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index b531d02998e4..30b092d92a80 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1979,7 +1979,7 @@ "Չհաջողվեց վերականգնել դյուրանցումը, քանի որ հավելվածների ստորագրությունները տարբեր են" "Չհաջողվեց վերականգնել դյուրանցումը" "Դյուրանցումն անջատված է" - "ՀԵՌԱՑՆԵԼ" + "ԱՊԱՏԵՂԱԴՐԵԼ" "ԲԱՑԵԼ" "Հայտնաբերվել է վնասաբեր հավելված" "%1$s հավելվածն ուզում է ցուցադրել հատվածներ %2$s հավելվածից" diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index edc4de685334..1517c17d9615 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1317,7 +1317,7 @@ "Сериялык консоль иштетилди" "Майнаптуулугуна таасири тиет. Аны өчүрүү үчүн операциялык тутумду жүктөгүчтү текшериңиз." "USB портунда суюктук же урандылар бар" - "USB порт автоматтык түрдө өчүрүлдү. Кененирээк маалымат алуу үчүн, таптап коюңуз." + "USB порт автоматтык түрдө өчтү. Кененирээк маалымат алуу үчүн, таптап коюңуз." "USB портун колдонууга болот" "Телефон суюктук менен урандыларды аныктаган жок." "Мүчүлүштүк тууралуу кабар алынууда…" diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 6af5d5ee87ca..3833605fa78b 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -1117,7 +1117,7 @@ "ОК" "Цуцлах" "Анхаар" - "Ачааллаж байна..." + "Ачаалж байна..." "Идэвхтэй" "Идэвхгүй" "тэмдэглэсэн" diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 95d5f8f3ab64..439a1a31b894 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1276,7 +1276,7 @@ "Nooit toestaan" "Simkaart verwijderd" "Het mobiele netwerk is niet beschikbaar totdat u het apparaat opnieuw start met een geldige simkaart." - "Gereed" + "Klaar" "Simkaart aangesloten" "Start je apparaat opnieuw voor toegang tot het mobiele netwerk." "Opnieuw starten" @@ -1289,7 +1289,7 @@ "Tijd instellen" "Datum instellen" "Instellen" - "Gereed" + "Klaar" "NIEUW: " "Geleverd door %1$s." "Geen rechten nodig" @@ -1376,7 +1376,7 @@ "Verwijderd" "Uitgeworpen" "Controleren…" - "Gereed" + "Klaar" "Alleen lezen" "Onveilig verwijderd" "Beschadigd" @@ -1401,7 +1401,7 @@ "Zoeken" "Verzenden" "Volgende" - "Gereed" + "Klaar" "Vorige" "Uitvoeren" "Nummer bellen\nmet %s" @@ -1448,7 +1448,7 @@ %d van %d 1 overeenkomst - "Gereed" + "Klaar" "Gedeelde opslag wissen…" "Delen" "Vinden" @@ -1492,7 +1492,7 @@ "Alt" "Annuleren" "Delete" - "Gereed" + "Klaar" "Modus wijzigen" "Shift" "Enter" @@ -1645,7 +1645,7 @@ "Functies kiezen voor gebruik met de sneltoets via de volumeknop" "%s is uitgeschakeld" "Snelkoppelingen bewerken" - "Gereed" + "Klaar" "Sneltoets uitschakelen" "Sneltoets gebruiken" "Kleurinversie" @@ -1774,7 +1774,7 @@ "Volledig scherm wordt weergegeven" "Swipe omlaag vanaf de bovenkant van het scherm om af te sluiten." "Ik snap het" - "Gereed" + "Klaar" "Ronde schuifregelaar voor uren" "Ronde schuifregelaar voor minuten" "Uren selecteren" diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index fe647cb70d4c..279c619c65fc 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1829,7 +1829,7 @@ I %d tim I en 1 tim - "Till kl. %1$s" + "Till %1$s" "Till %1$s (nästa alarm)" "Tills du stänger av" "Tills du inaktiverar Stör ej" diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 8276905e2ef0..e168ae44a2d0 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -303,7 +303,7 @@ "itume na iangalie SMS" "Faili na maudhui" "ifikie picha, maudhui na faili kwenye kifaa chako" - "Kipokea sauti" + "Maikrofoni" "irekodi sauti" "Shughuli za kimwili" "ifikie shughuli zako za kimwili" -- GitLab From f71dbc4559b02d67b69cb85f62843007f58eb37c Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 14 Sep 2020 10:33:03 +0000 Subject: [PATCH 395/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ifa519b1746e37bcd08cdbbce12fe0c05508b0b58 --- .../DynamicSystemInstallationService/res/values-nl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/DynamicSystemInstallationService/res/values-nl/strings.xml b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml index 47eeb839c6dc..2b9fa414dcc5 100644 --- a/packages/DynamicSystemInstallationService/res/values-nl/strings.xml +++ b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml @@ -2,7 +2,7 @@ "Geef je wachtwoord op en ga door naar \'Dynamische systeemupdates\'" - "Dynamisch systeem is gereed. Start je apparaat opnieuw op om het te gebruiken." + "Dynamisch systeem is klaar. Start je apparaat opnieuw op om het te gebruiken." "Installatie wordt uitgevoerd" "Installatie mislukt" "Valideren van afbeelding mislukt. Installatie afbreken." -- GitLab From f5075cb77d60881a5fa01bc9d64a09366045ced3 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 14 Sep 2020 14:43:09 +0000 Subject: [PATCH 396/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: If9a1b6cd93d2c11caa1170046df69e3957177518 --- packages/PackageInstaller/res/values-ar/strings.xml | 2 +- packages/PackageInstaller/res/values-nl/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml index 87f89ce192c4..c840374d3f6b 100644 --- a/packages/PackageInstaller/res/values-ar/strings.xml +++ b/packages/PackageInstaller/res/values-ar/strings.xml @@ -57,7 +57,7 @@ "هل تريد إزالة هذا التطبيق ""لكل"" المستخدمين؟ ستتم إزالة التطبيق وبياناته من ""كل"" المستخدمين على هذا الجهاز." "هل تريد إزالة هذا التطبيق للمستخدم %1$s؟" "هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات." - "هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات. وسيؤثر هذا في جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل." + "هل تريد إعادة ضبط هذا التطبيق على الإعدادات الأصلية؟ سؤدي ذلك إلى إزالة جميع البيانات، كما سيؤثر على جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل." "الاحتفاظ بالحجم %1$s من بيانات التطبيق." "عمليات إلغاء التثبيت الجارية" "عمليات إلغاء التثبيت غير الناجحة" diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml index 108c86fe8369..d3a958922d1c 100644 --- a/packages/PackageInstaller/res/values-nl/strings.xml +++ b/packages/PackageInstaller/res/values-nl/strings.xml @@ -18,7 +18,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Pakket-installatie" "Installeren" - "Gereed" + "Klaar" "Annuleren" "Installeren…" "%1$s installeren…" -- GitLab From e214fb4f25c775b16f15fbcc3ca34713e033b5ca Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Fri, 28 Aug 2020 11:25:04 -0400 Subject: [PATCH 397/536] Add log to NoMan for canceled cancels In the case where a notification_cancel is skipped when finding a more recently enqueued notification for the same key, now throw a log so we know that we're dropping a message from the system. Bug: 162652224 Test: manual Change-Id: I313076f8b15b00286f532ace1bbe7da2f7db4afe --- .../android/server/notification/NotificationManagerService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index e42dd359dad1..5d0981da1906 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -6245,6 +6245,8 @@ public class NotificationManagerService extends SystemService { for (NotificationRecord r : enqueued) { if (r.mUpdateTimeMs > mWhen) { // At least one enqueue was posted after the cancel, so we're invalid + Slog.i(TAG, "notification cancel ignored due to newer enqueued entry" + + "key=" + r.getSbn().getKey()); return; } } -- GitLab From 6d51c36542616a74c149109dcc667ed628a474cf Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Mon, 14 Sep 2020 11:26:53 -0400 Subject: [PATCH 398/536] Add placeholder to priority onboarding When an app hasn't provided an icon for their conversation Test: manual Fixes: 168184445 Change-Id: Iea9abe87c787c6d42210cb9b51f90715a3cc7d33 --- .../row/NotificationConversationInfo.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java index f543db74d91a..25a0ea515ea3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java @@ -42,6 +42,8 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutManager; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; @@ -539,12 +541,21 @@ public class NotificationConversationInfo extends LinearLayout implements && Settings.Global.getInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 0) == 1; + Drawable person = mIconFactory.getBaseIconDrawable(mShortcutInfo); + if (person == null) { + person = mContext.getDrawable(R.drawable.ic_person).mutate(); + TypedArray ta = mContext.obtainStyledAttributes(new int[]{android.R.attr.colorAccent}); + int colorAccent = ta.getColor(0, 0); + ta.recycle(); + person.setTint(colorAccent); + } + PriorityOnboardingDialogController controller = mBuilderProvider.get() .setContext(mUserContext) .setView(onboardingView) .setIgnoresDnd(ignoreDnd) .setShowsAsBubble(showAsBubble) - .setIcon(mIconFactory.getBaseIconDrawable(mShortcutInfo)) + .setIcon(person) .setBadge(mIconFactory.getAppBadge( mPackageName, UserHandle.getUserId(mSbn.getUid()))) .setOnSettingsClick(mOnConversationSettingsClickListener) -- GitLab From 520fbd2ae4ce76903613c712c6dcc58a6caeac3e Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 14 Sep 2020 18:03:01 +0000 Subject: [PATCH 399/536] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I2f5e6156db6eb5499618284bee821433a1f0fd86 --- packages/SystemUI/res-keyguard/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml index 6d86a78360d8..65e3f0dbd176 100644 --- a/packages/SystemUI/res-keyguard/values-ar/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml @@ -112,7 +112,7 @@ "تم قبول الرمز" "لا تتوفر خدمة." "تبديل أسلوب الإدخال" - "وضع الطائرة" + "وضع الطيران" "يجب رسم النقش بعد إعادة تشغيل الجهاز" "يجب إدخال رقم التعريف الشخصي بعد إعادة تشغيل الجهاز" "يجب إدخال كلمة المرور بعد إعادة تشغيل الجهاز" -- GitLab From 7d26c8c526e49a290fd90a3365439ee887856a7b Mon Sep 17 00:00:00 2001 From: Patrick Baumann Date: Wed, 29 Jul 2020 14:21:00 -0700 Subject: [PATCH 400/536] Expose grantImplicitAccess in IPackageManager This change exposes the method to grant implicit visibility access via IPackageManager and as a hidden API in PackageManager. This variant of the method takes a recipient UID and the authority that it should see and limits access to only the contacts provider on device. Bug: 158688602 Test: PackageManagerTests Change-Id: I0050593e4aa734af1a69a40a60746f7cf0ea72df --- .../android/content/pm/IPackageManager.aidl | 2 ++ .../android/content/pm/PackageManager.java | 14 ++++++++++ .../server/pm/PackageManagerService.java | 27 +++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index f257326904fd..2138f53e9f54 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -785,4 +785,6 @@ interface IPackageManager { List getMimeGroup(String packageName, String group); boolean isAutoRevokeWhitelisted(String packageName); + + void grantImplicitAccess(int queryingUid, String visibleAuthority); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index ea4a2a0b8c35..8a7214db31eb 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -8011,6 +8011,20 @@ public abstract class PackageManager { "getMimeGroup not implemented in subclass"); } + /** + * Grants implicit visibility of the package that provides an authority to a querying UID. + * + * @throws SecurityException when called by a package other than the contacts provider + * @hide + */ + public void grantImplicitAccess(int queryingUid, String visibleAuthority) { + try { + ActivityThread.getPackageManager().grantImplicitAccess(queryingUid, visibleAuthority); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + // Some of the flags don't affect the query result, but let's be conservative and cache // each combination of flags separately. diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5c3644e5b262..d994d61eb505 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -280,6 +280,7 @@ import android.os.storage.StorageManagerInternal; import android.os.storage.VolumeInfo; import android.os.storage.VolumeRecord; import android.permission.IPermissionManager; +import android.provider.ContactsContract; import android.provider.DeviceConfig; import android.provider.Settings.Global; import android.provider.Settings.Secure; @@ -25423,6 +25424,32 @@ public class PackageManagerService extends IPackageManager.Stub } } + @Override + public void grantImplicitAccess(int recipientUid, String visibleAuthority) { + // This API is exposed temporarily to only the contacts provider. (b/158688602) + final int callingUid = Binder.getCallingUid(); + ProviderInfo contactsProvider = resolveContentProviderInternal( + ContactsContract.AUTHORITY, 0, UserHandle.USER_SYSTEM); + if (contactsProvider == null || contactsProvider.applicationInfo == null + || !UserHandle.isSameApp(contactsProvider.applicationInfo.uid, callingUid)) { + throw new SecurityException(callingUid + " is not allow to call grantImplicitAccess"); + } + final int userId = UserHandle.getUserId(recipientUid); + final long token = Binder.clearCallingIdentity(); + final ProviderInfo providerInfo; + try { + providerInfo = resolveContentProvider(visibleAuthority, 0 /*flags*/, userId); + } finally { + Binder.restoreCallingIdentity(token); + } + if (providerInfo == null) { + return; + } + int visibleUid = providerInfo.applicationInfo.uid; + mPmInternal.grantImplicitAccess(userId, null /*Intent*/, UserHandle.getAppId(recipientUid), + visibleUid, false); + } + boolean canHaveOatDir(String packageName) { synchronized (mLock) { AndroidPackage p = mPackages.get(packageName); -- GitLab From 5b5fdb80ec9ffa00a4d35dfc84fa8f28d9a6d8fb Mon Sep 17 00:00:00 2001 From: Marco Ballesio Date: Thu, 10 Sep 2020 13:36:14 -0700 Subject: [PATCH 401/536] ActivityManager: kill frozen processes receiving sync transactions Synchronous transactions to frozen processes are rejected by binder, which can potentially leave these processes in an unclean state when unfrozen. Kill such processes insted of unfreezing then when they're removed from the cache. This patch also increases the timeout before freezing an app, to allow pending transactions to be processes for a longer window after caching and so to reduce the amount of background kills. Bug: 143717177 Test: cached/frozen a few apps, sent sync and async transactions to them and verified that killing happened when expected. Change-Id: Ieca9d49e1befd1358862aa7afeeec15a408d7ef3 --- .../android/server/am/CachedAppOptimizer.java | 55 ++++++++++++++++++- ...m_android_server_am_CachedAppOptimizer.cpp | 30 +++++++++- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 966038986791..8112bb854b71 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -22,6 +22,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import android.app.ActivityManager; import android.app.ActivityThread; +import android.app.ApplicationExitInfo; import android.os.Debug; import android.os.Handler; import android.os.Message; @@ -132,11 +133,15 @@ public final class CachedAppOptimizer { static final int REPORT_UNFREEZE_MSG = 4; //TODO:change this static definition into a configurable flag. - static final int FREEZE_TIMEOUT_MS = 500; + static final int FREEZE_TIMEOUT_MS = 10000; static final int DO_FREEZE = 1; static final int REPORT_UNFREEZE = 2; + // Bitfield values for sync/async transactions reveived by frozen processes + static final int SYNC_RECEIVED_WHILE_FROZEN = 1; + static final int ASYNC_RECEIVED_WHILE_FROZEN = 2; + /** * This thread must be moved to the system background cpuset. * If that doesn't happen, it's probably going to draw a lot of power. @@ -493,6 +498,15 @@ public final class CachedAppOptimizer { */ private static native void freezeBinder(int pid, boolean freeze); + /** + * Retrieves binder freeze info about a process. + * @param pid the pid for which binder freeze info is to be retrieved. + * + * @throws RuntimeException if the operation could not complete successfully. + * @return a bit field reporting the binder freeze info for the process. + */ + private static native int getBinderFreezeInfo(int pid); + /** * Determines whether the freezer is supported by this system */ @@ -729,6 +743,37 @@ public final class CachedAppOptimizer { return; } + boolean processKilled = false; + + try { + int freezeInfo = getBinderFreezeInfo(app.pid); + + if ((freezeInfo & SYNC_RECEIVED_WHILE_FROZEN) != 0) { + Slog.d(TAG_AM, "pid " + app.pid + " " + app.processName + " " + + " received sync transactions while frozen, killing"); + app.kill("Sync transaction while in frozen state", + ApplicationExitInfo.REASON_OTHER, + ApplicationExitInfo.SUBREASON_INVALID_STATE, true); + processKilled = true; + } + + if ((freezeInfo & ASYNC_RECEIVED_WHILE_FROZEN) != 0) { + Slog.d(TAG_AM, "pid " + app.pid + " " + app.processName + " " + + " received async transactions while frozen"); + } + } catch (Exception e) { + Slog.d(TAG_AM, "Unable to query binder frozen info for pid " + app.pid + " " + + app.processName + ". Killing it. Exception: " + e); + app.kill("Unable to query binder frozen stats", + ApplicationExitInfo.REASON_OTHER, + ApplicationExitInfo.SUBREASON_INVALID_STATE, true); + processKilled = true; + } + + if (processKilled) { + return; + } + long freezeTime = app.freezeUnfreezeTime; try { @@ -745,8 +790,12 @@ public final class CachedAppOptimizer { try { freezeBinder(app.pid, false); } catch (RuntimeException e) { - // TODO: it might be preferable to kill the target pid in this case - Slog.e(TAG_AM, "Unable to unfreeze binder for " + app.pid + " " + app.processName); + Slog.e(TAG_AM, "Unable to unfreeze binder for " + app.pid + " " + app.processName + + ". Killing it"); + app.kill("Unable to unfreeze", + ApplicationExitInfo.REASON_OTHER, + ApplicationExitInfo.SUBREASON_INVALID_STATE, true); + return; } if (DEBUG_FREEZER) { diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp index 95d4ba7c199a..678308af34ea 100644 --- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp @@ -36,6 +36,9 @@ using android::base::StringPrintf; using android::base::WriteStringToFile; +#define SYNC_RECEIVED_WHILE_FROZEN (1) +#define ASYNC_RECEIVED_WHILE_FROZEN (2) + namespace android { // This performs per-process reclaim on all processes belonging to non-app UIDs. @@ -99,12 +102,37 @@ static void com_android_server_am_CachedAppOptimizer_freezeBinder( } } +static jint com_android_server_am_CachedAppOptimizer_getBinderFreezeInfo(JNIEnv *env, + jobject clazz, jint pid) { + bool syncReceived = false, asyncReceived = false; + + int error = IPCThreadState::getProcessFreezeInfo(pid, &syncReceived, &asyncReceived); + + if (error < 0) { + jniThrowException(env, "java/lang/RuntimeException", strerror(error)); + } + + jint retVal = 0; + + if(syncReceived) { + retVal |= SYNC_RECEIVED_WHILE_FROZEN;; + } + + if(asyncReceived) { + retVal |= ASYNC_RECEIVED_WHILE_FROZEN; + } + + return retVal; +} + static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ {"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem}, {"enableFreezerInternal", "(Z)V", (void*)com_android_server_am_CachedAppOptimizer_enableFreezerInternal}, - {"freezeBinder", "(IZ)V", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder} + {"freezeBinder", "(IZ)V", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder}, + {"getBinderFreezeInfo", "(I)I", + (void*)com_android_server_am_CachedAppOptimizer_getBinderFreezeInfo} }; int register_android_server_am_CachedAppOptimizer(JNIEnv* env) -- GitLab From c22364237abbaa6a092f2d8732becc101b3a1511 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Mon, 14 Sep 2020 17:52:02 +0800 Subject: [PATCH 402/536] Update language to comply with Android's inclusive language guidance See https://source.android.com/setup/contribute/respectful-code for reference. Bug: 162536543 Test: Treehugger Change-Id: I6dac60aac172a8fccf4b5671107b41c5c84ccd76 Merged-In: I6dac60aac172a8fccf4b5671107b41c5c84ccd76 --- .../java/android/content/pm/ActivityInfo.java | 6 +- .../server/am/PendingTempWhitelists.java | 4 +- .../com/android/server/wm/ActivityRecord.java | 4 +- .../server/wm/ActivityStackSupervisor.java | 4 +- .../wm/ActivityTaskManagerInternal.java | 4 +- .../server/wm/ActivityTaskManagerService.java | 26 +-- .../android/server/wm/LockTaskController.java | 44 ++--- .../com/android/server/wm/PolicyControl.java | 42 ++--- .../com/android/server/wm/RecentTasks.java | 3 +- .../server/wm/RootWindowContainer.java | 2 +- .../server/wm/SafeActivityOptions.java | 4 +- .../core/java/com/android/server/wm/Task.java | 16 +- .../server/wm/ActivityRecordTests.java | 4 +- .../server/wm/LockTaskControllerTest.java | 162 +++++++++--------- 14 files changed, 163 insertions(+), 162 deletions(-) diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index bd02210259b8..31c77eeb5424 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -963,7 +963,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { /** @hide */ public static final int LOCK_TASK_LAUNCH_MODE_ALWAYS = 2; /** @hide */ - public static final int LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED = 3; + public static final int LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED = 3; /** @hide */ public static final String lockTaskLaunchModeToString(int lockTaskLaunchMode) { @@ -974,8 +974,8 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { return "LOCK_TASK_LAUNCH_MODE_NEVER"; case LOCK_TASK_LAUNCH_MODE_ALWAYS: return "LOCK_TASK_LAUNCH_MODE_ALWAYS"; - case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED: - return "LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED"; + case LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED: + return "LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED"; default: return "unknown=" + lockTaskLaunchMode; } diff --git a/services/core/java/com/android/server/am/PendingTempWhitelists.java b/services/core/java/com/android/server/am/PendingTempWhitelists.java index b36e3c7b9e35..50d58f02baa7 100644 --- a/services/core/java/com/android/server/am/PendingTempWhitelists.java +++ b/services/core/java/com/android/server/am/PendingTempWhitelists.java @@ -32,13 +32,13 @@ final class PendingTempWhitelists { void put(int uid, ActivityManagerService.PendingTempWhitelist value) { mPendingTempWhitelist.put(uid, value); - mService.mAtmInternal.onUidAddedToPendingTempWhitelist(uid, value.tag); + mService.mAtmInternal.onUidAddedToPendingTempAllowlist(uid, value.tag); } void removeAt(int index) { final int uid = mPendingTempWhitelist.keyAt(index); mPendingTempWhitelist.removeAt(index); - mService.mAtmInternal.onUidRemovedFromPendingTempWhitelist(uid); + mService.mAtmInternal.onUidRemovedFromPendingTempAllowlist(uid); } ActivityManagerService.PendingTempWhitelist get(int uid) { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 5339d86a7b78..1a13d0fc64c4 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -70,7 +70,7 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT; -import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; +import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER; import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS; import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY; @@ -1680,7 +1680,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (options != null) { final boolean useLockTask = options.getLockTaskMode(); if (useLockTask && lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_DEFAULT) { - lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; + lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED; } } return lockTaskLaunchMode; diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index 6bfcf0c75b83..3dd82a6221c6 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -75,9 +75,9 @@ import static com.android.server.wm.RootWindowContainer.TAG_STATES; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK; +import static com.android.server.wm.Task.LOCK_TASK_AUTH_ALLOWLISTED; import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE; import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; -import static com.android.server.wm.Task.LOCK_TASK_AUTH_WHITELISTED; import static com.android.server.wm.Task.REPARENT_KEEP_STACK_AT_FRONT; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; @@ -788,7 +788,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { final LockTaskController lockTaskController = mService.getLockTaskController(); if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV - || (task.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED + || (task.mLockTaskAuth == LOCK_TASK_AUTH_ALLOWLISTED && lockTaskController.getLockTaskModeState() == LOCK_TASK_MODE_LOCKED)) { lockTaskController.startLockTaskMode(task, false, 0 /* blank UID */); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index a903bcd3d728..d4dd35f53cf0 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -520,8 +520,8 @@ public abstract class ActivityTaskManagerInternal { public abstract void onActiveUidsCleared(); public abstract void onUidProcStateChanged(int uid, int procState); - public abstract void onUidAddedToPendingTempWhitelist(int uid, String tag); - public abstract void onUidRemovedFromPendingTempWhitelist(int uid); + public abstract void onUidAddedToPendingTempAllowlist(int uid, String tag); + public abstract void onUidRemovedFromPendingTempAllowlist(int uid); /** Handle app crash event in {@link android.app.IActivityController} if there is one. */ public abstract boolean handleAppCrashInActivityController(String processName, int pid, diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 52d4b6fc78df..0542ef9b09a4 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -382,7 +382,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { private AppOpsManager mAppOpsManager; /** All active uids in the system. */ private final MirrorActiveUids mActiveUids = new MirrorActiveUids(); - private final SparseArray mPendingTempWhitelist = new SparseArray<>(); + private final SparseArray mPendingTempAllowlist = new SparseArray<>(); /** All processes currently running that might have a window organized by name. */ final ProcessMap mProcessNames = new ProcessMap<>(); /** All processes we currently have running mapped by pid and uid */ @@ -1099,7 +1099,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public int startActivityIntentSender(IApplicationThread caller, IIntentSender target, - IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo, + IBinder allowlistToken, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) { enforceNotIsolatedCaller("startActivityIntentSender"); // Refuse possible leaked file descriptors @@ -1122,7 +1122,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mAppSwitchesAllowedTime = 0; } } - return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null, + return pir.sendInner(0, fillInIntent, resolvedType, allowlistToken, null, null, resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions); } @@ -3025,7 +3025,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // system or a specific app. // * System-initiated requests will only start the pinned mode (screen pinning) // * App-initiated requests - // - will put the device in fully locked mode (LockTask), if the app is whitelisted + // - will put the device in fully locked mode (LockTask), if the app is allowlisted // - will start the pinned mode, otherwise final int callingUid = Binder.getCallingUid(); long ident = Binder.clearCallingIdentity(); @@ -3073,7 +3073,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { "updateLockTaskPackages()"); } synchronized (mGlobalLock) { - if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" + if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowlisting " + userId + ":" + Arrays.toString(packages)); getLockTaskController().updateLockTaskPackages(userId, packages); } @@ -5962,11 +5962,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } /** - * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on - * the whitelist + * @return allowlist tag for a uid from mPendingTempAllowlist, null if not currently on + * the allowlist */ - String getPendingTempWhitelistTagForUidLocked(int uid) { - return mPendingTempWhitelist.get(uid); + String getPendingTempAllowlistTagForUidLocked(int uid) { + return mPendingTempAllowlist.get(uid); } void logAppTooSlow(WindowProcessController app, long startTime, String msg) { @@ -7295,16 +7295,16 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void onUidAddedToPendingTempWhitelist(int uid, String tag) { + public void onUidAddedToPendingTempAllowlist(int uid, String tag) { synchronized (mGlobalLockWithoutBoost) { - mPendingTempWhitelist.put(uid, tag); + mPendingTempAllowlist.put(uid, tag); } } @Override - public void onUidRemovedFromPendingTempWhitelist(int uid) { + public void onUidRemovedFromPendingTempAllowlist(int uid) { synchronized (mGlobalLockWithoutBoost) { - mPendingTempWhitelist.remove(uid); + mPendingTempAllowlist.remove(uid); } } diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java index 892ee717e21f..c36dede013f4 100644 --- a/services/core/java/com/android/server/wm/LockTaskController.java +++ b/services/core/java/com/android/server/wm/LockTaskController.java @@ -33,11 +33,11 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTAS import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.wm.Task.LOCK_TASK_AUTH_ALLOWLISTED; import static com.android.server.wm.Task.LOCK_TASK_AUTH_DONT_LOCK; import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE; import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; import static com.android.server.wm.Task.LOCK_TASK_AUTH_PINNABLE; -import static com.android.server.wm.Task.LOCK_TASK_AUTH_WHITELISTED; import android.annotation.NonNull; import android.annotation.Nullable; @@ -264,12 +264,12 @@ public class LockTaskController { } /** - * @return whether the requested task is allowed to be locked (either whitelisted, or declares + * @return whether the requested task is allowed to be locked (either allowlisted, or declares * lockTaskMode="always" in the manifest). */ - boolean isTaskWhitelisted(Task task) { + boolean isTaskAllowlisted(Task task) { switch(task.mLockTaskAuth) { - case LOCK_TASK_AUTH_WHITELISTED: + case LOCK_TASK_AUTH_ALLOWLISTED: case LOCK_TASK_AUTH_LAUNCHABLE: case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return true; @@ -311,7 +311,7 @@ public class LockTaskController { private boolean isLockTaskModeViolationInternal(Task task, boolean isNewClearTask) { // TODO: Double check what's going on here. If the task is already in lock task mode, it's - // likely whitelisted, so will return false below. + // likely allowlisted, so will return false below. if (isTaskLocked(task) && !isNewClearTask) { // If the task is already at the top and won't be cleared, then allow the operation return false; @@ -327,7 +327,7 @@ public class LockTaskController { return false; } - return !(isTaskWhitelisted(task) || mLockTaskModeTasks.isEmpty()); + return !(isTaskAllowlisted(task) || mLockTaskModeTasks.isEmpty()); } private boolean isRecentsAllowed(int userId) { @@ -356,7 +356,7 @@ public class LockTaskController { return false; default: } - return isPackageWhitelisted(userId, packageName); + return isPackageAllowlisted(userId, packageName); } private boolean isEmergencyCallTask(Task task) { @@ -556,7 +556,7 @@ public class LockTaskController { if (!isSystemCaller) { task.mLockTaskUid = callingUid; if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) { - // startLockTask() called by app, but app is not part of lock task whitelist. Show + // startLockTask() called by app, but app is not part of lock task allowlist. Show // app pinning request. We will come back here with isSystemCaller true. if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user"); StatusBarManagerInternal statusBarManager = LocalServices.getService( @@ -649,8 +649,8 @@ public class LockTaskController { /** * Update packages that are allowed to be launched in lock task mode. - * @param userId Which user this whitelist is associated with - * @param packages The whitelist of packages allowed in lock task mode + * @param userId Which user this allowlist is associated with + * @param packages The allowlist of packages allowed in lock task mode * @see #mLockTaskPackages */ void updateLockTaskPackages(int userId, String[] packages) { @@ -659,19 +659,19 @@ public class LockTaskController { boolean taskChanged = false; for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { final Task lockedTask = mLockTaskModeTasks.get(taskNdx); - final boolean wasWhitelisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE - || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED; + final boolean wasAllowlisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE + || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_ALLOWLISTED; lockedTask.setLockTaskAuth(); - final boolean isWhitelisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE - || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED; + final boolean isAllowlisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE + || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_ALLOWLISTED; if (mLockTaskModeState != LOCK_TASK_MODE_LOCKED || lockedTask.mUserId != userId - || !wasWhitelisted || isWhitelisted) { + || !wasAllowlisted || isAllowlisted) { continue; } - // Terminate locked tasks that have recently lost whitelist authorization. + // Terminate locked tasks that have recently lost allowlist authorization. if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " + lockedTask + " mLockTaskAuth()=" + lockedTask.lockTaskAuthToString()); removeLockedTask(lockedTask); @@ -697,17 +697,17 @@ public class LockTaskController { } } - boolean isPackageWhitelisted(int userId, String pkg) { + boolean isPackageAllowlisted(int userId, String pkg) { if (pkg == null) { return false; } - String[] whitelist; - whitelist = mLockTaskPackages.get(userId); - if (whitelist == null) { + String[] allowlist; + allowlist = mLockTaskPackages.get(userId); + if (allowlist == null) { return false; } - for (String whitelistedPkg : whitelist) { - if (pkg.equals(whitelistedPkg)) { + for (String allowlistedPkg : allowlist) { + if (pkg.equals(allowlistedPkg)) { return true; } } diff --git a/services/core/java/com/android/server/wm/PolicyControl.java b/services/core/java/com/android/server/wm/PolicyControl.java index 0f92bc83a666..61b6e0b25961 100644 --- a/services/core/java/com/android/server/wm/PolicyControl.java +++ b/services/core/java/com/android/server/wm/PolicyControl.java @@ -196,40 +196,40 @@ class PolicyControl { private static final String ALL = "*"; private static final String APPS = "apps"; - private final ArraySet mWhitelist; - private final ArraySet mBlacklist; + private final ArraySet mAllowlist; + private final ArraySet mDenylist; - private Filter(ArraySet whitelist, ArraySet blacklist) { - mWhitelist = whitelist; - mBlacklist = blacklist; + private Filter(ArraySet allowlist, ArraySet denylist) { + mAllowlist = allowlist; + mDenylist = denylist; } boolean matches(LayoutParams attrs) { if (attrs == null) return false; boolean isApp = attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW && attrs.type <= WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; - if (isApp && mBlacklist.contains(APPS)) return false; - if (onBlacklist(attrs.packageName)) return false; - if (isApp && mWhitelist.contains(APPS)) return true; - return onWhitelist(attrs.packageName); + if (isApp && mDenylist.contains(APPS)) return false; + if (onDenylist(attrs.packageName)) return false; + if (isApp && mAllowlist.contains(APPS)) return true; + return onAllowlist(attrs.packageName); } boolean matches(String packageName) { - return !onBlacklist(packageName) && onWhitelist(packageName); + return !onDenylist(packageName) && onAllowlist(packageName); } - private boolean onBlacklist(String packageName) { - return mBlacklist.contains(packageName) || mBlacklist.contains(ALL); + private boolean onDenylist(String packageName) { + return mDenylist.contains(packageName) || mDenylist.contains(ALL); } - private boolean onWhitelist(String packageName) { - return mWhitelist.contains(ALL) || mWhitelist.contains(packageName); + private boolean onAllowlist(String packageName) { + return mAllowlist.contains(ALL) || mAllowlist.contains(packageName); } void dump(PrintWriter pw) { pw.print("Filter["); - dump("whitelist", mWhitelist, pw); pw.print(','); - dump("blacklist", mBlacklist, pw); pw.print(']'); + dump("allowlist", mAllowlist, pw); pw.print(','); + dump("denylist", mDenylist, pw); pw.print(']'); } private void dump(String name, ArraySet set, PrintWriter pw) { @@ -253,18 +253,18 @@ class PolicyControl { // e.g. "com.package1", or "apps, com.android.keyguard" or "*" static Filter parse(String value) { if (value == null) return null; - ArraySet whitelist = new ArraySet(); - ArraySet blacklist = new ArraySet(); + ArraySet allowlist = new ArraySet(); + ArraySet denylist = new ArraySet(); for (String token : value.split(",")) { token = token.trim(); if (token.startsWith("-") && token.length() > 1) { token = token.substring(1); - blacklist.add(token); + denylist.add(token); } else { - whitelist.add(token); + allowlist.add(token); } } - return new Filter(whitelist, blacklist); + return new Filter(allowlist, denylist); } } } diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index 851b533a550d..3fe75a4ab49e 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -655,7 +655,8 @@ class RecentTasks { } for (int i = mTasks.size() - 1; i >= 0; --i) { final Task task = mTasks.get(i); - if (task.mUserId == userId && !mService.getLockTaskController().isTaskWhitelisted(task)) { + if (task.mUserId == userId + && !mService.getLockTaskController().isTaskAllowlisted(task)) { remove(task); } } diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 049e46fb6cef..ab2231b186ae 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2590,7 +2590,7 @@ class RootWindowContainer extends WindowContainer mDisplayAccessUIDs.clear(); for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { final DisplayContent displayContent = getChildAt(displayNdx); - // Only bother calculating the whitelist for private displays + // Only bother calculating the allowlist for private displays if (displayContent.isPrivate()) { mDisplayAccessUIDs.append( displayContent.mDisplayId, displayContent.getPresentUIDs()); diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java index b71ecbb8a72d..ede6708d5f8f 100644 --- a/services/core/java/com/android/server/wm/SafeActivityOptions.java +++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java @@ -233,10 +233,10 @@ public class SafeActivityOptions { Slog.w(TAG, msg); throw new SecurityException(msg); } - // Check if someone tries to launch an unwhitelisted activity into LockTask mode. + // Check if someone tries to launch an unallowlisted activity into LockTask mode. final boolean lockTaskMode = options.getLockTaskMode(); if (aInfo != null && lockTaskMode - && !supervisor.mService.getLockTaskController().isPackageWhitelisted( + && !supervisor.mService.getLockTaskController().isPackageAllowlisted( UserHandle.getUserId(callingUid), aInfo.packageName)) { final String msg = "Permission Denial: starting " + getIntentString(intent) + " from " + callerApp + " (pid=" + callingPid diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 954b7a026bf5..3a750f2c9da3 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -40,7 +40,7 @@ import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT; -import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; +import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER; import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY; import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY; @@ -264,7 +264,7 @@ class Task extends WindowContainer { /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */ final static int LOCK_TASK_AUTH_LAUNCHABLE = 2; /** Can enter lockTask without user approval. Can start over existing lockTask task. */ - final static int LOCK_TASK_AUTH_WHITELISTED = 3; + final static int LOCK_TASK_AUTH_ALLOWLISTED = 3; /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing * lockTask task. */ final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4; @@ -1377,7 +1377,7 @@ class Task extends WindowContainer { getDisplayArea().addStackReferenceIfNeeded((ActivityStack) child); } - // Make sure the list of display UID whitelists is updated + // Make sure the list of display UID allowlists is updated // now that this record is in a new task. mRootWindowContainer.updateUIDsPresentOnDisplay(); @@ -1605,7 +1605,7 @@ class Task extends WindowContainer { case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK"; case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE"; case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE"; - case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED"; + case LOCK_TASK_AUTH_ALLOWLISTED: return "LOCK_TASK_AUTH_ALLOWLISTED"; case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV"; default: return "unknown=" + mLockTaskAuth; } @@ -1625,8 +1625,8 @@ class Task extends WindowContainer { final LockTaskController lockTaskController = mAtmService.getLockTaskController(); switch (r.lockTaskLaunchMode) { case LOCK_TASK_LAUNCH_MODE_DEFAULT: - mLockTaskAuth = lockTaskController.isPackageWhitelisted(mUserId, pkg) - ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE; + mLockTaskAuth = lockTaskController.isPackageAllowlisted(mUserId, pkg) + ? LOCK_TASK_AUTH_ALLOWLISTED : LOCK_TASK_AUTH_PINNABLE; break; case LOCK_TASK_LAUNCH_MODE_NEVER: @@ -1637,8 +1637,8 @@ class Task extends WindowContainer { mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV; break; - case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED: - mLockTaskAuth = lockTaskController.isPackageWhitelisted(mUserId, pkg) + case LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED: + mLockTaskAuth = lockTaskController.isPackageAllowlisted(mUserId, pkg) ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE; break; } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 1ef0acd20835..02a3bb1f5632 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -22,7 +22,7 @@ import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT; -import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; +import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; @@ -1694,7 +1694,7 @@ public class ActivityRecordTests extends ActivityTestsBase { public void testGetLockTaskLaunchMode() { final ActivityOptions options = ActivityOptions.makeBasic().setLockTaskEnabled(true); mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT; - assertEquals(LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED, + assertEquals(LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED, ActivityRecord.getLockTaskLaunchMode(mActivity.info, options)); mActivity.info.lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_ALWAYS; diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java index a137cde2d351..e345becf0499 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java @@ -168,8 +168,8 @@ public class LockTaskControllerTest { @Test public void testStartLockTaskMode_once() throws Exception { - // GIVEN a task record with whitelisted auth - Task tr = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + // GIVEN a task record with allowlisted auth + Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); // WHEN calling setLockTaskMode for LOCKED mode without resuming mLockTaskController.startLockTaskMode(tr, false, TEST_UID); @@ -185,9 +185,9 @@ public class LockTaskControllerTest { @Test public void testStartLockTaskMode_twice() throws Exception { - // GIVEN two task records with whitelisted auth - Task tr1 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); - Task tr2 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + // GIVEN two task records with allowlisted auth + Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); + Task tr2 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); // WHEN calling setLockTaskMode for LOCKED mode on both tasks mLockTaskController.startLockTaskMode(tr1, false, TEST_UID); @@ -205,7 +205,7 @@ public class LockTaskControllerTest { @Test public void testStartLockTaskMode_pinningRequest() { - // GIVEN a task record that is not whitelisted, i.e. with pinned auth + // GIVEN a task record that is not allowlisted, i.e. with pinned auth Task tr = getTask(Task.LOCK_TASK_AUTH_PINNABLE); // WHEN calling startLockTaskMode @@ -236,23 +236,23 @@ public class LockTaskControllerTest { @Test public void testLockTaskViolation() { - // GIVEN one task record with whitelisted auth that is in lock task mode - Task tr = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + // GIVEN one task record with allowlisted auth that is in lock task mode + Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); // THEN it's not a lock task violation to try and launch this task without clearing assertFalse(mLockTaskController.isLockTaskModeViolation(tr, false)); - // THEN it's a lock task violation to launch another task that is not whitelisted + // THEN it's a lock task violation to launch another task that is not allowlisted assertTrue(mLockTaskController.isLockTaskModeViolation(getTask( Task.LOCK_TASK_AUTH_PINNABLE))); // THEN it's a lock task violation to launch another task that is disallowed from lock task assertTrue(mLockTaskController.isLockTaskModeViolation(getTask( Task.LOCK_TASK_AUTH_DONT_LOCK))); - // THEN it's no a lock task violation to launch another task that is whitelisted + // THEN it's no a lock task violation to launch another task that is allowlisted assertFalse(mLockTaskController.isLockTaskModeViolation(getTask( - Task.LOCK_TASK_AUTH_WHITELISTED))); + Task.LOCK_TASK_AUTH_ALLOWLISTED))); assertFalse(mLockTaskController.isLockTaskModeViolation(getTask( Task.LOCK_TASK_AUTH_LAUNCHABLE))); // THEN it's not a lock task violation to launch another task that is priv launchable @@ -262,8 +262,8 @@ public class LockTaskControllerTest { @Test public void testLockTaskViolation_emergencyCall() { - // GIVEN one task record with whitelisted auth that is in lock task mode - Task tr = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + // GIVEN one task record with allowlisted auth that is in lock task mode + Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); // GIVEN tasks necessary for emergency calling @@ -294,8 +294,8 @@ public class LockTaskControllerTest { @Test public void testStopLockTaskMode() throws Exception { - // GIVEN one task record with whitelisted auth that is in lock task mode - Task tr = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + // GIVEN one task record with allowlisted auth that is in lock task mode + Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); // WHEN the same caller calls stopLockTaskMode @@ -311,8 +311,8 @@ public class LockTaskControllerTest { @Test(expected = SecurityException.class) public void testStopLockTaskMode_differentCaller() { - // GIVEN one task record with whitelisted auth that is in lock task mode - Task tr = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + // GIVEN one task record with allowlisted auth that is in lock task mode + Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); // WHEN a different caller calls stopLockTaskMode @@ -323,8 +323,8 @@ public class LockTaskControllerTest { @Test public void testStopLockTaskMode_systemCaller() { - // GIVEN one task record with whitelisted auth that is in lock task mode - Task tr = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + // GIVEN one task record with allowlisted auth that is in lock task mode + Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); // WHEN system calls stopLockTaskMode @@ -336,9 +336,9 @@ public class LockTaskControllerTest { @Test public void testStopLockTaskMode_twoTasks() throws Exception { - // GIVEN two task records with whitelisted auth that is in lock task mode - Task tr1 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); - Task tr2 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + // GIVEN two task records with allowlisted auth that is in lock task mode + Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); + Task tr2 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr1, false, TEST_UID); mLockTaskController.startLockTaskMode(tr2, false, TEST_UID); @@ -357,9 +357,9 @@ public class LockTaskControllerTest { @Test public void testStopLockTaskMode_rootTask() throws Exception { - // GIVEN two task records with whitelisted auth that is in lock task mode - Task tr1 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); - Task tr2 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + // GIVEN two task records with allowlisted auth that is in lock task mode + Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); + Task tr2 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr1, false, TEST_UID); mLockTaskController.startLockTaskMode(tr2, false, TEST_UID); @@ -405,9 +405,9 @@ public class LockTaskControllerTest { @Test public void testClearLockedTasks() throws Exception { - // GIVEN two task records with whitelisted auth that is in lock task mode - Task tr1 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); - Task tr2 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + // GIVEN two task records with allowlisted auth that is in lock task mode + Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); + Task tr2 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr1, false, TEST_UID); mLockTaskController.startLockTaskMode(tr2, false, TEST_UID); @@ -434,7 +434,7 @@ public class LockTaskControllerTest { .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); // AND there is a task record - Task tr1 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr1, true, TEST_UID); // WHEN calling clearLockedTasks on the root task @@ -454,7 +454,7 @@ public class LockTaskControllerTest { .thenReturn(true); // AND there is a task record - Task tr1 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr1, true, TEST_UID); // WHEN calling clearLockedTasks on the root task @@ -471,7 +471,7 @@ public class LockTaskControllerTest { Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, 1, mContext.getUserId()); // AND there is a task record - Task tr1 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr1, true, TEST_UID); // WHEN calling clearLockedTasks on the root task @@ -488,7 +488,7 @@ public class LockTaskControllerTest { Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, 0, mContext.getUserId()); // AND there is a task record - Task tr1 = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + Task tr1 = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr1, true, TEST_UID); // WHEN calling clearLockedTasks on the root task @@ -500,45 +500,45 @@ public class LockTaskControllerTest { @Test public void testUpdateLockTaskPackages() { - String[] whitelist1 = {TEST_PACKAGE_NAME, TEST_PACKAGE_NAME_2}; - String[] whitelist2 = {TEST_PACKAGE_NAME}; - - // No package is whitelisted initially - for (String pkg : whitelist1) { - assertFalse("Package shouldn't be whitelisted: " + pkg, - mLockTaskController.isPackageWhitelisted(TEST_USER_ID, pkg)); - assertFalse("Package shouldn't be whitelisted for user 0: " + pkg, - mLockTaskController.isPackageWhitelisted(0, pkg)); + String[] allowlist1 = {TEST_PACKAGE_NAME, TEST_PACKAGE_NAME_2}; + String[] allowlist2 = {TEST_PACKAGE_NAME}; + + // No package is allowlisted initially + for (String pkg : allowlist1) { + assertFalse("Package shouldn't be allowlisted: " + pkg, + mLockTaskController.isPackageAllowlisted(TEST_USER_ID, pkg)); + assertFalse("Package shouldn't be allowlisted for user 0: " + pkg, + mLockTaskController.isPackageAllowlisted(0, pkg)); } - // Apply whitelist - mLockTaskController.updateLockTaskPackages(TEST_USER_ID, whitelist1); + // Apply allowlist + mLockTaskController.updateLockTaskPackages(TEST_USER_ID, allowlist1); - // Assert the whitelist is applied to the correct user - for (String pkg : whitelist1) { - assertTrue("Package should be whitelisted: " + pkg, - mLockTaskController.isPackageWhitelisted(TEST_USER_ID, pkg)); - assertFalse("Package shouldn't be whitelisted for user 0: " + pkg, - mLockTaskController.isPackageWhitelisted(0, pkg)); + // Assert the allowlist is applied to the correct user + for (String pkg : allowlist1) { + assertTrue("Package should be allowlisted: " + pkg, + mLockTaskController.isPackageAllowlisted(TEST_USER_ID, pkg)); + assertFalse("Package shouldn't be allowlisted for user 0: " + pkg, + mLockTaskController.isPackageAllowlisted(0, pkg)); } - // Update whitelist - mLockTaskController.updateLockTaskPackages(TEST_USER_ID, whitelist2); + // Update allowlist + mLockTaskController.updateLockTaskPackages(TEST_USER_ID, allowlist2); - // Assert the new whitelist is applied - assertTrue("Package should remain whitelisted: " + TEST_PACKAGE_NAME, - mLockTaskController.isPackageWhitelisted(TEST_USER_ID, TEST_PACKAGE_NAME)); - assertFalse("Package should no longer be whitelisted: " + TEST_PACKAGE_NAME_2, - mLockTaskController.isPackageWhitelisted(TEST_USER_ID, TEST_PACKAGE_NAME_2)); + // Assert the new allowlist is applied + assertTrue("Package should remain allowlisted: " + TEST_PACKAGE_NAME, + mLockTaskController.isPackageAllowlisted(TEST_USER_ID, TEST_PACKAGE_NAME)); + assertFalse("Package should no longer be allowlisted: " + TEST_PACKAGE_NAME_2, + mLockTaskController.isPackageAllowlisted(TEST_USER_ID, TEST_PACKAGE_NAME_2)); } @Test public void testUpdateLockTaskPackages_taskRemoved() throws Exception { - // GIVEN two tasks which are whitelisted initially + // GIVEN two tasks which are allowlisted initially Task tr1 = getTaskForUpdate(TEST_PACKAGE_NAME, true); Task tr2 = getTaskForUpdate(TEST_PACKAGE_NAME_2, false); - String[] whitelist = {TEST_PACKAGE_NAME, TEST_PACKAGE_NAME_2}; - mLockTaskController.updateLockTaskPackages(TEST_USER_ID, whitelist); + String[] allowlist = {TEST_PACKAGE_NAME, TEST_PACKAGE_NAME_2}; + mLockTaskController.updateLockTaskPackages(TEST_USER_ID, allowlist); // GIVEN the tasks are launched into LockTask mode mLockTaskController.startLockTaskMode(tr1, false, TEST_UID); @@ -548,9 +548,9 @@ public class LockTaskControllerTest { assertTrue(mLockTaskController.isTaskLocked(tr2)); verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK); - // WHEN removing one package from whitelist - whitelist = new String[] {TEST_PACKAGE_NAME}; - mLockTaskController.updateLockTaskPackages(TEST_USER_ID, whitelist); + // WHEN removing one package from allowlist + allowlist = new String[] {TEST_PACKAGE_NAME}; + mLockTaskController.updateLockTaskPackages(TEST_USER_ID, allowlist); // THEN the task running that package should be stopped verify(tr2).performClearTaskLocked(); @@ -560,9 +560,9 @@ public class LockTaskControllerTest { assertTrue(mLockTaskController.isTaskLocked(tr1)); verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK); - // WHEN removing the last package from whitelist - whitelist = new String[] {}; - mLockTaskController.updateLockTaskPackages(TEST_USER_ID, whitelist); + // WHEN removing the last package from allowlist + allowlist = new String[] {}; + mLockTaskController.updateLockTaskPackages(TEST_USER_ID, allowlist); // THEN the last task should be cleared, and the system should quit LockTask mode verify(tr1).performClearTaskLocked(); @@ -574,7 +574,7 @@ public class LockTaskControllerTest { @Test public void testUpdateLockTaskFeatures() throws Exception { // GIVEN a locked task - Task tr = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); // THEN lock task mode should be started with default status bar masks @@ -616,7 +616,7 @@ public class LockTaskControllerTest { @Test public void testUpdateLockTaskFeatures_differentUser() throws Exception { // GIVEN a locked task - Task tr = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); // THEN lock task mode should be started with default status bar masks @@ -638,7 +638,7 @@ public class LockTaskControllerTest { @Test public void testUpdateLockTaskFeatures_keyguard() { // GIVEN a locked task - Task tr = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); // THEN keyguard should be disabled @@ -704,7 +704,7 @@ public class LockTaskControllerTest { TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT)); // Start lock task mode - Task tr = getTask(Task.LOCK_TASK_AUTH_WHITELISTED); + Task tr = getTask(Task.LOCK_TASK_AUTH_ALLOWLISTED); mLockTaskController.startLockTaskMode(tr, false, TEST_UID); // WHEN LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK is not enabled @@ -719,15 +719,15 @@ public class LockTaskControllerTest { assertTrue(mLockTaskController.isActivityAllowed( TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_ALWAYS)); - // unwhitelisted package should not be allowed + // unallowlisted package should not be allowed assertFalse(mLockTaskController.isActivityAllowed( TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT)); - // update the whitelist - String[] whitelist = new String[] { TEST_PACKAGE_NAME }; - mLockTaskController.updateLockTaskPackages(TEST_USER_ID, whitelist); + // update the allowlist + String[] allowlist = new String[] { TEST_PACKAGE_NAME }; + mLockTaskController.updateLockTaskPackages(TEST_USER_ID, allowlist); - // whitelisted package should be allowed + // allowlisted package should be allowed assertTrue(mLockTaskController.isActivityAllowed( TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT)); @@ -755,17 +755,17 @@ public class LockTaskControllerTest { } /** - * @param isAppAware {@code true} if the app has marked if_whitelisted in its manifest + * @param isAppAware {@code true} if the app has marked if_allowlisted in its manifest */ private Task getTaskForUpdate(String pkg, boolean isAppAware) { - final int authIfWhitelisted = isAppAware + final int authIfAllowlisted = isAppAware ? Task.LOCK_TASK_AUTH_LAUNCHABLE - : Task.LOCK_TASK_AUTH_WHITELISTED; - Task tr = getTask(pkg, authIfWhitelisted); + : Task.LOCK_TASK_AUTH_ALLOWLISTED; + Task tr = getTask(pkg, authIfAllowlisted); doAnswer((invocation) -> { - boolean isWhitelisted = - mLockTaskController.isPackageWhitelisted(TEST_USER_ID, pkg); - tr.mLockTaskAuth = isWhitelisted ? authIfWhitelisted : Task.LOCK_TASK_AUTH_PINNABLE; + boolean isAllowlisted = + mLockTaskController.isPackageAllowlisted(TEST_USER_ID, pkg); + tr.mLockTaskAuth = isAllowlisted ? authIfAllowlisted : Task.LOCK_TASK_AUTH_PINNABLE; return null; }).when(tr).setLockTaskAuth(); return tr; -- GitLab From e3488605b81ed12feefa5ab9b3bf95f6bff7e8fe Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Fri, 14 Aug 2020 01:11:25 +0800 Subject: [PATCH 403/536] Fix showing keyboard without editor focused in some cases (1/2) Starts from CL[1] that reporting focus change is now driven by input instead window manager, so the window focus sequence for the activity with EditTextPreference dialog after device unlock in between android Q and android R will be: [Android Q]: activity main window (with softInputMode STATE_UNSPECIFIED) -> EditTextPreference (with softInputMode STATE_ALWAYS_VISIBLE) [Android R]: Only EditTextPreference focused after device unlocked since the window is the last touched window. Since in Q, the softInputMode of activity main window is STATE_UNSPECIFIED , so by default InputMethodManagerService will hide soft-keyboard if there is no editor focused according this softInputMode flag. However, in R, because no main window focused, so after EditTextPerference focused and started the input connection, this will hit a logic to show soft-keyboard, if mShowRequested is true after the input session created. Since IMMS#mShowRequested originally is used to show soft-input while showSoftInput is called but IME service has been unbounded (e.g. switch IME or IME service killed), so use this flag can show soft-input aftter service re-connected. For the issue case, we should ignore STATE_ALWAYS_VISIBLE since the app's targetSdkVersion is P+ and no editor focus as CL[2] expectation. To fix that, we introduced new SoftInputShowHideReason to hide soft-input when the same window focused without valid editor focus after screen unlock, in order to align with the behavior prior to R. [1]: Iff0b88a05441b29834741aa3dfae31d55871ddd6 [2]: I56682c7dee71d461687b9e80ab746d382fd55e0c Bug: 161506356 Fix: 162444230 Test: atest CtsInputMethodTestCases Merged-In: I37ae6e30d1de581ba15131c2a90396b3a522a4d6 Change-Id: I37ae6e30d1de581ba15131c2a90396b3a522a4d6 (cherry picked from commit 1ef07dffe372e853873a4425345a9e532d520732) --- .../inputmethod/InputMethodDebug.java | 2 + .../inputmethod/SoftInputShowHideReason.java | 16 ++++++- .../InputMethodManagerService.java | 44 ++++++++++++++----- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/core/java/com/android/internal/inputmethod/InputMethodDebug.java b/core/java/com/android/internal/inputmethod/InputMethodDebug.java index 37f68233db53..3bcba75ec163 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodDebug.java +++ b/core/java/com/android/internal/inputmethod/InputMethodDebug.java @@ -224,6 +224,8 @@ public final class InputMethodDebug { return "HIDE_DOCKED_STACK_ATTACHED"; case SoftInputShowHideReason.HIDE_RECENTS_ANIMATION: return "HIDE_RECENTS_ANIMATION"; + case SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR: + return "HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR"; default: return "Unknown=" + reason; } diff --git a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java index 4b968b45f122..f46626be48a8 100644 --- a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java +++ b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java @@ -47,7 +47,8 @@ import java.lang.annotation.Retention; SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME, SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED, SoftInputShowHideReason.HIDE_RECENTS_ANIMATION, - SoftInputShowHideReason.HIDE_BUBBLES}) + SoftInputShowHideReason.HIDE_BUBBLES, + SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR}) public @interface SoftInputShowHideReason { /** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */ int SHOW_SOFT_INPUT = 0; @@ -147,4 +148,17 @@ public @interface SoftInputShowHideReason { * switching, or collapsing Bubbles. */ int HIDE_BUBBLES = 19; + + /** + * Hide soft input when focusing the same window (e.g. screen turned-off and turn-on) which no + * valid focused editor. + * + * Note: From Android R, the window focus change callback is processed by InputDispatcher, + * some focus behavior changes (e.g. There are an activity with a dialog window, after + * screen turned-off and turned-on, before Android R the window focus sequence would be + * the activity first and then the dialog focused, however, in R the focus sequence would be + * only the dialog focused as it's the latest window with input focus) makes we need to hide + * soft-input when the same window focused again to align with the same behavior prior to R. + */ + int HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR = 20; } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 254285dfbd41..588b7af5b902 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -71,6 +71,7 @@ import android.inputmethodservice.InputMethodService; import android.media.AudioManagerInternal; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.Handler; @@ -3273,6 +3274,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub boolean hideCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { + if (mCurClient == null || mCurClient.curSession == null) { + return false; + } if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0 && (mShowExplicitlyRequested || mShowForced)) { if (DEBUG) Slog.v(TAG, "Not hiding: explicit show not cancelled by non-explicit hide"); @@ -3457,7 +3461,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // pre-rendering not supported on low-ram devices. cs.shouldPreRenderIme = DebugFlags.FLAG_PRE_RENDER_IME_VIEWS.value() && !mIsLowRam; - if (mCurFocusedWindow == windowToken) { + final boolean sameWindowFocused = mCurFocusedWindow == windowToken; + final boolean isTextEditor = (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0; + if (sameWindowFocused && isTextEditor) { if (DEBUG) { Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client + " attribute=" + attribute + ", token = " + windowToken @@ -3472,6 +3478,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY, null, null, null, -1, null); } + mCurFocusedWindow = windowToken; mCurFocusedWindowSoftInputMode = softInputMode; mCurFocusedWindowClient = cs; @@ -3489,7 +3496,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub == LayoutParams.SOFT_INPUT_ADJUST_RESIZE || mRes.getConfiguration().isLayoutSizeAtLeast( Configuration.SCREENLAYOUT_SIZE_LARGE); - final boolean isTextEditor = (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0; // We want to start input before showing the IME, but after closing // it. We want to do this after closing it to help the IME disappear @@ -3549,9 +3555,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } break; case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: - if (DEBUG) Slog.v(TAG, "Window asks to hide input"); - hideCurrentInputLocked(mCurFocusedWindow, 0, null, - SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE); + if (!sameWindowFocused) { + if (DEBUG) Slog.v(TAG, "Window asks to hide input"); + hideCurrentInputLocked(mCurFocusedWindow, 0, null, + SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE); + } break; case LayoutParams.SOFT_INPUT_STATE_VISIBLE: if ((softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) { @@ -3576,13 +3584,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (DEBUG) Slog.v(TAG, "Window asks to always show input"); if (InputMethodUtils.isSoftInputModeStateVisibleAllowed( unverifiedTargetSdkVersion, startInputFlags)) { - if (attribute != null) { - res = startInputUncheckedLocked(cs, inputContext, missingMethods, - attribute, startInputFlags, startInputReason); - didStart = true; + if (!sameWindowFocused) { + if (attribute != null) { + res = startInputUncheckedLocked(cs, inputContext, missingMethods, + attribute, startInputFlags, startInputReason); + didStart = true; + } + showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null, + SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE); } - showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null, - SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE); } else { Slog.e(TAG, "SOFT_INPUT_STATE_ALWAYS_VISIBLE is ignored because" + " there is no focused view that also returns true from" @@ -3593,7 +3603,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (!didStart) { if (attribute != null) { - if (!DebugFlags.FLAG_OPTIMIZE_START_INPUT.value() + if (sameWindowFocused) { + hideCurrentInputLocked(mCurFocusedWindow, 0, null, + SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR); + res = new InputBindResult( + InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY, + null, null, null, -1, null); + } else if (!DebugFlags.FLAG_OPTIMIZE_START_INPUT.value() || (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0) { res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, startInputFlags, startInputReason); @@ -3607,6 +3623,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return res; } + private boolean isImeVisible() { + return (mImeWindowVis & InputMethodService.IME_VISIBLE) != 0; + } + private boolean canShowInputMethodPickerLocked(IInputMethodClient client) { // TODO(yukawa): multi-display support. final int uid = Binder.getCallingUid(); -- GitLab From 6e9cabd95e21fbcb37a1cbc1666eafb09b111caa Mon Sep 17 00:00:00 2001 From: jiabin Date: Fri, 21 Aug 2020 18:07:27 -0700 Subject: [PATCH 404/536] Add package name when creating AudioTrack. The package name will be used when starting external vibration. The package name will be sent to vibrator service to check if the application has the permission to start vibration, Bug: 165910728 Bug: 162343845 Test: atest AudioTrackTest MediaPlayerTest Test: start audio-coupled-haptic playback Change-Id: I04b4711d11ab5f0f0716ea4c5e1c0f754fe834bb Merged-In: I04b4711d11ab5f0f0716ea4c5e1c0f754fe834bb --- core/jni/android_media_AudioTrack.cpp | 76 ++++++++++++----------- media/java/android/media/AudioTrack.java | 9 ++- media/java/android/media/MediaPlayer.java | 5 +- media/java/android/media/PlayerBase.java | 5 ++ media/jni/android_media_MediaPlayer.cpp | 9 ++- 5 files changed, 60 insertions(+), 44 deletions(-) diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index 5c045b65be22..7a5c38385f32 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -20,6 +20,7 @@ #include "android_media_AudioTrack.h" #include +#include #include "core_jni_helpers.h" #include @@ -251,7 +252,7 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession, jlong nativeAudioTrack, jboolean offload, jint encapsulationMode, - jobject tunerConfiguration) { + jobject tunerConfiguration, jstring opPackageName) { ALOGV("sampleRates=%p, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d," " nativeAudioTrack=0x%" PRIX64 ", offload=%d encapsulationMode=%d tuner=%p", jSampleRate, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes, @@ -337,7 +338,8 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we } // create the native AudioTrack object - lpTrack = new AudioTrack(); + ScopedUtfChars opPackageNameStr(env, opPackageName); + lpTrack = new AudioTrack(opPackageNameStr.c_str()); // read the AudioAttributes values auto paa = JNIAudioAttributeHelper::makeUnique(); @@ -371,23 +373,24 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we status_t status = NO_ERROR; switch (memoryMode) { case MODE_STREAM: - status = lpTrack->set( - AUDIO_STREAM_DEFAULT,// stream type, but more info conveyed in paa (last argument) - sampleRateInHertz, - format,// word length, PCM - nativeChannelMask, - offload ? 0 : frameCount, - offload ? AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD : AUDIO_OUTPUT_FLAG_NONE, - audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user) - 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack - 0,// shared mem - true,// thread can call Java - sessionId,// audio session ID - offload ? AudioTrack::TRANSFER_SYNC_NOTIF_CALLBACK : AudioTrack::TRANSFER_SYNC, - offload ? &offloadInfo : NULL, - -1, -1, // default uid, pid values - paa.get()); - + status = lpTrack->set(AUDIO_STREAM_DEFAULT, // stream type, but more info conveyed + // in paa (last argument) + sampleRateInHertz, + format, // word length, PCM + nativeChannelMask, offload ? 0 : frameCount, + offload ? AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD + : AUDIO_OUTPUT_FLAG_NONE, + audioCallback, + &(lpJniStorage->mCallbackData), // callback, callback data (user) + 0, // notificationFrames == 0 since not using EVENT_MORE_DATA + // to feed the AudioTrack + 0, // shared mem + true, // thread can call Java + sessionId, // audio session ID + offload ? AudioTrack::TRANSFER_SYNC_NOTIF_CALLBACK + : AudioTrack::TRANSFER_SYNC, + offload ? &offloadInfo : NULL, -1, -1, // default uid, pid values + paa.get()); break; case MODE_STATIC: @@ -398,22 +401,22 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we goto native_init_failure; } - status = lpTrack->set( - AUDIO_STREAM_DEFAULT,// stream type, but more info conveyed in paa (last argument) - sampleRateInHertz, - format,// word length, PCM - nativeChannelMask, - frameCount, - AUDIO_OUTPUT_FLAG_NONE, - audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)); - 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack - lpJniStorage->mMemBase,// shared mem - true,// thread can call Java - sessionId,// audio session ID - AudioTrack::TRANSFER_SHARED, - NULL, // default offloadInfo - -1, -1, // default uid, pid values - paa.get()); + status = lpTrack->set(AUDIO_STREAM_DEFAULT, // stream type, but more info conveyed + // in paa (last argument) + sampleRateInHertz, + format, // word length, PCM + nativeChannelMask, frameCount, AUDIO_OUTPUT_FLAG_NONE, + audioCallback, + &(lpJniStorage->mCallbackData), // callback, callback data (user) + 0, // notificationFrames == 0 since not using EVENT_MORE_DATA + // to feed the AudioTrack + lpJniStorage->mMemBase, // shared mem + true, // thread can call Java + sessionId, // audio session ID + AudioTrack::TRANSFER_SHARED, + NULL, // default offloadInfo + -1, -1, // default uid, pid values + paa.get()); break; default: @@ -1428,7 +1431,8 @@ static const JNINativeMethod gMethods[] = { {"native_stop", "()V", (void *)android_media_AudioTrack_stop}, {"native_pause", "()V", (void *)android_media_AudioTrack_pause}, {"native_flush", "()V", (void *)android_media_AudioTrack_flush}, - {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIIII[IJZILjava/lang/Object;)I", + {"native_setup", + "(Ljava/lang/Object;Ljava/lang/Object;[IIIIII[IJZILjava/lang/Object;Ljava/lang/String;)I", (void *)android_media_AudioTrack_setup}, {"native_finalize", "()V", (void *)android_media_AudioTrack_finalize}, {"native_release", "()V", (void *)android_media_AudioTrack_release}, diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 1c0a526f536c..de2a7b2c15e3 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -807,7 +807,8 @@ public class AudioTrack extends PlayerBase int initResult = native_setup(new WeakReference(this), mAttributes, sampleRate, mChannelMask, mChannelIndexMask, mAudioFormat, mNativeBufferSizeInBytes, mDataLoadMode, session, 0 /*nativeTrackInJavaObj*/, - offload, encapsulationMode, tunerConfiguration); + offload, encapsulationMode, tunerConfiguration, + getCurrentOpPackageName()); if (initResult != SUCCESS) { loge("Error code "+initResult+" when initializing AudioTrack."); return; // with mState == STATE_UNINITIALIZED @@ -893,7 +894,8 @@ public class AudioTrack extends PlayerBase nativeTrackInJavaObj, false /*offload*/, ENCAPSULATION_MODE_NONE, - null /* tunerConfiguration */); + null /* tunerConfiguration */, + "" /* opPackagename */); if (initResult != SUCCESS) { loge("Error code "+initResult+" when initializing AudioTrack."); return; // with mState == STATE_UNINITIALIZED @@ -4062,7 +4064,8 @@ public class AudioTrack extends PlayerBase Object /*AudioAttributes*/ attributes, int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat, int buffSizeInBytes, int mode, int[] sessionId, long nativeAudioTrack, - boolean offload, int encapsulationMode, Object tunerConfiguration); + boolean offload, int encapsulationMode, Object tunerConfiguration, + @NonNull String opPackageName); private native final void native_finalize(); diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 49e416080041..36ae3ec75a99 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -672,7 +672,8 @@ public class MediaPlayer extends PlayerBase /* Native setup requires a weak reference to our object. * It's easier to create it here than in C++. */ - native_setup(new WeakReference(this)); + native_setup(new WeakReference(this), + getCurrentOpPackageName()); baseRegisterPlayer(); } @@ -2378,7 +2379,7 @@ public class MediaPlayer extends PlayerBase private native final int native_setMetadataFilter(Parcel request); private static native final void native_init(); - private native final void native_setup(Object mediaplayer_this); + private native void native_setup(Object mediaplayerThis, @NonNull String opPackageName); private native final void native_finalize(); /** diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java index ee8f1b3eec77..df5e85edbc30 100644 --- a/media/java/android/media/PlayerBase.java +++ b/media/java/android/media/PlayerBase.java @@ -27,6 +27,7 @@ import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; +import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -622,4 +623,8 @@ public abstract class PlayerBase { Log.w(className, "See the documentation of " + opName + " for what to use instead with " + "android.media.AudioAttributes to qualify your playback use case"); } + + protected String getCurrentOpPackageName() { + return TextUtils.emptyIfNull(ActivityThread.currentOpPackageName()); + } } diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 82b746f6a9e5..d63b1adff5a0 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -33,6 +33,7 @@ #include #include "jni.h" #include +#include #include "android_runtime/AndroidRuntime.h" #include "android_runtime/android_view_Surface.h" #include "android_runtime/Log.h" @@ -944,10 +945,12 @@ android_media_MediaPlayer_native_init(JNIEnv *env) } static void -android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this) +android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, + jstring opPackageName) { ALOGV("native_setup"); - sp mp = new MediaPlayer(); + ScopedUtfChars opPackageNameStr(env, opPackageName); + sp mp = new MediaPlayer(opPackageNameStr.c_str()); if (mp == NULL) { jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); return; @@ -1403,7 +1406,7 @@ static const JNINativeMethod gMethods[] = { {"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter}, {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata}, {"native_init", "()V", (void *)android_media_MediaPlayer_native_init}, - {"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup}, + {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;)V",(void *)android_media_MediaPlayer_native_setup}, {"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize}, {"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id}, {"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id}, -- GitLab From 80e875fad688a0af6c1971dd517680a03a92ffc8 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Fri, 11 Sep 2020 17:03:03 -0700 Subject: [PATCH 405/536] Log the application uid in PipUiEventLogger Regression from ag/12132203, we should log the application uid instead of the running user id. Bug: 168342514 Test: $ANDROID_HOST_OUT/bin/statsd_testdrive -terse 90 Merged-In: If5d1bfe9ce38ea21bb9e5e13f51622f732dd85b9 Change-Id: If5d1bfe9ce38ea21bb9e5e13f51622f732dd85b9 --- .../systemui/pip/PipUiEventLogger.java | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUiEventLogger.java b/packages/SystemUI/src/com/android/systemui/pip/PipUiEventLogger.java index 5e2cd9c111b2..970203578e73 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipUiEventLogger.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipUiEventLogger.java @@ -17,6 +17,7 @@ package com.android.systemui.pip; import android.app.TaskInfo; +import android.content.pm.PackageManager; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; @@ -31,27 +32,49 @@ import javax.inject.Singleton; @Singleton public class PipUiEventLogger { + private static final int INVALID_PACKAGE_UID = -1; + private final UiEventLogger mUiEventLogger; + private final PackageManager mPackageManager; - private TaskInfo mTaskInfo; + private String mPackageName; + private int mPackageUid = INVALID_PACKAGE_UID; @Inject - public PipUiEventLogger(UiEventLogger uiEventLogger) { + public PipUiEventLogger(UiEventLogger uiEventLogger, PackageManager packageManager) { mUiEventLogger = uiEventLogger; + mPackageManager = packageManager; } public void setTaskInfo(TaskInfo taskInfo) { - mTaskInfo = taskInfo; + if (taskInfo == null) { + mPackageName = null; + mPackageUid = INVALID_PACKAGE_UID; + } else { + mPackageName = taskInfo.topActivity.getPackageName(); + mPackageUid = getUid(mPackageName, taskInfo.userId); + } } /** * Sends log via UiEvent, reference go/uievent for how to debug locally */ public void log(PipUiEventEnum event) { - if (mTaskInfo == null) { + if (mPackageName == null || mPackageUid == INVALID_PACKAGE_UID) { return; } - mUiEventLogger.log(event, mTaskInfo.userId, mTaskInfo.topActivity.getPackageName()); + mUiEventLogger.log(event, mPackageUid, mPackageName); + } + + private int getUid(String packageName, int userId) { + int uid = INVALID_PACKAGE_UID; + try { + uid = mPackageManager.getApplicationInfoAsUser( + packageName, 0 /* ApplicationInfoFlags */, userId).uid; + } catch (PackageManager.NameNotFoundException e) { + // do nothing. + } + return uid; } /** -- GitLab From a0e8b666e4d3c8c7bd577ac34dfdccf51182246e Mon Sep 17 00:00:00 2001 From: kwaky Date: Wed, 9 Sep 2020 13:45:19 -0700 Subject: [PATCH 406/536] DO NOT MERGE Enable hiding system bars by side when IME appears. Bug: 167593045 Test: Manual + Unit Tests Change-Id: Ib0c2c70e2df361f5cce156315c7fd4ae489ae279 --- packages/CarSystemUI/res/values/config.xml | 10 ++++ .../car/navigationbar/CarNavigationBar.java | 40 +++++++++++---- .../CarNavigationBarController.java | 13 ++--- .../car/navigationbar/SystemBarConfigs.java | 49 ++++++++++++++++++- .../CarNavigationBarControllerTest.java | 22 +++++++++ .../navigationbar/SystemBarConfigsTest.java | 40 +++++++++++++++ 6 files changed, 157 insertions(+), 17 deletions(-) diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml index 039f2c039ded..24157f9e2038 100644 --- a/packages/CarSystemUI/res/values/config.xml +++ b/packages/CarSystemUI/res/values/config.xml @@ -53,6 +53,16 @@ 0 10 + + false + + @*android:bool/config_automotiveHideNavBarForKeyboard + + false + false + false diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java index 9584850fde7c..b6d251fbfe16 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java @@ -91,7 +91,11 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks private ActivityManagerWrapper mActivityManagerWrapper; // If the nav bar should be hidden when the soft keyboard is visible. - private boolean mHideNavBarForKeyboard; + private boolean mHideTopBarForKeyboard; + private boolean mHideLeftBarForKeyboard; + private boolean mHideRightBarForKeyboard; + private boolean mHideBottomBarForKeyboard; + private boolean mBottomNavBarVisible; // Nav bar views. @@ -160,8 +164,13 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks @Override public void start() { // Set initial state. - mHideNavBarForKeyboard = mResources.getBoolean( - com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard); + mHideTopBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.TOP); + mHideBottomBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide( + SystemBarConfigs.BOTTOM); + mHideLeftBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.LEFT); + mHideRightBarForKeyboard = mSystemBarConfigs.getHideForKeyboardBySide( + SystemBarConfigs.RIGHT); + mBottomNavBarVisible = false; // Connect into the status bar manager service @@ -407,17 +416,30 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks @Override public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher) { - if (!mHideNavBarForKeyboard) { - return; - } - if (mContext.getDisplayId() != displayId) { return; } boolean isKeyboardVisible = (vis & InputMethodService.IME_VISIBLE) != 0; - mCarNavigationBarController.setBottomWindowVisibility( - isKeyboardVisible ? View.GONE : View.VISIBLE); + + if (mHideTopBarForKeyboard) { + mCarNavigationBarController.setTopWindowVisibility( + isKeyboardVisible ? View.GONE : View.VISIBLE); + } + + if (mHideBottomBarForKeyboard) { + mCarNavigationBarController.setBottomWindowVisibility( + isKeyboardVisible ? View.GONE : View.VISIBLE); + } + + if (mHideLeftBarForKeyboard) { + mCarNavigationBarController.setLeftWindowVisibility( + isKeyboardVisible ? View.GONE : View.VISIBLE); + } + if (mHideRightBarForKeyboard) { + mCarNavigationBarController.setRightWindowVisibility( + isKeyboardVisible ? View.GONE : View.VISIBLE); + } } @Override diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java index fe26040c5eae..e522d19249e3 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java @@ -79,9 +79,7 @@ public class CarNavigationBarController { * Hides all system bars. */ public void hideBars() { - if (mTopView != null) { - mTopView.setVisibility(View.GONE); - } + setTopWindowVisibility(View.GONE); setBottomWindowVisibility(View.GONE); setLeftWindowVisibility(View.GONE); setRightWindowVisibility(View.GONE); @@ -91,9 +89,7 @@ public class CarNavigationBarController { * Shows all system bars. */ public void showBars() { - if (mTopView != null) { - mTopView.setVisibility(View.VISIBLE); - } + setTopWindowVisibility(View.VISIBLE); setBottomWindowVisibility(View.VISIBLE); setLeftWindowVisibility(View.VISIBLE); setRightWindowVisibility(View.VISIBLE); @@ -135,6 +131,11 @@ public class CarNavigationBarController { return mShowRight ? mNavigationBarViewFactory.getRightWindow() : null; } + /** Toggles the top nav bar visibility. */ + public boolean setTopWindowVisibility(@View.Visibility int visibility) { + return setWindowVisibility(getTopWindow(), visibility); + } + /** Toggles the bottom nav bar visibility. */ public boolean setBottomWindowVisibility(@View.Visibility int visibility) { return setWindowVisibility(getBottomWindow(), visibility); diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java index e7d31949eb24..3f6a08c39cc3 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java @@ -98,6 +98,7 @@ public class SystemBarConfigs { readConfigs(); checkEnabledBarsHaveUniqueBarTypes(); checkSystemBarEnabledForNotificationPanel(); + checkHideBottomBarForKeyboardConfigSync(); setInsetPaddingsForOverlappingCorners(); sortSystemBarSidesByZOrder(); } @@ -122,6 +123,11 @@ public class SystemBarConfigs { } } + protected boolean getHideForKeyboardBySide(@SystemBarSide int side) { + return mSystemBarConfigMap.get(side) != null + && mSystemBarConfigMap.get(side).getHideForKeyboard(); + } + protected void insetSystemBar(@SystemBarSide int side, CarNavigationBarView view) { int[] paddings = mSystemBarConfigMap.get(side).getPaddings(); view.setPadding(paddings[2], paddings[0], paddings[3], paddings[1]); @@ -167,6 +173,8 @@ public class SystemBarConfigs { com.android.internal.R.dimen.status_bar_height)) .setBarType(mResources.getInteger(R.integer.config_topSystemBarType)) .setZOrder(mResources.getInteger(R.integer.config_topSystemBarZOrder)) + .setHideForKeyboard(mResources.getBoolean( + R.bool.config_hideTopSystemBarForKeyboard)) .build(); mSystemBarConfigMap.put(TOP, topBarConfig); } @@ -180,6 +188,8 @@ public class SystemBarConfigs { .setBarType(mResources.getInteger(R.integer.config_bottomSystemBarType)) .setZOrder( mResources.getInteger(R.integer.config_bottomSystemBarZOrder)) + .setHideForKeyboard(mResources.getBoolean( + R.bool.config_hideBottomSystemBarForKeyboard)) .build(); mSystemBarConfigMap.put(BOTTOM, bottomBarConfig); } @@ -192,6 +202,8 @@ public class SystemBarConfigs { R.dimen.car_left_navigation_bar_width)) .setBarType(mResources.getInteger(R.integer.config_leftSystemBarType)) .setZOrder(mResources.getInteger(R.integer.config_leftSystemBarZOrder)) + .setHideForKeyboard(mResources.getBoolean( + R.bool.config_hideLeftSystemBarForKeyboard)) .build(); mSystemBarConfigMap.put(LEFT, leftBarConfig); } @@ -204,6 +216,8 @@ public class SystemBarConfigs { R.dimen.car_right_navigation_bar_width)) .setBarType(mResources.getInteger(R.integer.config_rightSystemBarType)) .setZOrder(mResources.getInteger(R.integer.config_rightSystemBarZOrder)) + .setHideForKeyboard(mResources.getBoolean( + R.bool.config_hideRightSystemBarForKeyboard)) .build(); mSystemBarConfigMap.put(RIGHT, rightBarConfig); } @@ -252,6 +266,24 @@ public class SystemBarConfigs { } } + private void checkHideBottomBarForKeyboardConfigSync() throws RuntimeException { + if (mBottomNavBarEnabled) { + boolean actual = mResources.getBoolean(R.bool.config_hideBottomSystemBarForKeyboard); + boolean expected = mResources.getBoolean( + com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard); + + if (actual != expected) { + throw new RuntimeException("config_hideBottomSystemBarForKeyboard must not be " + + "overlaid directly and should always refer to" + + "config_automotiveHideNavBarForKeyboard. However, their values " + + "currently do not sync. Set config_hideBottomSystemBarForKeyguard to " + + "@*android:bool/config_automotiveHideNavBarForKeyboard. To change its " + + "value, overlay config_automotiveHideNavBarForKeyboard in " + + "framework/base/core/res/res."); + } + } + } + private void setInsetPaddingsForOverlappingCorners() { setInsetPaddingForOverlappingCorner(TOP, LEFT); setInsetPaddingForOverlappingCorner(TOP, RIGHT); @@ -320,14 +352,17 @@ public class SystemBarConfigs { private final int mBarType; private final int mGirth; private final int mZOrder; + private final boolean mHideForKeyboard; private int[] mPaddings = new int[]{0, 0, 0, 0}; - private SystemBarConfig(@SystemBarSide int side, int barType, int girth, int zOrder) { + private SystemBarConfig(@SystemBarSide int side, int barType, int girth, int zOrder, + boolean hideForKeyboard) { mSide = side; mBarType = barType; mGirth = girth; mZOrder = zOrder; + mHideForKeyboard = hideForKeyboard; } private int getSide() { @@ -346,6 +381,10 @@ public class SystemBarConfigs { return mZOrder; } + private boolean getHideForKeyboard() { + return mHideForKeyboard; + } + private int[] getPaddings() { return mPaddings; } @@ -383,6 +422,7 @@ public class SystemBarConfigs { private int mBarType; private int mGirth; private int mZOrder; + private boolean mHideForKeyboard; private SystemBarConfigBuilder setSide(@SystemBarSide int side) { mSide = side; @@ -404,8 +444,13 @@ public class SystemBarConfigs { return this; } + private SystemBarConfigBuilder setHideForKeyboard(boolean hide) { + mHideForKeyboard = hide; + return this; + } + private SystemBarConfig build() { - return new SystemBarConfig(mSide, mBarType, mGirth, mZOrder); + return new SystemBarConfig(mSide, mBarType, mGirth, mZOrder, mHideForKeyboard); } } } diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java index 84c840477302..3fd0852bc0ff 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java @@ -250,6 +250,28 @@ public class CarNavigationBarControllerTest extends SysuiTestCase { assertThat(window1).isEqualTo(window2); } + @Test + public void testSetTopWindowVisibility_setTrue_isVisible() { + mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true); + mCarNavigationBar = createNavigationBarController(); + + ViewGroup window = mCarNavigationBar.getTopWindow(); + mCarNavigationBar.setTopWindowVisibility(View.VISIBLE); + + assertThat(window.getVisibility()).isEqualTo(View.VISIBLE); + } + + @Test + public void testSetTopWindowVisibility_setFalse_isGone() { + mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true); + mCarNavigationBar = createNavigationBarController(); + + ViewGroup window = mCarNavigationBar.getTopWindow(); + mCarNavigationBar.setTopWindowVisibility(View.GONE); + + assertThat(window.getVisibility()).isEqualTo(View.GONE); + } + @Test public void testSetBottomWindowVisibility_setTrue_isVisible() { mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true); diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java index 8b1589913d1d..41b0d785201b 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java @@ -17,6 +17,7 @@ package com.android.systemui.car.navigationbar; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -92,6 +93,16 @@ public class SystemBarConfigsTest extends SysuiTestCase { mSystemBarConfigs = new SystemBarConfigs(mResources); } + @Test(expected = RuntimeException.class) + public void onInit_hideBottomSystemBarForKeyboardValueDoNotSync_throwsRuntimeException() { + when(mResources.getBoolean(R.bool.config_hideBottomSystemBarForKeyboard)).thenReturn(false); + when(mResources.getBoolean( + com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard)).thenReturn( + true); + + mSystemBarConfigs = new SystemBarConfigs(mResources); + } + @Test public void getTopSystemBarLayoutParams_topBarEnabled_returnsTopSystemBarLayoutParams() { mSystemBarConfigs = new SystemBarConfigs(mResources); @@ -111,6 +122,26 @@ public class SystemBarConfigsTest extends SysuiTestCase { assertNull(lp); } + @Test + public void getTopSystemBarHideForKeyboard_hideBarForKeyboard_returnsTrue() { + when(mResources.getBoolean(R.bool.config_hideTopSystemBarForKeyboard)).thenReturn(true); + mSystemBarConfigs = new SystemBarConfigs(mResources); + + boolean hideKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.TOP); + + assertTrue(hideKeyboard); + } + + @Test + public void getTopSystemBarHideForKeyboard_topBarNotEnabled_returnsFalse() { + when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(false); + mSystemBarConfigs = new SystemBarConfigs(mResources); + + boolean hideKeyboard = mSystemBarConfigs.getHideForKeyboardBySide(SystemBarConfigs.TOP); + + assertFalse(hideKeyboard); + } + @Test public void topSystemBarHasHigherZOrderThanHuns_topSystemBarIsNavigationBarPanelType() { when(mResources.getInteger(R.integer.config_topSystemBarZOrder)).thenReturn( @@ -158,5 +189,14 @@ public class SystemBarConfigsTest extends SysuiTestCase { when(mResources.getInteger(R.integer.config_bottomSystemBarZOrder)).thenReturn(10); when(mResources.getInteger(R.integer.config_leftSystemBarZOrder)).thenReturn(2); when(mResources.getInteger(R.integer.config_rightSystemBarZOrder)).thenReturn(3); + + when(mResources.getBoolean(R.bool.config_hideTopSystemBarForKeyboard)).thenReturn(false); + when(mResources.getBoolean( + com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard)).thenReturn( + false); + when(mResources.getBoolean(R.bool.config_hideLeftSystemBarForKeyboard)).thenReturn( + false); + when(mResources.getBoolean(R.bool.config_hideRightSystemBarForKeyboard)).thenReturn( + false); } } -- GitLab From cc3dfbeebacca23b07bbd5f59354786f538cc056 Mon Sep 17 00:00:00 2001 From: kwaky Date: Thu, 10 Sep 2020 18:58:03 -0700 Subject: [PATCH 407/536] DO NOT MERGE Fix subclass/superclass check for NotificationPanelViewMediator. Bug: 165806308 Test: Manual + Unit Tests Passing Change-Id: I8f443762f1b487ab9d3fe4f6f84b0aa86e3d0c8a --- .../car/navigationbar/SystemBarConfigs.java | 8 +-- .../navigationbar/SystemBarConfigsTest.java | 50 +++++++++++++++++++ 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java index e7d31949eb24..39ea79cff718 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/SystemBarConfigs.java @@ -239,14 +239,14 @@ public class SystemBarConfigs { e.printStackTrace(); } - if (!mTopNavBarEnabled && notificationPanelMediatorUsed.isAssignableFrom( - TopNotificationPanelViewMediator.class)) { + if (!mTopNavBarEnabled && TopNotificationPanelViewMediator.class.isAssignableFrom( + notificationPanelMediatorUsed)) { throw new RuntimeException( "Top System Bar must be enabled to use " + notificationPanelMediatorName); } - if (!mBottomNavBarEnabled && notificationPanelMediatorUsed.isAssignableFrom( - BottomNotificationPanelViewMediator.class)) { + if (!mBottomNavBarEnabled && BottomNotificationPanelViewMediator.class.isAssignableFrom( + notificationPanelMediatorUsed)) { throw new RuntimeException("Bottom System Bar must be enabled to use " + notificationPanelMediatorName); } diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java index 8b1589913d1d..19b25958c2ad 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/SystemBarConfigsTest.java @@ -31,7 +31,14 @@ import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.car.CarDeviceProvisionedController; import com.android.systemui.car.CarSystemUiTest; +import com.android.systemui.car.notification.NotificationPanelViewController; +import com.android.systemui.car.notification.NotificationPanelViewMediator; +import com.android.systemui.car.notification.PowerManagerHelper; +import com.android.systemui.car.notification.TopNotificationPanelViewMediator; +import com.android.systemui.statusbar.policy.ConfigurationController; import org.junit.Before; import org.junit.Test; @@ -92,6 +99,33 @@ public class SystemBarConfigsTest extends SysuiTestCase { mSystemBarConfigs = new SystemBarConfigs(mResources); } + @Test + public void onInit_topNotifPanelViewMediatorUsed_topBarEnabled_doesNotThrowException() { + when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(true); + when(mResources.getString(R.string.config_notificationPanelViewMediator)).thenReturn( + TestTopNotificationPanelViewMediator.class.getName()); + + mSystemBarConfigs = new SystemBarConfigs(mResources); + } + + @Test(expected = RuntimeException.class) + public void onInit_topNotifPanelViewMediatorUsed_topBarNotEnabled_throwsRuntimeException() { + when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(false); + when(mResources.getString(R.string.config_notificationPanelViewMediator)).thenReturn( + TestTopNotificationPanelViewMediator.class.getName()); + + mSystemBarConfigs = new SystemBarConfigs(mResources); + } + + @Test + public void onInit_notificationPanelViewMediatorUsed_topBarNotEnabled_doesNotThrowException() { + when(mResources.getBoolean(R.bool.config_enableTopNavigationBar)).thenReturn(false); + when(mResources.getString(R.string.config_notificationPanelViewMediator)).thenReturn( + NotificationPanelViewMediator.class.getName()); + + mSystemBarConfigs = new SystemBarConfigs(mResources); + } + @Test public void getTopSystemBarLayoutParams_topBarEnabled_returnsTopSystemBarLayoutParams() { mSystemBarConfigs = new SystemBarConfigs(mResources); @@ -159,4 +193,20 @@ public class SystemBarConfigsTest extends SysuiTestCase { when(mResources.getInteger(R.integer.config_leftSystemBarZOrder)).thenReturn(2); when(mResources.getInteger(R.integer.config_rightSystemBarZOrder)).thenReturn(3); } + + // Intentionally using a subclass of TopNotificationPanelViewMediator for testing purposes to + // ensure that OEM's will be able to implement and use their own NotificationPanelViewMediator. + private class TestTopNotificationPanelViewMediator extends + TopNotificationPanelViewMediator { + TestTopNotificationPanelViewMediator( + CarNavigationBarController carNavigationBarController, + NotificationPanelViewController notificationPanelViewController, + PowerManagerHelper powerManagerHelper, + BroadcastDispatcher broadcastDispatcher, + CarDeviceProvisionedController carDeviceProvisionedController, + ConfigurationController configurationController) { + super(carNavigationBarController, notificationPanelViewController, powerManagerHelper, + broadcastDispatcher, carDeviceProvisionedController, configurationController); + } + } } -- GitLab From 51d9edc29249593ace7328f6d0a81c21c5d062c3 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Fri, 11 Sep 2020 18:49:08 -0700 Subject: [PATCH 408/536] Fixed PackageManager.readLPw() call. It wasn't including pre-created users; as such, apps that were not installed on pre-created users got installed on reboot. To test it: adb shell pm create-user --pre-create-only m ApiDemos adb install --user current ~/Downloads/apk/ApiDemos.apk adb shell dumpsys package com.example.android.apis |egrep ".*User .*:"|grep installed adb shell stop && adb shell start adb shell dumpsys package com.example.android.apis |egrep ".*User .*:"|grep installed Without this fix, the second dumpsys would show the app installed for the pre-created user. Test: see above Test: atest CtsMultiUserHostTestCases:android.host.multiuser.PreCreateUsersTest # will be added later on AOSP branch Bug: 160252062 Change-Id: I46c2ec94a3ab422e3e39b66239c21fb6cbff5a8e Merged-In: I46c2ec94a3ab422e3e39b66239c21fb6cbff5a8e (cherry picked from commit 2c43b50331eaf428df3e7cb1886fd7d60f41ad54) --- .../java/android/os/UserManagerInternal.java | 8 +++++++ .../server/pm/PackageManagerService.java | 5 +++- .../java/com/android/server/pm/Settings.java | 7 +++++- .../android/server/pm/UserManagerService.java | 10 ++++++-- .../permission/PermissionManagerService.java | 23 +++++++++---------- 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/services/core/java/android/os/UserManagerInternal.java b/services/core/java/android/os/UserManagerInternal.java index fbe8c04bd59c..38983488654e 100644 --- a/services/core/java/android/os/UserManagerInternal.java +++ b/services/core/java/android/os/UserManagerInternal.java @@ -226,6 +226,14 @@ public abstract class UserManagerInternal { */ public abstract @NonNull List getUsers(boolean excludeDying); + /** + * Internal implementation of getUsers does not check permissions. + * This improves performance for calls from inside system server which already have permissions + * checked. + */ + public abstract @NonNull List getUsers(boolean excludePartial, boolean excludeDying, + boolean excludePreCreated); + /** * Checks if the {@code callingUserId} and {@code targetUserId} are same or in same group * and that the {@code callingUserId} is not a profile and {@code targetUserId} is enabled. diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5c3644e5b262..daca0b34ec2a 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -2991,7 +2991,10 @@ public class PackageManagerService extends IPackageManager.Stub t.traceEnd(); t.traceBegin("read user settings"); - mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(false)); + mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers( + /* excludePartial= */ true, + /* excludeDying= */ false, + /* excludePreCreated= */ false)); t.traceEnd(); // Clean up orphaned packages for which the code path doesn't exist diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index a0feb94fd3fc..aeea2514d0a4 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1613,6 +1613,7 @@ public final class Settings { return; } str = new FileInputStream(userPackagesStateFile); + if (DEBUG_MU) Log.i(TAG, "Reading " + userPackagesStateFile); } final XmlPullParser parser = Xml.newPullParser(); parser.setInput(str, StandardCharsets.UTF_8.name()); @@ -2057,9 +2058,13 @@ public final class Settings { serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS); + if (DEBUG_MU) Log.i(TAG, "Writing " + userPackagesStateFile); for (final PackageSetting pkg : mPackages.values()) { final PackageUserState ustate = pkg.readUserState(userId); - if (DEBUG_MU) Log.i(TAG, " pkg=" + pkg.name + ", state=" + ustate.enabled); + if (DEBUG_MU) { + Log.i(TAG, " pkg=" + pkg.name + ", installed=" + ustate.installed + + ", state=" + ustate.enabled); + } serializer.startTag(null, TAG_PACKAGE); serializer.attribute(null, ATTR_NAME, pkg.name); diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 01a3d14e05df..244818a6f311 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -5102,8 +5102,14 @@ public class UserManagerService extends IUserManager.Stub { @Override public @NonNull List getUsers(boolean excludeDying) { - return UserManagerService.this.getUsersInternal(/*excludePartial= */ true, - excludeDying, /* excludePreCreated= */ true); + return getUsers(/*excludePartial= */ true, excludeDying, /* excludePreCreated= */ true); + } + + @Override + public @NonNull List getUsers(boolean excludePartial, boolean excludeDying, + boolean excludePreCreated) { + return UserManagerService.this.getUsersInternal(excludePartial, excludeDying, + excludePreCreated); } @Override diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 2533aa7c4302..66d8b5974261 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -2603,13 +2603,13 @@ public class PermissionManagerService extends IPermissionManager.Stub { final int N = pkg.getRequestedPermissions().size(); for (int i = 0; i < N; i++) { final String permName = pkg.getRequestedPermissions().get(i); + final String friendlyName = pkg.getPackageName() + "(" + pkg.getUid() + ")"; final BasePermission bp = mSettings.getPermissionLocked(permName); final boolean appSupportsRuntimePermissions = pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M; String upgradedActivityRecognitionPermission = null; - if (DEBUG_INSTALL && bp != null) { - Log.i(TAG, "Package " + pkg.getPackageName() + Log.i(TAG, "Package " + friendlyName + " checking " + permName + ": " + bp); } @@ -2618,7 +2618,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { pkg.getPackageName())) { if (DEBUG_PERMISSIONS) { Slog.i(TAG, "Unknown permission " + permName - + " in package " + pkg.getPackageName()); + + " in package " + friendlyName); } } continue; @@ -2634,7 +2634,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { newImplicitPermissions.add(permName); if (DEBUG_PERMISSIONS) { - Slog.i(TAG, permName + " is newly added for " + pkg.getPackageName()); + Slog.i(TAG, permName + " is newly added for " + friendlyName); } } else { // Special case for Activity Recognition permission. Even if AR permission @@ -2656,8 +2656,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { newImplicitPermissions.add(permName); if (DEBUG_PERMISSIONS) { - Slog.i(TAG, permName + " is newly added for " - + pkg.getPackageName()); + Slog.i(TAG, permName + " is newly added for " + friendlyName); } break; } @@ -2671,7 +2670,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { // if (/*pkg.isInstantApp()*/ false && !bp.isInstant()) { // if (DEBUG_PERMISSIONS) { // Log.i(TAG, "Denying non-ephemeral permission " + bp.getName() -// + " for package " + pkg.getPackageName()); +// + " for package " + friendlyName); // } // continue; // } @@ -2679,7 +2678,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) { if (DEBUG_PERMISSIONS) { Log.i(TAG, "Denying runtime-only permission " + bp.getName() - + " for package " + pkg.getPackageName()); + + " for package " + friendlyName); } continue; } @@ -2716,7 +2715,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (DEBUG_PERMISSIONS) { Slog.i(TAG, "Considering granting permission " + perm + " to package " - + pkg.getPackageName()); + + friendlyName); } if (grant != GRANT_DENIED) { @@ -3005,7 +3004,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { || packageOfInterest.equals(pkg.getPackageName())) { if (DEBUG_PERMISSIONS) { Slog.i(TAG, "Not granting permission " + perm - + " to package " + pkg.getPackageName() + + " to package " + friendlyName + " because it was previously installed without"); } } @@ -3020,7 +3019,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { changedInstallPermission = true; if (DEBUG_PERMISSIONS) { Slog.i(TAG, "Un-granting permission " + perm - + " from package " + pkg.getPackageName() + + " from package " + friendlyName + " (protectionLevel=" + bp.getProtectionLevel() + " flags=0x" + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, ps)) @@ -3033,7 +3032,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { && (packageOfInterest == null || packageOfInterest.equals(pkg.getPackageName()))) { Slog.i(TAG, "Not granting permission " + perm - + " to package " + pkg.getPackageName() + + " to package " + friendlyName + " (protectionLevel=" + bp.getProtectionLevel() + " flags=0x" + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, ps)) -- GitLab From fcd4cbf4f42e2bb3fad7e3a8a8db71dc8981d134 Mon Sep 17 00:00:00 2001 From: jiabin Date: Fri, 21 Aug 2020 18:07:27 -0700 Subject: [PATCH 409/536] Add package name when creating AudioTrack. The package name will be used when starting external vibration. The package name will be sent to vibrator service to check if the application has the permission to start vibration, Bug: 165910728 Bug: 162343845 Test: atest AudioTrackTest MediaPlayerTest Test: start audio-coupled-haptic playback Change-Id: I04b4711d11ab5f0f0716ea4c5e1c0f754fe834bb Merged-In: I04b4711d11ab5f0f0716ea4c5e1c0f754fe834bb --- core/jni/android_media_AudioTrack.cpp | 76 ++++++++++++----------- media/java/android/media/AudioTrack.java | 9 ++- media/java/android/media/MediaPlayer.java | 5 +- media/java/android/media/PlayerBase.java | 5 ++ media/jni/android_media_MediaPlayer.cpp | 9 ++- 5 files changed, 60 insertions(+), 44 deletions(-) diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index 5c045b65be22..7a5c38385f32 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -20,6 +20,7 @@ #include "android_media_AudioTrack.h" #include +#include #include "core_jni_helpers.h" #include @@ -251,7 +252,7 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession, jlong nativeAudioTrack, jboolean offload, jint encapsulationMode, - jobject tunerConfiguration) { + jobject tunerConfiguration, jstring opPackageName) { ALOGV("sampleRates=%p, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d," " nativeAudioTrack=0x%" PRIX64 ", offload=%d encapsulationMode=%d tuner=%p", jSampleRate, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes, @@ -337,7 +338,8 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we } // create the native AudioTrack object - lpTrack = new AudioTrack(); + ScopedUtfChars opPackageNameStr(env, opPackageName); + lpTrack = new AudioTrack(opPackageNameStr.c_str()); // read the AudioAttributes values auto paa = JNIAudioAttributeHelper::makeUnique(); @@ -371,23 +373,24 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we status_t status = NO_ERROR; switch (memoryMode) { case MODE_STREAM: - status = lpTrack->set( - AUDIO_STREAM_DEFAULT,// stream type, but more info conveyed in paa (last argument) - sampleRateInHertz, - format,// word length, PCM - nativeChannelMask, - offload ? 0 : frameCount, - offload ? AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD : AUDIO_OUTPUT_FLAG_NONE, - audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user) - 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack - 0,// shared mem - true,// thread can call Java - sessionId,// audio session ID - offload ? AudioTrack::TRANSFER_SYNC_NOTIF_CALLBACK : AudioTrack::TRANSFER_SYNC, - offload ? &offloadInfo : NULL, - -1, -1, // default uid, pid values - paa.get()); - + status = lpTrack->set(AUDIO_STREAM_DEFAULT, // stream type, but more info conveyed + // in paa (last argument) + sampleRateInHertz, + format, // word length, PCM + nativeChannelMask, offload ? 0 : frameCount, + offload ? AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD + : AUDIO_OUTPUT_FLAG_NONE, + audioCallback, + &(lpJniStorage->mCallbackData), // callback, callback data (user) + 0, // notificationFrames == 0 since not using EVENT_MORE_DATA + // to feed the AudioTrack + 0, // shared mem + true, // thread can call Java + sessionId, // audio session ID + offload ? AudioTrack::TRANSFER_SYNC_NOTIF_CALLBACK + : AudioTrack::TRANSFER_SYNC, + offload ? &offloadInfo : NULL, -1, -1, // default uid, pid values + paa.get()); break; case MODE_STATIC: @@ -398,22 +401,22 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we goto native_init_failure; } - status = lpTrack->set( - AUDIO_STREAM_DEFAULT,// stream type, but more info conveyed in paa (last argument) - sampleRateInHertz, - format,// word length, PCM - nativeChannelMask, - frameCount, - AUDIO_OUTPUT_FLAG_NONE, - audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)); - 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack - lpJniStorage->mMemBase,// shared mem - true,// thread can call Java - sessionId,// audio session ID - AudioTrack::TRANSFER_SHARED, - NULL, // default offloadInfo - -1, -1, // default uid, pid values - paa.get()); + status = lpTrack->set(AUDIO_STREAM_DEFAULT, // stream type, but more info conveyed + // in paa (last argument) + sampleRateInHertz, + format, // word length, PCM + nativeChannelMask, frameCount, AUDIO_OUTPUT_FLAG_NONE, + audioCallback, + &(lpJniStorage->mCallbackData), // callback, callback data (user) + 0, // notificationFrames == 0 since not using EVENT_MORE_DATA + // to feed the AudioTrack + lpJniStorage->mMemBase, // shared mem + true, // thread can call Java + sessionId, // audio session ID + AudioTrack::TRANSFER_SHARED, + NULL, // default offloadInfo + -1, -1, // default uid, pid values + paa.get()); break; default: @@ -1428,7 +1431,8 @@ static const JNINativeMethod gMethods[] = { {"native_stop", "()V", (void *)android_media_AudioTrack_stop}, {"native_pause", "()V", (void *)android_media_AudioTrack_pause}, {"native_flush", "()V", (void *)android_media_AudioTrack_flush}, - {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIIII[IJZILjava/lang/Object;)I", + {"native_setup", + "(Ljava/lang/Object;Ljava/lang/Object;[IIIIII[IJZILjava/lang/Object;Ljava/lang/String;)I", (void *)android_media_AudioTrack_setup}, {"native_finalize", "()V", (void *)android_media_AudioTrack_finalize}, {"native_release", "()V", (void *)android_media_AudioTrack_release}, diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 1c0a526f536c..de2a7b2c15e3 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -807,7 +807,8 @@ public class AudioTrack extends PlayerBase int initResult = native_setup(new WeakReference(this), mAttributes, sampleRate, mChannelMask, mChannelIndexMask, mAudioFormat, mNativeBufferSizeInBytes, mDataLoadMode, session, 0 /*nativeTrackInJavaObj*/, - offload, encapsulationMode, tunerConfiguration); + offload, encapsulationMode, tunerConfiguration, + getCurrentOpPackageName()); if (initResult != SUCCESS) { loge("Error code "+initResult+" when initializing AudioTrack."); return; // with mState == STATE_UNINITIALIZED @@ -893,7 +894,8 @@ public class AudioTrack extends PlayerBase nativeTrackInJavaObj, false /*offload*/, ENCAPSULATION_MODE_NONE, - null /* tunerConfiguration */); + null /* tunerConfiguration */, + "" /* opPackagename */); if (initResult != SUCCESS) { loge("Error code "+initResult+" when initializing AudioTrack."); return; // with mState == STATE_UNINITIALIZED @@ -4062,7 +4064,8 @@ public class AudioTrack extends PlayerBase Object /*AudioAttributes*/ attributes, int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat, int buffSizeInBytes, int mode, int[] sessionId, long nativeAudioTrack, - boolean offload, int encapsulationMode, Object tunerConfiguration); + boolean offload, int encapsulationMode, Object tunerConfiguration, + @NonNull String opPackageName); private native final void native_finalize(); diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 49e416080041..36ae3ec75a99 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -672,7 +672,8 @@ public class MediaPlayer extends PlayerBase /* Native setup requires a weak reference to our object. * It's easier to create it here than in C++. */ - native_setup(new WeakReference(this)); + native_setup(new WeakReference(this), + getCurrentOpPackageName()); baseRegisterPlayer(); } @@ -2378,7 +2379,7 @@ public class MediaPlayer extends PlayerBase private native final int native_setMetadataFilter(Parcel request); private static native final void native_init(); - private native final void native_setup(Object mediaplayer_this); + private native void native_setup(Object mediaplayerThis, @NonNull String opPackageName); private native final void native_finalize(); /** diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java index ee8f1b3eec77..df5e85edbc30 100644 --- a/media/java/android/media/PlayerBase.java +++ b/media/java/android/media/PlayerBase.java @@ -27,6 +27,7 @@ import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; +import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -622,4 +623,8 @@ public abstract class PlayerBase { Log.w(className, "See the documentation of " + opName + " for what to use instead with " + "android.media.AudioAttributes to qualify your playback use case"); } + + protected String getCurrentOpPackageName() { + return TextUtils.emptyIfNull(ActivityThread.currentOpPackageName()); + } } diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 5cb42a9a96cc..1516c5152054 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -33,6 +33,7 @@ #include #include "jni.h" #include +#include #include "android_runtime/AndroidRuntime.h" #include "android_runtime/android_view_Surface.h" #include "android_runtime/Log.h" @@ -944,10 +945,12 @@ android_media_MediaPlayer_native_init(JNIEnv *env) } static void -android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this) +android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, + jstring opPackageName) { ALOGV("native_setup"); - sp mp = new MediaPlayer(); + ScopedUtfChars opPackageNameStr(env, opPackageName); + sp mp = new MediaPlayer(opPackageNameStr.c_str()); if (mp == NULL) { jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); return; @@ -1403,7 +1406,7 @@ static const JNINativeMethod gMethods[] = { {"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter}, {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata}, {"native_init", "()V", (void *)android_media_MediaPlayer_native_init}, - {"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup}, + {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;)V",(void *)android_media_MediaPlayer_native_setup}, {"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize}, {"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id}, {"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id}, -- GitLab From 8c35d00752120ef91dad1ffd2d3cb8d0f5d4434f Mon Sep 17 00:00:00 2001 From: timhypeng Date: Wed, 12 Aug 2020 13:03:39 +0800 Subject: [PATCH 410/536] Display disconnected bluetooth devices only when local output device is available. -If media app does not support cast->phone transferring, local output audio device is unavailable. Disconnected bluetooth devices should be also unavilable. -These types are local output audio devices defined in MediaRoute2Info: TYPE_BUILTIN_SPEAKER TYPE_WIRED_HEADSET TYPE_WIRED_HEADPHONES TYPE_USB_DEVICE TYPE_USB_HEADSET TYPE_USB_ACCESSORY TYPE_DOCK TYPE_HDMI -Update test case Bug: 163095048 Test: make -j50 RunSettingsLibRoboTests Change-Id: I0ceea496d677e514cce0e773a8731bb4eeff874d (cherry picked from commit 254a0a2603a539c4b4fd2eec12bbec874553ee37) --- .../android/settingslib/media/LocalMediaManager.java | 11 ++++++++++- .../settingslib/media/LocalMediaManagerTest.java | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java index 9d06c8467e41..72a6074ff89c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java @@ -465,7 +465,16 @@ public class LocalMediaManager implements BluetoothCallback { synchronized (mMediaDevicesLock) { mMediaDevices.clear(); mMediaDevices.addAll(devices); - mMediaDevices.addAll(buildDisconnectedBluetoothDevice()); + // Add disconnected bluetooth devices only when phone output device is available. + for (MediaDevice device : devices) { + final int type = device.getDeviceType(); + if (type == MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE + || type == MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE + || type == MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE) { + mMediaDevices.addAll(buildDisconnectedBluetoothDevice()); + break; + } + } } final MediaDevice infoMediaDevice = mInfoMediaManager.getCurrentConnectedDevice(); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java index a654fd47ea12..8e850b25159c 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java @@ -585,6 +585,7 @@ public class LocalMediaManagerTest { when(device1.getId()).thenReturn(TEST_DEVICE_ID_1); when(device2.getId()).thenReturn(TEST_DEVICE_ID_2); when(device3.getId()).thenReturn(TEST_DEVICE_ID_3); + when(device1.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE); when(mLocalMediaManager.mPhoneDevice.getId()).thenReturn("test_phone_id"); assertThat(mLocalMediaManager.mMediaDevices).hasSize(2); @@ -683,6 +684,7 @@ public class LocalMediaManagerTest { when(device1.getId()).thenReturn(TEST_DEVICE_ID_1); when(device2.getId()).thenReturn(TEST_DEVICE_ID_2); when(device3.getId()).thenReturn(TEST_DEVICE_ID_3); + when(device1.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE); when(mLocalMediaManager.mPhoneDevice.getId()).thenReturn("test_phone_id"); assertThat(mLocalMediaManager.mMediaDevices).hasSize(2); -- GitLab From d5b74ca2648c1dabc0ebbe617d98ec084e6de66c Mon Sep 17 00:00:00 2001 From: Agatha Man Date: Tue, 15 Sep 2020 20:41:23 -0700 Subject: [PATCH 411/536] Increase keyguard password maxlength to 500 Bug: 166867759 Bug: 165784344 Test: manual Change-Id: Ic39223652fc7afe627259c4317ae90e0bcbc65b9 --- .../CarSystemUI/res-keyguard/layout/keyguard_password_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/CarSystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/CarSystemUI/res-keyguard/layout/keyguard_password_view.xml index 8b235e6f246e..d57875f8daba 100644 --- a/packages/CarSystemUI/res-keyguard/layout/keyguard_password_view.xml +++ b/packages/CarSystemUI/res-keyguard/layout/keyguard_password_view.xml @@ -53,7 +53,7 @@ android:textColor="?attr/wallpaperTextColor" android:textAppearance="?android:attr/textAppearanceMedium" android:imeOptions="flagForceAscii|actionDone" - android:maxLength="@integer/password_text_view_scale" + android:maxLength="@integer/password_max_length" /> Date: Wed, 15 Jul 2020 13:56:13 +0800 Subject: [PATCH 412/536] Pass correct install user when creating sessions This CL passes the correct install user when creating sessions in StagingManager and effectively reverts ag/6901350. Add a test to ensure b/129397974 is not regressed as described in b/158222747#comment11. (Cherry-picked from 838dea54caba0c6a17d90757211bc897ef77c963) Fix: 129744602 Fix: 158222747 Test: atest MultiUserRollbackTest#testStagedRollback Merged-In: I718992240aa76898ff9e4220ea6a769ee8cd61f5 Change-Id: I718992240aa76898ff9e4220ea6a769ee8cd61f5 --- .../com/android/server/pm/StagingManager.java | 6 +- tests/RollbackTest/Android.bp | 3 + .../rollback/host/MultiUserRollbackTest.java | 28 ++++++++ .../tests/rollback/MultiUserRollbackTest.java | 28 ++++++++ .../rollback/host/AbandonSessionsRule.java | 66 +++++++++++++++++++ 5 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 tests/utils/hostutils/src/com/android/tests/rollback/host/AbandonSessionsRule.java diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 5b1c0fdb8249..600357b7697f 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -743,7 +743,6 @@ public class StagingManager { PackageInstaller.SessionParams params = originalSession.params.copy(); params.isStaged = false; params.installFlags |= PackageManager.INSTALL_STAGED; - // TODO(b/129744602): use the userid from the original session. if (preReboot) { params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK; params.installFlags |= PackageManager.INSTALL_DRY_RUN; @@ -753,7 +752,7 @@ public class StagingManager { try { int apkSessionId = mPi.createSession( params, originalSession.getInstallerPackageName(), - 0 /* UserHandle.SYSTEM */); + originalSession.userId); PackageInstallerSession apkSession = mPi.getSession(apkSessionId); apkSession.open(); for (int i = 0, size = apkFilePaths.size(); i < size; i++) { @@ -811,10 +810,9 @@ public class StagingManager { if (preReboot) { params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK; } - // TODO(b/129744602): use the userid from the original session. final int apkParentSessionId = mPi.createSession( params, session.getInstallerPackageName(), - 0 /* UserHandle.SYSTEM */); + session.userId); final PackageInstallerSession apkParentSession = mPi.getSession(apkParentSessionId); try { apkParentSession.open(); diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp index 2be4ae6bb214..3ccbad84f2e0 100644 --- a/tests/RollbackTest/Android.bp +++ b/tests/RollbackTest/Android.bp @@ -48,6 +48,9 @@ java_test_host { name: "MultiUserRollbackTest", srcs: ["MultiUserRollbackTest/src/**/*.java"], libs: ["tradefed"], + static_libs: [ + "frameworks-base-hostutils", + ], test_suites: ["general-tests"], test_config: "MultiUserRollbackTest.xml", } diff --git a/tests/RollbackTest/MultiUserRollbackTest/src/com/android/tests/rollback/host/MultiUserRollbackTest.java b/tests/RollbackTest/MultiUserRollbackTest/src/com/android/tests/rollback/host/MultiUserRollbackTest.java index 42b886f0774f..f16084744853 100644 --- a/tests/RollbackTest/MultiUserRollbackTest/src/com/android/tests/rollback/host/MultiUserRollbackTest.java +++ b/tests/RollbackTest/MultiUserRollbackTest/src/com/android/tests/rollback/host/MultiUserRollbackTest.java @@ -24,6 +24,7 @@ import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -40,6 +41,9 @@ public class MultiUserRollbackTest extends BaseHostJUnit4Test { private static final long SWITCH_USER_COMPLETED_NUMBER_OF_POLLS = 60; private static final long SWITCH_USER_COMPLETED_POLL_INTERVAL_IN_MILLIS = 1000; + @Rule + public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this); + @After public void tearDown() throws Exception { removeSecondaryUserIfNecessary(); @@ -59,6 +63,30 @@ public class MultiUserRollbackTest extends BaseHostJUnit4Test { runPhaseForUsers("testBasic", mSecondaryUserId); } + /** + * Tests staged install/rollback works correctly on the 2nd user. + */ + @Test + public void testStagedRollback() throws Exception { + runPhaseForUsers("testStagedRollback_Phase1", mSecondaryUserId); + getDevice().reboot(); + + // Need to unlock the user for device tests to run successfully + getDevice().startUser(mSecondaryUserId); + awaitUserUnlocked(mSecondaryUserId); + runPhaseForUsers("testStagedRollback_Phase2", mSecondaryUserId); + getDevice().reboot(); + + getDevice().startUser(mSecondaryUserId); + awaitUserUnlocked(mSecondaryUserId); + runPhaseForUsers("testStagedRollback_Phase3", mSecondaryUserId); + getDevice().reboot(); + + getDevice().startUser(mSecondaryUserId); + awaitUserUnlocked(mSecondaryUserId); + runPhaseForUsers("testStagedRollback_Phase4", mSecondaryUserId); + } + @Test public void testMultipleUsers() throws Exception { runPhaseForUsers("testMultipleUsersInstallV1", mOriginalUserId, mSecondaryUserId); diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/MultiUserRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/MultiUserRollbackTest.java index 8641f4d4013a..5d133a4de13d 100644 --- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/MultiUserRollbackTest.java +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/MultiUserRollbackTest.java @@ -115,4 +115,32 @@ public class MultiUserRollbackTest { assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1); InstallUtils.processUserData(TestApp.A); } + + @Test + public void testStagedRollback_Phase1() throws Exception { + assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1); + Install.single(TestApp.A1).setStaged().commit(); + assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1); + } + + @Test + public void testStagedRollback_Phase2() throws Exception { + assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1); + Install.single(TestApp.A2).setStaged().setEnableRollback().commit(); + assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1); + } + + @Test + public void testStagedRollback_Phase3() throws Exception { + assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2); + RollbackInfo rollback = RollbackUtils.waitForAvailableRollback(TestApp.A); + assertThat(rollback).packagesContainsExactly(Rollback.from(TestApp.A2).to(TestApp.A1)); + RollbackUtils.rollback(rollback.getRollbackId()); + assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2); + } + + @Test + public void testStagedRollback_Phase4() { + assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1); + } } diff --git a/tests/utils/hostutils/src/com/android/tests/rollback/host/AbandonSessionsRule.java b/tests/utils/hostutils/src/com/android/tests/rollback/host/AbandonSessionsRule.java new file mode 100644 index 000000000000..5bfc75203ae3 --- /dev/null +++ b/tests/utils/hostutils/src/com/android/tests/rollback/host/AbandonSessionsRule.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 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.tests.rollback.host; + +import com.android.ddmlib.Log; +import com.android.tradefed.device.ITestDevice; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; + +import org.junit.rules.ExternalResource; + +public final class AbandonSessionsRule extends ExternalResource { + private static final String TAG = "AbandonSessionsRule"; + private final BaseHostJUnit4Test mHost; + + public AbandonSessionsRule(BaseHostJUnit4Test host) { + mHost = host; + } + + @Override + protected void before() throws Throwable { + abandonSessions(mHost.getDevice()); + } + + @Override + protected void after() { + try { + abandonSessions(mHost.getDevice()); + } catch (Exception e) { + mHost.getDevice().logOnDevice(TAG, Log.LogLevel.ERROR, + "%s", "Failed to abandon sessions"); + } + } + + /** + * Abandons all sessions to prevent interference in our tests. + */ + private static void abandonSessions(ITestDevice device) throws Exception { + // No point in abandoning applied or failed sessions. We care about ready sessions only. + String cmdListReadySessions = + "pm list staged-sessions --only-sessionid --only-parent --only-ready"; + String output = device.executeShellCommand(cmdListReadySessions); + if (output.trim().isEmpty()) { + // No sessions to abandon + return; + } + // Ensure we have sufficient privilege to abandon sessions from other apps + device.enableAdbRoot(); + device.executeShellCommand("for i in $(" + cmdListReadySessions + + "); do pm install-abandon $i; done"); + device.disableAdbRoot(); + } +} -- GitLab From 0db7d12a5ecd2cf76316527162bdf3757e5f476a Mon Sep 17 00:00:00 2001 From: Robert Snoeberger Date: Mon, 20 Jul 2020 16:55:59 -0400 Subject: [PATCH 413/536] Move call to MediaRouter2Manager to worker thread The call to MediaRouter2Manager#getRoutingSessionForMediaController was implicated in an ANR. So, moving the call to a background thread to prevent it from being caught blocking the main thread. Fixes: 161690149 Test: atest tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt Change-Id: Icf3945a971be84397a335672134b1067decfe6da (cherry picked from commit 290a624441e9c37c7638939a64ebcd1ab5a0edbe) Merged-In: Icf3945a971be84397a335672134b1067decfe6da --- .../systemui/media/MediaDeviceManager.kt | 34 +++++++++---- .../systemui/media/MediaDeviceManagerTest.kt | 48 ++++++++++++++----- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt index 143f8496e7aa..ae7f66b5ac48 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt @@ -19,8 +19,12 @@ package com.android.systemui.media import android.content.Context import android.media.MediaRouter2Manager import android.media.session.MediaController +import androidx.annotation.AnyThread +import androidx.annotation.MainThread +import androidx.annotation.WorkerThread import com.android.settingslib.media.LocalMediaManager import com.android.settingslib.media.MediaDevice +import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.Dumpable import com.android.systemui.dump.DumpManager @@ -39,11 +43,12 @@ class MediaDeviceManager @Inject constructor( private val localMediaManagerFactory: LocalMediaManagerFactory, private val mr2manager: MediaRouter2Manager, @Main private val fgExecutor: Executor, + @Background private val bgExecutor: Executor, private val mediaDataManager: MediaDataManager, private val dumpManager: DumpManager ) : MediaDataManager.Listener, Dumpable { private val listeners: MutableSet = mutableSetOf() - private val entries: MutableMap = mutableMapOf() + private val entries: MutableMap = mutableMapOf() init { mediaDataManager.addListener(this) @@ -71,7 +76,7 @@ class MediaDeviceManager @Inject constructor( val controller = data.token?.let { MediaController(context, it) } - entry = Token(key, oldKey, controller, + entry = Entry(key, oldKey, controller, localMediaManagerFactory.create(data.packageName)) entries[key] = entry entry.start() @@ -99,6 +104,7 @@ class MediaDeviceManager @Inject constructor( } } + @MainThread private fun processDevice(key: String, oldKey: String?, device: MediaDevice?) { val enabled = device != null val data = MediaDeviceData(enabled, device?.iconWithoutBackground, device?.name) @@ -114,12 +120,13 @@ class MediaDeviceManager @Inject constructor( fun onKeyRemoved(key: String) } - private inner class Token( + private inner class Entry( val key: String, val oldKey: String?, val controller: MediaController?, val localMediaManager: LocalMediaManager ) : LocalMediaManager.DeviceCallback { + val token get() = controller?.sessionToken private var started = false @@ -127,20 +134,27 @@ class MediaDeviceManager @Inject constructor( set(value) { if (!started || value != field) { field = value - processDevice(key, oldKey, value) + fgExecutor.execute { + processDevice(key, oldKey, value) + } } } - fun start() { + + @AnyThread + fun start() = bgExecutor.execute { localMediaManager.registerCallback(this) localMediaManager.startScan() updateCurrent() started = true } - fun stop() { + + @AnyThread + fun stop() = bgExecutor.execute { started = false localMediaManager.stopScan() localMediaManager.unregisterCallback(this) } + fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array) { val route = controller?.let { mr2manager.getRoutingSessionForMediaController(it) @@ -152,14 +166,18 @@ class MediaDeviceManager @Inject constructor( println(" route=$route") } } - override fun onDeviceListUpdate(devices: List?) = fgExecutor.execute { + + override fun onDeviceListUpdate(devices: List?) = bgExecutor.execute { updateCurrent() } + override fun onSelectedDeviceStateChanged(device: MediaDevice, state: Int) { - fgExecutor.execute { + bgExecutor.execute { updateCurrent() } } + + @WorkerThread private fun updateCurrent() { val device = localMediaManager.getCurrentConnectedDevice() controller?.let { diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt index 3c6e19f0ec6f..7bc15dd46cd6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt @@ -72,7 +72,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() { @Mock private lateinit var lmmFactory: LocalMediaManagerFactory @Mock private lateinit var lmm: LocalMediaManager @Mock private lateinit var mr2: MediaRouter2Manager - private lateinit var fakeExecutor: FakeExecutor + private lateinit var fakeFgExecutor: FakeExecutor + private lateinit var fakeBgExecutor: FakeExecutor @Mock private lateinit var dumpster: DumpManager @Mock private lateinit var listener: MediaDeviceManager.Listener @Mock private lateinit var device: MediaDevice @@ -87,9 +88,10 @@ public class MediaDeviceManagerTest : SysuiTestCase() { @Before fun setUp() { - fakeExecutor = FakeExecutor(FakeSystemClock()) - manager = MediaDeviceManager(context, lmmFactory, mr2, fakeExecutor, mediaDataManager, - dumpster) + fakeFgExecutor = FakeExecutor(FakeSystemClock()) + fakeBgExecutor = FakeExecutor(FakeSystemClock()) + manager = MediaDeviceManager(context, lmmFactory, mr2, fakeFgExecutor, fakeBgExecutor, + mediaDataManager, dumpster) manager.addListener(listener) // Configure mocks. @@ -144,13 +146,15 @@ public class MediaDeviceManagerTest : SysuiTestCase() { fun loadAndRemoveMediaData() { manager.onMediaDataLoaded(KEY, null, mediaData) manager.onMediaDataRemoved(KEY) + fakeBgExecutor.runAllReady() verify(lmm).unregisterCallback(any()) } @Test fun loadMediaDataWithNullToken() { manager.onMediaDataLoaded(KEY, null, mediaData.copy(token = null)) - fakeExecutor.runAllReady() + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() val data = captureDeviceData(KEY) assertThat(data.enabled).isTrue() assertThat(data.name).isEqualTo(DEVICE_NAME) @@ -163,6 +167,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() { reset(listener) // WHEN data is loaded with a new key manager.onMediaDataLoaded(KEY, KEY_OLD, mediaData) + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() // THEN the listener for the old key should removed. verify(lmm).unregisterCallback(any()) // AND a new device event emitted @@ -186,6 +192,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() { fun unknownOldKey() { val oldKey = "unknown" manager.onMediaDataLoaded(KEY, oldKey, mediaData) + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() verify(listener).onMediaDeviceChanged(eq(KEY), eq(oldKey), any()) } @@ -193,13 +201,16 @@ public class MediaDeviceManagerTest : SysuiTestCase() { fun updateToSessionTokenWithNullRoute() { // GIVEN that media data has been loaded with a null token manager.onMediaDataLoaded(KEY, null, mediaData.copy(token = null)) + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() + reset(listener) // WHEN media data is loaded with a different token // AND that token results in a null route - reset(listener) whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(null) manager.onMediaDataLoaded(KEY, null, mediaData) + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() // THEN the device should be disabled - fakeExecutor.runAllReady() val data = captureDeviceData(KEY) assertThat(data.enabled).isFalse() assertThat(data.name).isNull() @@ -210,7 +221,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() { fun deviceEventOnAddNotification() { // WHEN a notification is added manager.onMediaDataLoaded(KEY, null, mediaData) - val deviceCallback = captureCallback() + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() // THEN the update is dispatched to the listener val data = captureDeviceData(KEY) assertThat(data.enabled).isTrue() @@ -230,10 +242,12 @@ public class MediaDeviceManagerTest : SysuiTestCase() { @Test fun deviceListUpdate() { manager.onMediaDataLoaded(KEY, null, mediaData) + fakeBgExecutor.runAllReady() val deviceCallback = captureCallback() // WHEN the device list changes deviceCallback.onDeviceListUpdate(mutableListOf(device)) - assertThat(fakeExecutor.runAllReady()).isEqualTo(1) + assertThat(fakeBgExecutor.runAllReady()).isEqualTo(1) + assertThat(fakeFgExecutor.runAllReady()).isEqualTo(1) // THEN the update is dispatched to the listener val data = captureDeviceData(KEY) assertThat(data.enabled).isTrue() @@ -244,10 +258,12 @@ public class MediaDeviceManagerTest : SysuiTestCase() { @Test fun selectedDeviceStateChanged() { manager.onMediaDataLoaded(KEY, null, mediaData) + fakeBgExecutor.runAllReady() val deviceCallback = captureCallback() // WHEN the selected device changes state deviceCallback.onSelectedDeviceStateChanged(device, 1) - assertThat(fakeExecutor.runAllReady()).isEqualTo(1) + assertThat(fakeBgExecutor.runAllReady()).isEqualTo(1) + assertThat(fakeFgExecutor.runAllReady()).isEqualTo(1) // THEN the update is dispatched to the listener val data = captureDeviceData(KEY) assertThat(data.enabled).isTrue() @@ -270,6 +286,8 @@ public class MediaDeviceManagerTest : SysuiTestCase() { whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(null) // WHEN a notification is added manager.onMediaDataLoaded(KEY, null, mediaData) + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() // THEN the device is disabled val data = captureDeviceData(KEY) assertThat(data.enabled).isFalse() @@ -281,13 +299,16 @@ public class MediaDeviceManagerTest : SysuiTestCase() { fun deviceDisabledWhenMR2ReturnsNullRouteInfoOnDeviceChanged() { // GIVEN a notif is added manager.onMediaDataLoaded(KEY, null, mediaData) + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() reset(listener) // AND MR2Manager returns null for routing session whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(null) // WHEN the selected device changes state val deviceCallback = captureCallback() deviceCallback.onSelectedDeviceStateChanged(device, 1) - fakeExecutor.runAllReady() + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() // THEN the device is disabled val data = captureDeviceData(KEY) assertThat(data.enabled).isFalse() @@ -299,13 +320,16 @@ public class MediaDeviceManagerTest : SysuiTestCase() { fun deviceDisabledWhenMR2ReturnsNullRouteInfoOnDeviceListUpdate() { // GIVEN a notif is added manager.onMediaDataLoaded(KEY, null, mediaData) + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() reset(listener) // GIVEN that MR2Manager returns null for routing session whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(null) // WHEN the selected device changes state val deviceCallback = captureCallback() deviceCallback.onDeviceListUpdate(mutableListOf(device)) - fakeExecutor.runAllReady() + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() // THEN the device is disabled val data = captureDeviceData(KEY) assertThat(data.enabled).isFalse() -- GitLab From b4592687452771ec053d61946c78157f81b3c034 Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Thu, 23 Jul 2020 14:16:39 -0400 Subject: [PATCH 414/536] Add logging for swipe and timeout We weren't logging when the user swiped the carousel away, which makes it hard to tell in bugreports whether players were set to inactive because of that or something else. Bug: 158721393 Bug: 160944177 Test: manual Change-Id: Ie2205d6c369576f1f83996b2f96d040ddd328e83 (cherry picked from commit a0546c79128c97ba1fa2408073c81e0b9c076a6d) Merged-In: Ie2205d6c369576f1f83996b2f96d040ddd328e83 --- .../com/android/systemui/media/MediaDataFilter.kt | 6 ++++-- .../com/android/systemui/media/MediaDataManager.kt | 14 +++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt index 662831e4a445..24ca9708a4e3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt @@ -27,6 +27,7 @@ import javax.inject.Inject import javax.inject.Singleton private const val TAG = "MediaDataFilter" +private const val DEBUG = true /** * Filters data updates from [MediaDataCombineLatest] based on the current user ID, and handles user @@ -98,7 +99,7 @@ class MediaDataFilter @Inject constructor( // are up to date mediaEntries.clear() keyCopy.forEach { - Log.d(TAG, "Removing $it after user change") + if (DEBUG) Log.d(TAG, "Removing $it after user change") listenersCopy.forEach { listener -> listener.onMediaDataRemoved(it) } @@ -106,7 +107,7 @@ class MediaDataFilter @Inject constructor( dataSource.getData().forEach { (key, data) -> if (lockscreenUserManager.isCurrentProfile(data.userId)) { - Log.d(TAG, "Re-adding $key after user change") + if (DEBUG) Log.d(TAG, "Re-adding $key after user change") mediaEntries.put(key, data) listenersCopy.forEach { listener -> listener.onMediaDataLoaded(key, null, data) @@ -119,6 +120,7 @@ class MediaDataFilter @Inject constructor( * Invoked when the user has dismissed the media carousel */ fun onSwipeToDismiss() { + if (DEBUG) Log.d(TAG, "Media carousel swiped away") val mediaKeys = mediaEntries.keys.toSet() mediaKeys.forEach { mediaDataManager.setTimedOut(it, timedOut = true) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 7e246c803254..b85e3656eccd 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -67,6 +67,7 @@ private val ART_URIS = arrayOf( ) private const val TAG = "MediaDataManager" +private const val DEBUG = true private const val DEFAULT_LUMINOSITY = 0.25f private const val LUMINOSITY_THRESHOLD = 0.05f private const val SATURATION_MULTIPLIER = 0.8f @@ -265,7 +266,7 @@ class MediaDataManager( fun removeListener(listener: Listener) = listeners.remove(listener) /** - * Called whenever the player has been paused or stopped for a while. + * Called whenever the player has been paused or stopped for a while, or swiped from QQS. * This will make the player not active anymore, hiding it from QQS and Keyguard. * @see MediaData.active */ @@ -275,6 +276,7 @@ class MediaDataManager( return } it.active = !timedOut + if (DEBUG) Log.d(TAG, "Updating $token timedOut: $timedOut") onMediaDataLoaded(token, token, it) } } @@ -307,7 +309,9 @@ class MediaDataManager( return } - Log.d(TAG, "adding track for $userId from browser: $desc") + if (DEBUG) { + Log.d(TAG, "adding track for $userId from browser: $desc") + } // Album art var artworkBitmap = desc.iconBitmap @@ -408,7 +412,7 @@ class MediaDataManager( if (actions != null) { for ((index, action) in actions.withIndex()) { if (action.getIcon() == null) { - Log.i(TAG, "No icon for action $index ${action.title}") + if (DEBUG) Log.i(TAG, "No icon for action $index ${action.title}") actionsToShowCollapsed.remove(index) continue } @@ -455,7 +459,7 @@ class MediaDataManager( if (!TextUtils.isEmpty(uriString)) { val albumArt = loadBitmapFromUri(Uri.parse(uriString)) if (albumArt != null) { - Log.d(TAG, "loaded art from $uri") + if (DEBUG) Log.d(TAG, "loaded art from $uri") return albumArt } } @@ -546,7 +550,7 @@ class MediaDataManager( val removed = mediaEntries.remove(key) if (useMediaResumption && removed?.resumeAction != null && !isBlockedFromResume(removed?.packageName)) { - Log.d(TAG, "Not removing $key because resumable") + if (DEBUG) Log.d(TAG, "Not removing $key because resumable") // Move to resume key (aka package name) if that key doesn't already exist. val resumeAction = getResumeMediaAction(removed.resumeAction!!) val updated = removed.copy(token = null, actions = listOf(resumeAction), -- GitLab From 370971972ea81105cdbc85a2742a4c1830374bc2 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Thu, 27 Aug 2020 14:08:05 -0400 Subject: [PATCH 415/536] Reduce vertical margins in landscape add controls This makes it so we can have at least one entire control tile visible when scrolling. Test: manual Bug: 166166119 Change-Id: I7514cf8af69b4ba1d6c0bf76cdc21cd3c0719bd2 (cherry picked from commit a3a7c45f36cfa465c56d047cf8b3568760e0bda3) --- packages/SystemUI/res/layout/controls_management.xml | 5 +++-- .../res/layout/controls_management_favorites.xml | 2 +- .../SystemUI/res/layout/controls_structure_page.xml | 2 +- packages/SystemUI/res/values-land/dimens.xml | 11 +++++++++++ packages/SystemUI/res/values/dimens.xml | 4 ++++ 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/res/layout/controls_management.xml b/packages/SystemUI/res/layout/controls_management.xml index ae7f44d19430..b9e711e54b3b 100644 --- a/packages/SystemUI/res/layout/controls_management.xml +++ b/packages/SystemUI/res/layout/controls_management.xml @@ -50,7 +50,7 @@ + android:layout_height="@dimen/controls_management_footer_height"> + android:paddingHorizontal="@dimen/controls_management_footer_side_margin" + android:paddingVertical="@dimen/controls_management_footer_top_margin" >