summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp14
-rw-r--r--apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java17
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java10
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java58
-rw-r--r--api/current.txt9
-rw-r--r--api/system-current.txt6
-rw-r--r--api/test-current.txt8
-rw-r--r--cmds/statsd/src/StatsLogProcessor.h13
-rw-r--r--cmds/statsd/src/metrics/CountMetricProducer.cpp1
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.cpp2
-rw-r--r--cmds/statsd/src/metrics/GaugeMetricProducer.cpp1
-rw-r--r--core/java/android/app/ITaskStackListener.aidl7
-rw-r--r--core/java/android/app/TaskStackListener.java4
-rw-r--r--core/java/android/app/admin/DelegatedAdminReceiver.java4
-rw-r--r--core/java/android/app/admin/DeviceAdminReceiver.java4
-rw-r--r--core/java/android/app/admin/DevicePolicyManagerInternal.java14
-rw-r--r--core/java/android/app/usage/UsageStatsManager.java8
-rw-r--r--core/java/android/content/pm/AndroidTestBaseUpdater.java31
-rw-r--r--core/java/android/content/pm/PackageInstaller.java13
-rw-r--r--core/java/android/hardware/usb/UsbDevice.java24
-rw-r--r--core/java/android/net/LinkProperties.java47
-rwxr-xr-xcore/java/android/os/Build.java3
-rw-r--r--core/java/android/os/HwParcel.java52
-rw-r--r--core/java/android/os/OWNERS2
-rw-r--r--core/java/android/os/Parcel.java6
-rw-r--r--core/java/android/os/Process.java5
-rw-r--r--core/java/android/os/UpdateEngine.java8
-rw-r--r--core/java/android/os/UserHandle.java59
-rw-r--r--core/java/android/text/TextUtils.java11
-rw-r--r--core/java/android/text/style/AccessibilityReplacementSpan.java100
-rw-r--r--core/java/android/text/style/ReplacementSpan.java23
-rw-r--r--core/java/android/util/ArraySet.java13
-rw-r--r--core/java/android/util/FeatureFlagUtils.java1
-rw-r--r--core/java/android/util/OWNERS2
-rw-r--r--core/java/android/util/StatsEvent.java331
-rw-r--r--core/java/android/view/ViewGroup.java10
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java101
-rw-r--r--core/java/android/widget/AbsListView.java3
-rw-r--r--core/java/com/android/internal/app/ResolverListController.java8
-rw-r--r--core/jni/android_os_Parcel.cpp6
-rw-r--r--core/jni/android_util_Binder.cpp3
-rw-r--r--core/jni/android_util_Process.cpp67
-rw-r--r--core/res/res/values/attrs_manifest.xml8
-rw-r--r--core/res/res/values/config.xml8
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/coretests/src/android/view/ViewGroupTest.java71
-rw-r--r--core/tests/featureflagtests/OWNERS2
-rw-r--r--keystore/java/android/security/KeyChain.java10
-rw-r--r--libs/hwui/renderthread/CacheManager.cpp2
-rw-r--r--mms/OWNERS14
-rw-r--r--mms/java/android/telephony/MmsManager.java (renamed from telephony/java/android/telephony/MmsManager.java)0
-rw-r--r--mms/java/com/android/internal/telephony/IMms.aidl (renamed from telephony/java/com/android/internal/telephony/IMms.aidl)0
-rw-r--r--packages/CarSystemUI/res/layout/super_status_bar.xml2
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java9
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java5
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java5
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml12
-rw-r--r--packages/SystemUI/res/layout/super_status_bar.xml2
-rw-r--r--packages/SystemUI/res/values/ids.xml3
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java4
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java13
-rw-r--r--packages/SystemUI/src/com/android/keyguard/CarrierTextController.java6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java3
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java54
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java384
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java543
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java108
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java80
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java16
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java73
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java4
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java2
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java12
-rw-r--r--services/core/java/com/android/server/integrity/model/AppInstallMetadata.java155
-rw-r--r--services/core/java/com/android/server/integrity/model/AtomicFormula.java136
-rw-r--r--services/core/java/com/android/server/integrity/model/Formula.java24
-rw-r--r--services/core/java/com/android/server/integrity/model/OpenFormula.java79
-rw-r--r--services/core/java/com/android/server/integrity/model/Rule.java100
-rw-r--r--services/core/java/com/android/server/notification/GroupHelper.java53
-rw-r--r--services/core/java/com/android/server/notification/ManagedServices.java2
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java64
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java29
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java10
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java3
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java35
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java7
-rw-r--r--services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java2
-rw-r--r--services/core/java/com/android/server/slice/SliceManagerService.java9
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java24
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java28
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java20
-rw-r--r--services/core/java/com/android/server/wm/ActivityStartInterceptor.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java16
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java4
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java39
-rw-r--r--services/core/java/com/android/server/wm/DockedStackDividerController.java17
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java81
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java7
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java15
-rw-r--r--services/core/java/com/android/server/wm/LaunchParamsPersister.java4
-rw-r--r--services/core/java/com/android/server/wm/LockTaskController.java16
-rw-r--r--services/core/java/com/android/server/wm/RecentTasks.java66
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimation.java2
-rw-r--r--services/core/java/com/android/server/wm/RootActivityContainer.java12
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java6
-rw-r--r--services/core/java/com/android/server/wm/Task.java29
-rw-r--r--services/core/java/com/android/server/wm/TaskChangeNotificationController.java18
-rw-r--r--services/core/java/com/android/server/wm/TaskPersister.java16
-rw-r--r--services/core/java/com/android/server/wm/TaskRecord.java269
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java21
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java18
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java120
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java6
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java22
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java20
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java50
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java24
-rw-r--r--services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java100
-rw-r--r--services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java64
-rw-r--r--services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java5
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java192
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java73
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java26
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java20
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java3
-rw-r--r--telephony/common/com/android/internal/telephony/HbpcdLookup.java124
-rw-r--r--telephony/common/com/android/internal/telephony/HbpcdUtils.java163
-rw-r--r--telephony/common/com/android/internal/telephony/SmsNumberUtils.java627
-rw-r--r--telephony/java/android/provider/Telephony.java13
-rw-r--r--telephony/java/android/telephony/ServiceState.java9
-rw-r--r--telephony/java/android/telephony/SmsCbMessage.java26
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java13
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java72
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/SmsMessage.java5
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java9
-rwxr-xr-xtests/Codegen/runTest.sh3
-rw-r--r--tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java6
-rw-r--r--tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java6
-rw-r--r--tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java6
-rw-r--r--tests/Codegen/src/com/android/codegentest/SampleDataClass.java6
-rw-r--r--tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java6
-rw-r--r--tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java71
-rw-r--r--tests/net/common/java/android/net/LinkPropertiesTest.java14
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java25
-rw-r--r--tools/codegen/src/com/android/codegen/SharedConstants.kt2
-rw-r--r--tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt5
173 files changed, 4778 insertions, 1429 deletions
diff --git a/Android.bp b/Android.bp
index 594126fcc157..a1061681358f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -170,6 +170,15 @@ filegroup {
}
filegroup {
+ name: "framework-mms-sources",
+ srcs: [
+ "mms/java/**/*.java",
+ "mms/java/**/*.aidl",
+ ],
+ path: "mms/java",
+}
+
+filegroup {
name: "framework-wifi-sources",
srcs: [
"wifi/java/**/*.java",
@@ -193,6 +202,7 @@ filegroup {
":framework-mca-filterfw-sources",
":framework-mca-filterpacks-sources",
":framework-mime-sources",
+ ":framework-mms-sources",
":framework-opengl-sources",
":framework-rs-sources",
":framework-sax-sources",
@@ -252,6 +262,7 @@ java_defaults {
"media/mca/effect/java",
"media/mca/filterfw/java",
"media/mca/filterpacks/java",
+ "mms/java",
"opengl/java",
"rs/java",
"sax/java",
@@ -415,7 +426,7 @@ java_library {
java_library {
name: "framework-annotation-proc",
- defaults: ["framework-defaults"],
+ defaults: ["framework-aidl-export-defaults"],
srcs: [":framework-all-sources"],
installable: false,
plugins: [
@@ -820,6 +831,7 @@ frameworks_base_subdirs = [
"media/mca/filterfw/java",
"media/mca/filterpacks/java",
"drm/java",
+ "mms/java",
"opengl/java",
"sax/java",
"telecomm/java",
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 65aaf20ecacb..d6661c2c8616 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -1684,7 +1684,7 @@ public class DeviceIdleController extends SystemService
static class Injector {
private final Context mContext;
- private ConnectivityService mConnectivityService;
+ private ConnectivityManager mConnectivityManager;
private Constants mConstants;
private LocationManager mLocationManager;
@@ -1705,12 +1705,11 @@ public class DeviceIdleController extends SystemService
return new AppStateTracker(ctx, looper);
}
- ConnectivityService getConnectivityService() {
- if (mConnectivityService == null) {
- mConnectivityService = (ConnectivityService) ServiceManager.getService(
- Context.CONNECTIVITY_SERVICE);
+ ConnectivityManager getConnectivityManager() {
+ if (mConnectivityManager == null) {
+ mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
}
- return mConnectivityService;
+ return mConnectivityManager;
}
Constants getConstants(DeviceIdleController controller, Handler handler,
@@ -1909,7 +1908,7 @@ public class DeviceIdleController extends SystemService
if (getContext().getResources().getBoolean(
com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
- mLocationRequest = new LocationRequest()
+ mLocationRequest = LocationRequest.create()
.setQuality(LocationRequest.ACCURACY_FINE)
.setInterval(0)
.setFastestInterval(0)
@@ -2497,9 +2496,9 @@ public class DeviceIdleController extends SystemService
}
void updateConnectivityState(Intent connIntent) {
- ConnectivityService cm;
+ ConnectivityManager cm;
synchronized (this) {
- cm = mInjector.getConnectivityService();
+ cm = mInjector.getConnectivityManager();
}
if (cm == null) {
return;
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index 43e8dfb6bab6..7d3630338fc1 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -34,6 +34,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.UserHandle;
import android.text.format.DateUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DataUnit;
import android.util.Log;
@@ -441,7 +442,7 @@ public final class ConnectivityController extends StateController implements
synchronized (mLock) {
// Since this is a really hot codepath, temporarily cache any
// answers that we get from ConnectivityManager.
- final SparseArray<NetworkCapabilities> networkToCapabilities = new SparseArray<>();
+ final ArrayMap<Network, NetworkCapabilities> networkToCapabilities = new ArrayMap<>();
boolean changed = false;
if (filterUid == -1) {
@@ -460,17 +461,16 @@ public final class ConnectivityController extends StateController implements
}
private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork,
- SparseArray<NetworkCapabilities> networkToCapabilities) {
+ ArrayMap<Network, NetworkCapabilities> networkToCapabilities) {
if (jobs == null || jobs.size() == 0) {
return false;
}
final Network network = mConnManager.getActiveNetworkForUid(jobs.valueAt(0).getSourceUid());
- final int netId = network != null ? network.netId : -1;
- NetworkCapabilities capabilities = networkToCapabilities.get(netId);
+ NetworkCapabilities capabilities = networkToCapabilities.get(network);
if (capabilities == null) {
capabilities = mConnManager.getNetworkCapabilities(network);
- networkToCapabilities.put(netId, capabilities);
+ networkToCapabilities.put(network, capabilities);
}
final boolean networkMatch = (filterNetwork == null
|| Objects.equals(filterNetwork, network));
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index df5d6aeb8ee5..7c472a9813aa 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -872,64 +872,66 @@ public class AppStandbyController implements AppStandbyInternal {
public void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId) {
if (!mAppIdleEnabled) return;
synchronized (mAppIdleLock) {
+ final String pkg = event.getPackageName();
+ final int eventType = event.getEventType();
// TODO: Ideally this should call isAppIdleFiltered() to avoid calling back
// about apps that are on some kind of whitelist anyway.
final boolean previouslyIdle = mAppIdleHistory.isIdle(
- event.mPackage, userId, elapsedRealtime);
+ pkg, userId, elapsedRealtime);
// Inform listeners if necessary
- if ((event.mEventType == UsageEvents.Event.ACTIVITY_RESUMED
- || event.mEventType == UsageEvents.Event.ACTIVITY_PAUSED
- || event.mEventType == UsageEvents.Event.SYSTEM_INTERACTION
- || event.mEventType == UsageEvents.Event.USER_INTERACTION
- || event.mEventType == UsageEvents.Event.NOTIFICATION_SEEN
- || event.mEventType == UsageEvents.Event.SLICE_PINNED
- || event.mEventType == UsageEvents.Event.SLICE_PINNED_PRIV
- || event.mEventType == UsageEvents.Event.FOREGROUND_SERVICE_START)) {
+ if ((eventType == UsageEvents.Event.ACTIVITY_RESUMED
+ || eventType == UsageEvents.Event.ACTIVITY_PAUSED
+ || eventType == UsageEvents.Event.SYSTEM_INTERACTION
+ || eventType == UsageEvents.Event.USER_INTERACTION
+ || eventType == UsageEvents.Event.NOTIFICATION_SEEN
+ || eventType == UsageEvents.Event.SLICE_PINNED
+ || eventType == UsageEvents.Event.SLICE_PINNED_PRIV
+ || eventType == UsageEvents.Event.FOREGROUND_SERVICE_START)) {
final AppUsageHistory appHistory = mAppIdleHistory.getAppUsageHistory(
- event.mPackage, userId, elapsedRealtime);
+ pkg, userId, elapsedRealtime);
final int prevBucket = appHistory.currentBucket;
final int prevBucketReason = appHistory.bucketingReason;
final long nextCheckTime;
- final int subReason = usageEventToSubReason(event.mEventType);
+ final int subReason = usageEventToSubReason(eventType);
final int reason = REASON_MAIN_USAGE | subReason;
- if (event.mEventType == UsageEvents.Event.NOTIFICATION_SEEN
- || event.mEventType == UsageEvents.Event.SLICE_PINNED) {
+ if (eventType == UsageEvents.Event.NOTIFICATION_SEEN
+ || eventType == UsageEvents.Event.SLICE_PINNED) {
// Mild usage elevates to WORKING_SET but doesn't change usage time.
- mAppIdleHistory.reportUsage(appHistory, event.mPackage,
+ mAppIdleHistory.reportUsage(appHistory, pkg,
STANDBY_BUCKET_WORKING_SET, subReason,
0, elapsedRealtime + mNotificationSeenTimeoutMillis);
nextCheckTime = mNotificationSeenTimeoutMillis;
- } else if (event.mEventType == UsageEvents.Event.SYSTEM_INTERACTION) {
- mAppIdleHistory.reportUsage(appHistory, event.mPackage,
+ } else if (eventType == UsageEvents.Event.SYSTEM_INTERACTION) {
+ mAppIdleHistory.reportUsage(appHistory, pkg,
STANDBY_BUCKET_ACTIVE, subReason,
0, elapsedRealtime + mSystemInteractionTimeoutMillis);
nextCheckTime = mSystemInteractionTimeoutMillis;
- } else if (event.mEventType == UsageEvents.Event.FOREGROUND_SERVICE_START) {
+ } else if (eventType == UsageEvents.Event.FOREGROUND_SERVICE_START) {
// Only elevate bucket if this is the first usage of the app
if (prevBucket != STANDBY_BUCKET_NEVER) return;
- mAppIdleHistory.reportUsage(appHistory, event.mPackage,
+ mAppIdleHistory.reportUsage(appHistory, pkg,
STANDBY_BUCKET_ACTIVE, subReason,
0, elapsedRealtime + mInitialForegroundServiceStartTimeoutMillis);
nextCheckTime = mInitialForegroundServiceStartTimeoutMillis;
} else {
- mAppIdleHistory.reportUsage(appHistory, event.mPackage,
+ mAppIdleHistory.reportUsage(appHistory, pkg,
STANDBY_BUCKET_ACTIVE, subReason,
elapsedRealtime, elapsedRealtime + mStrongUsageTimeoutMillis);
nextCheckTime = mStrongUsageTimeoutMillis;
}
mHandler.sendMessageDelayed(mHandler.obtainMessage
- (MSG_CHECK_PACKAGE_IDLE_STATE, userId, -1, event.mPackage),
+ (MSG_CHECK_PACKAGE_IDLE_STATE, userId, -1, pkg),
nextCheckTime);
final boolean userStartedInteracting =
appHistory.currentBucket == STANDBY_BUCKET_ACTIVE &&
prevBucket != appHistory.currentBucket &&
(prevBucketReason & REASON_MAIN_MASK) != REASON_MAIN_USAGE;
- maybeInformListeners(event.mPackage, userId, elapsedRealtime,
+ maybeInformListeners(pkg, userId, elapsedRealtime,
appHistory.currentBucket, reason, userStartedInteracting);
if (previouslyIdle) {
- notifyBatteryStats(event.mPackage, userId, false);
+ notifyBatteryStats(pkg, userId, false);
}
}
}
@@ -1849,16 +1851,6 @@ public class AppStandbyController implements AppStandbyInternal {
* Observe settings changes for {@link Global#APP_IDLE_CONSTANTS}.
*/
private class SettingsObserver extends ContentObserver {
- /**
- * This flag has been used to disable app idle on older builds with bug b/26355386.
- */
- @Deprecated
- private static final String KEY_IDLE_DURATION_OLD = "idle_duration";
- @Deprecated
- private static final String KEY_IDLE_DURATION = "idle_duration2";
- @Deprecated
- private static final String KEY_WALLCLOCK_THRESHOLD = "wallclock_threshold";
-
private static final String KEY_PAROLE_INTERVAL = "parole_interval";
private static final String KEY_PAROLE_WINDOW = "parole_window";
private static final String KEY_PAROLE_DURATION = "parole_duration";
@@ -1993,7 +1985,7 @@ public class AppStandbyController implements AppStandbyInternal {
: DEFAULT_EXEMPTED_SYNC_START_TIMEOUT);
mUnexemptedSyncScheduledTimeoutMillis = mParser.getDurationMillis(
- KEY_EXEMPTED_SYNC_SCHEDULED_DOZE_HOLD_DURATION,
+ KEY_UNEXEMPTED_SYNC_SCHEDULED_HOLD_DURATION,
COMPRESS_TIME ? ONE_MINUTE
: DEFAULT_UNEXEMPTED_SYNC_SCHEDULED_TIMEOUT); // TODO
diff --git a/api/current.txt b/api/current.txt
index bba193873630..3a768ea98eb2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -28809,6 +28809,7 @@ package android.net {
method @Nullable public String getPrivateDnsServerName();
method @NonNull public java.util.List<android.net.RouteInfo> getRoutes();
method public boolean isPrivateDnsActive();
+ method public boolean isWakeOnLanSupported();
method public void setDnsServers(@NonNull java.util.Collection<java.net.InetAddress>);
method public void setDomains(@Nullable String);
method public void setHttpProxy(@Nullable android.net.ProxyInfo);
@@ -40804,6 +40805,7 @@ package android.security {
field public static final String EXTRA_KEY_ALIAS = "android.security.extra.KEY_ALIAS";
field public static final String EXTRA_NAME = "name";
field public static final String EXTRA_PKCS12 = "PKCS12";
+ field public static final String KEY_ALIAS_SELECTION_DENIED = "alias-selection-denied-ef829e15-210a-409d-96c9-ee684fc41972";
}
public interface KeyChainAliasCallback {
@@ -45109,7 +45111,7 @@ package android.telephony {
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid(int);
method public String getMmsUAProfUrl();
method public String getMmsUserAgent();
- method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getNai();
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getNai();
method public String getNetworkCountryIso();
method public String getNetworkOperator();
method public String getNetworkOperatorName();
@@ -45182,6 +45184,7 @@ package android.telephony {
method public void updateAvailableNetworks(@NonNull java.util.List<android.telephony.AvailableNetworkInfo>, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
field public static final String ACTION_CARRIER_MESSAGING_CLIENT_SERVICE = "android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE";
field public static final String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
+ field public static final String ACTION_MULTI_SIM_CONFIG_CHANGED = "android.telephony.action.MULTI_SIM_CONFIG_CHANGED";
field public static final String ACTION_NETWORK_COUNTRY_CHANGED = "android.telephony.action.NETWORK_COUNTRY_CHANGED";
field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
field public static final String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -45222,6 +45225,7 @@ package android.telephony {
field public static final String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT";
field public static final String EXTRA_NETWORK_COUNTRY = "android.telephony.extra.NETWORK_COUNTRY";
field public static final String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT";
+ field public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED = "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED";
field public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telephony.extra.PHONE_ACCOUNT_HANDLE";
field public static final String EXTRA_SPECIFIC_CARRIER_ID = "android.telephony.extra.SPECIFIC_CARRIER_ID";
field public static final String EXTRA_SPECIFIC_CARRIER_NAME = "android.telephony.extra.SPECIFIC_CARRIER_NAME";
@@ -47133,7 +47137,9 @@ package android.text.style {
public abstract class ReplacementSpan extends android.text.style.MetricAffectingSpan {
ctor public ReplacementSpan();
method public abstract void draw(@NonNull android.graphics.Canvas, CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, float, int, int, int, @NonNull android.graphics.Paint);
+ method @Nullable public CharSequence getContentDescription();
method public abstract int getSize(@NonNull android.graphics.Paint, CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @Nullable android.graphics.Paint.FontMetricsInt);
+ method public void setContentDescription(@Nullable CharSequence);
method public void updateDrawState(android.text.TextPaint);
method public void updateMeasureState(android.text.TextPaint);
}
@@ -47907,6 +47913,7 @@ package android.util {
ctor public ArraySet(int);
ctor public ArraySet(android.util.ArraySet<E>);
ctor public ArraySet(java.util.Collection<? extends E>);
+ ctor public ArraySet(@Nullable E[]);
method public boolean add(E);
method public void addAll(android.util.ArraySet<? extends E>);
method public boolean addAll(java.util.Collection<? extends E>);
diff --git a/api/system-current.txt b/api/system-current.txt
index 696801a28882..8ed79a3f2338 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5520,7 +5520,7 @@ package android.os {
public class UpdateEngine {
ctor public UpdateEngine();
method public void applyPayload(String, long, long, String[]);
- method public void applyPayload(@NonNull java.io.FileDescriptor, long, long, @NonNull String[]);
+ method public void applyPayload(@NonNull android.os.ParcelFileDescriptor, long, long, @NonNull String[]);
method public boolean bind(android.os.UpdateEngineCallback, android.os.Handler);
method public boolean bind(android.os.UpdateEngineCallback);
method public void cancel();
@@ -8114,7 +8114,7 @@ package android.telephony {
}
public final class SmsCbMessage implements android.os.Parcelable {
- ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo);
+ ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int);
method @NonNull public static android.telephony.SmsCbMessage createFromCursor(@NonNull android.database.Cursor);
method public int describeContents();
method @Nullable public android.telephony.SmsCbCmasInfo getCmasWarningInfo();
@@ -8129,6 +8129,7 @@ package android.telephony {
method public long getReceivedTime();
method public int getSerialNumber();
method public int getServiceCategory();
+ method public int getSlotIndex();
method public boolean isCmasMessage();
method public boolean isEmergencyMessage();
method public boolean isEtwsMessage();
@@ -8276,6 +8277,7 @@ package android.telephony {
method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int);
method public boolean isDataConnectivityPossible();
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
diff --git a/api/test-current.txt b/api/test-current.txt
index d709886eff66..70837a84adfd 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2034,10 +2034,18 @@ package android.os {
public final class UserHandle implements android.os.Parcelable {
method public static int getAppId(int);
method public int getIdentifier();
+ method public static int getUid(int, int);
+ method public static int getUserId(int);
method public static boolean isApp(int);
+ method public static int myUserId();
+ method public static android.os.UserHandle of(int);
field @NonNull public static final android.os.UserHandle ALL;
field @NonNull public static final android.os.UserHandle CURRENT;
+ field public static final int MIN_SECONDARY_USER_ID = 10; // 0xa
field @NonNull public static final android.os.UserHandle SYSTEM;
+ field public static final int USER_ALL = -1; // 0xffffffff
+ field public static final int USER_NULL = -10000; // 0xffffd8f0
+ field public static final int USER_SYSTEM = 0; // 0x0
}
public class UserManager {
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index f0db1b0128a1..3d002d2efdd0 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -248,19 +248,6 @@ private:
FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
- FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_Link_OR_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_OR_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_OR_CombinationCondition);
-
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_SimpleCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition);
-
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationCondition);
-
FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 23d025f82c26..1d0d2fb70a9d 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -251,6 +251,7 @@ bool CountMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
ALOGE("CountMetric %lld dropping data for dimension key %s",
(long long)mMetricId, newKey.toString().c_str());
+ StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
return true;
}
}
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index cca793b2146a..d7b46d1858cc 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -491,6 +491,7 @@ bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey
if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
ALOGE("DurationMetric %lld dropping data for condition dimension key %s",
(long long)mMetricId, newKey.getDimensionKeyInCondition().toString().c_str());
+ StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
return true;
}
}
@@ -504,6 +505,7 @@ bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey
if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
ALOGE("DurationMetric %lld dropping data for what dimension key %s",
(long long)mMetricId, newKey.getDimensionKeyInWhat().toString().c_str());
+ StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
return true;
}
}
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 1f423cd384ef..efd05dcb04f1 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -439,6 +439,7 @@ bool GaugeMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
if (newTupleCount > mDimensionHardLimit) {
ALOGE("GaugeMetric %lld dropping data for dimension key %s",
(long long)mMetricId, newKey.toString().c_str());
+ StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
return true;
}
}
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 750020eb5bb8..0ba1989e681c 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -197,4 +197,11 @@ oneway interface ITaskStackListener {
* Called when any additions or deletions to the recent tasks list have been made.
*/
void onRecentTaskListUpdated();
+
+ /**
+ * Called when Recent Tasks list is frozen or unfrozen.
+ *
+ * @param frozen if true, Recents Tasks list is currently frozen, false otherwise
+ */
+ void onRecentTaskListFrozenChanged(boolean frozen);
}
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 46045faecbd4..f21aaf3867fd 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -190,4 +190,8 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
@Override
public void onRecentTaskListUpdated() throws RemoteException {
}
+
+ @Override
+ public void onRecentTaskListFrozenChanged(boolean frozen) {
+ }
}
diff --git a/core/java/android/app/admin/DelegatedAdminReceiver.java b/core/java/android/app/admin/DelegatedAdminReceiver.java
index f66de8d238ed..25b8eab452bf 100644
--- a/core/java/android/app/admin/DelegatedAdminReceiver.java
+++ b/core/java/android/app/admin/DelegatedAdminReceiver.java
@@ -63,6 +63,10 @@ public class DelegatedAdminReceiver extends BroadcastReceiver {
* Allows this receiver to select the alias for a private key and certificate pair for
* authentication. If this method returns null, the default {@link android.app.Activity} will
* be shown that lets the user pick a private key and certificate pair.
+ * If this method returns {@link KeyChain#KEY_ALIAS_SELECTION_DENIED},
+ * the default {@link android.app.Activity} will not be shown and the user will not be allowed
+ * to pick anything. And the app, that called {@link KeyChain#choosePrivateKeyAlias}, will
+ * receive {@code null} back.
*
* <p> This callback is only applicable if the delegated app has
* {@link DevicePolicyManager#DELEGATION_CERT_SELECTION} capability. Additionally, it must
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 0c500da0294a..d175a66e90ea 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -791,6 +791,10 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
* Allows this receiver to select the alias for a private key and certificate pair for
* authentication. If this method returns null, the default {@link android.app.Activity} will be
* shown that lets the user pick a private key and certificate pair.
+ * If this method returns {@link KeyChain#KEY_ALIAS_SELECTION_DENIED},
+ * the default {@link android.app.Activity} will not be shown and the user will not be allowed
+ * to pick anything. And the app, that called {@link KeyChain#choosePrivateKeyAlias}, will
+ * receive {@code null} back.
*
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index b873be3e7042..713126ee9341 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -24,6 +24,10 @@ import java.util.List;
/**
* Device policy manager local system service interface.
*
+ * Maintenance note: if you need to expose information from DPMS to lower level services such as
+ * PM/UM/AM/etc, then exposing it from DevicePolicyManagerInternal is not safe because it may cause
+ * lock order inversion. Consider using {@link DevicePolicyCache} instead.
+ *
* @hide Only for use within the system server.
*/
public abstract class DevicePolicyManagerInternal {
@@ -81,6 +85,16 @@ public abstract class DevicePolicyManagerInternal {
public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy);
/**
+ * Checks if an app with given uid is the active supervision admin.
+ *
+ * <p>This takes the DPMS lock. DO NOT call from PM/UM/AM with their lock held.
+ *
+ * @param uid App uid.
+ * @return true if the uid is the active supervision app.
+ */
+ public abstract boolean isActiveSupervisionApp(int uid);
+
+ /**
* Creates an intent to show the admin support dialog to say that an action is disallowed by
* the device/profile owner.
*
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 656f474f72ce..1f13a1e13d13 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -801,8 +801,8 @@ public final class UsageStatsManager {
* {@link #EXTRA_TIME_USED}. Cannot be {@code null} unless the observer is
* being registered with a {@code timeUsed} equal to or greater than
* {@code timeLimit}.
- * @throws SecurityException if the caller doesn't have both SUSPEND_APPS and OBSERVE_APP_USAGE
- * permissions.
+ * @throws SecurityException if the caller is neither the active supervision app nor does it
+ * have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions.
* @hide
*/
@SystemApi
@@ -827,8 +827,8 @@ public final class UsageStatsManager {
* an observer that was already unregistered or never registered will have no effect.
*
* @param observerId The id of the observer that was previously registered.
- * @throws SecurityException if the caller doesn't have both SUSPEND_APPS and OBSERVE_APP_USAGE
- * permissions.
+ * @throws SecurityException if the caller is neither the active supervision app nor does it
+ * have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions.
* @hide
*/
@SystemApi
diff --git a/core/java/android/content/pm/AndroidTestBaseUpdater.java b/core/java/android/content/pm/AndroidTestBaseUpdater.java
index da1a693b13c3..8fcfe711a882 100644
--- a/core/java/android/content/pm/AndroidTestBaseUpdater.java
+++ b/core/java/android/content/pm/AndroidTestBaseUpdater.java
@@ -18,10 +18,17 @@ package android.content.pm;
import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE;
import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
+import android.content.Context;
import android.content.pm.PackageParser.Package;
import android.os.Build;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.compat.IPlatformCompat;
/**
* Updates a package to ensure that if it targets <= Q that the android.test.base library is
@@ -37,10 +44,26 @@ import com.android.internal.annotations.VisibleForTesting;
*/
@VisibleForTesting
public class AndroidTestBaseUpdater extends PackageSharedLibraryUpdater {
+ private static final String TAG = "AndroidTestBaseUpdater";
- private static boolean apkTargetsApiLevelLessThanOrEqualToQ(Package pkg) {
- int targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
- return targetSdkVersion <= Build.VERSION_CODES.Q;
+ /**
+ * Remove android.test.base library for apps that target SDK R or more and do not depend on
+ * android.test.runner (as it depends on classes from the android.test.base library).
+ */
+ @ChangeId
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
+ private static final long REMOVE_ANDROID_TEST_BASE = 133396946L;
+
+ private static boolean isChangeEnabled(Package pkg) {
+ IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
+ ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+ try {
+ return platformCompat.isChangeEnabled(REMOVE_ANDROID_TEST_BASE, pkg.applicationInfo);
+ } catch (RemoteException | NullPointerException e) {
+ Log.e(TAG, "Failed to get a response from PLATFORM_COMPAT_SERVICE", e);
+ }
+ // Fall back to previous behaviour.
+ return pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.Q;
}
@Override
@@ -48,7 +71,7 @@ public class AndroidTestBaseUpdater extends PackageSharedLibraryUpdater {
// Packages targeted at <= Q expect the classes in the android.test.base library
// to be accessible so this maintains backward compatibility by adding the
// android.test.base library to those packages.
- if (apkTargetsApiLevelLessThanOrEqualToQ(pkg)) {
+ if (!isChangeEnabled(pkg)) {
prefixRequiredLibrary(pkg, ANDROID_TEST_BASE);
} else {
// If a package already depends on android.test.runner then add a dependency on
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 1099d8bdc7dd..69ce3bd55071 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -101,19 +101,6 @@ import java.util.concurrent.Executor;
* <p>
* The ApiDemos project contains examples of using this API:
* <code>ApiDemos/src/com/example/android/apis/content/InstallApk*.java</code>.
- * <p>
- * On Android Q or above, an app installed notification will be posted
- * by system after a new app is installed.
- * To customize installer's notification icon, you should declare the following in the manifest
- * &lt;application> as follows: </p>
- * <pre>
- * &lt;meta-data android:name="com.android.packageinstaller.notification.smallIcon"
- * android:resource="@drawable/installer_notification_icon"/>
- * </pre>
- * <pre>
- * &lt;meta-data android:name="com.android.packageinstaller.notification.color"
- * android:resource="@color/installer_notification_color"/>
- * </pre>
*/
public class PackageInstaller {
private static final String TAG = "PackageInstaller";
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index 43336682e45f..11f4ffb4c225 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -62,7 +62,7 @@ public class UsbDevice implements Parcelable {
private final int mProtocol;
private final boolean mHasAudioPlayback;
private final boolean mHasAudioCapture;
-
+ private final boolean mHasMidi;
/** All interfaces on the device. Initialized on first call to getInterfaceList */
@UnsupportedAppUsage
@@ -77,7 +77,7 @@ public class UsbDevice implements Parcelable {
int protocol, @Nullable String manufacturerName, @Nullable String productName,
@NonNull String version, @NonNull UsbConfiguration[] configurations,
@NonNull IUsbSerialReader serialNumberReader,
- boolean hasAudioPlayback, boolean hasAudioCapture) {
+ boolean hasAudioPlayback, boolean hasAudioCapture, boolean hasMidi) {
mName = Preconditions.checkNotNull(name);
mVendorId = vendorId;
mProductId = productId;
@@ -91,6 +91,7 @@ public class UsbDevice implements Parcelable {
mSerialNumberReader = Preconditions.checkNotNull(serialNumberReader);
mHasAudioPlayback = hasAudioPlayback;
mHasAudioCapture = hasAudioCapture;
+ mHasMidi = hasMidi;
// Make sure the binder belongs to the system
if (ActivityThread.isSystem()) {
@@ -230,6 +231,11 @@ public class UsbDevice implements Parcelable {
return mHasAudioCapture;
}
+ /** @hide */
+ public boolean getHasMidi() {
+ return mHasMidi;
+ }
+
/**
* Returns the {@link UsbConfiguration} at the given index.
*
@@ -309,6 +315,7 @@ public class UsbDevice implements Parcelable {
+ ",mVersion=" + mVersion + ",mSerialNumberReader=" + mSerialNumberReader
+ ", mHasAudioPlayback=" + mHasAudioPlayback
+ ", mHasAudioCapture=" + mHasAudioCapture
+ + ", mHasMidi=" + mHasMidi
+ ", mConfigurations=[");
for (int i = 0; i < mConfigurations.length; i++) {
builder.append("\n");
@@ -337,9 +344,11 @@ public class UsbDevice implements Parcelable {
// Capabilities
boolean hasAudioPlayback = in.readInt() == 1;
boolean hasAudioCapture = in.readInt() == 1;
+ boolean hasMidi = in.readInt() == 1;
+
UsbDevice device = new UsbDevice(name, vendorId, productId, clasz, subClass, protocol,
manufacturerName, productName, version, configurations, serialNumberReader,
- hasAudioPlayback, hasAudioCapture);
+ hasAudioPlayback, hasAudioCapture, hasMidi);
return device;
}
@@ -367,7 +376,8 @@ public class UsbDevice implements Parcelable {
parcel.writeParcelableArray(mConfigurations, 0);
parcel.writeInt(mHasAudioPlayback ? 1 : 0);
parcel.writeInt(mHasAudioCapture ? 1 : 0);
- }
+ parcel.writeInt(mHasMidi ? 1 : 0);
+ }
public static int getDeviceId(String name) {
return native_get_device_id(name);
@@ -396,6 +406,7 @@ public class UsbDevice implements Parcelable {
private final @NonNull UsbConfiguration[] mConfigurations;
private final boolean mHasAudioPlayback;
private final boolean mHasAudioCapture;
+ private final boolean mHasMidi;
// Temporary storage for serial number. Serial number reader need to be wrapped in a
// IUsbSerialReader as they might be used as PII.
@@ -405,7 +416,7 @@ public class UsbDevice implements Parcelable {
int protocol, @Nullable String manufacturerName, @Nullable String productName,
@NonNull String version, @NonNull UsbConfiguration[] configurations,
@Nullable String serialNumber,
- boolean hasAudioPlayback, boolean hasAudioCapture) {
+ boolean hasAudioPlayback, boolean hasAudioCapture, boolean hasMidi) {
mName = Preconditions.checkNotNull(name);
mVendorId = vendorId;
mProductId = productId;
@@ -419,6 +430,7 @@ public class UsbDevice implements Parcelable {
this.serialNumber = serialNumber;
mHasAudioPlayback = hasAudioPlayback;
mHasAudioCapture = hasAudioCapture;
+ mHasMidi = hasMidi;
}
/**
@@ -431,7 +443,7 @@ public class UsbDevice implements Parcelable {
public UsbDevice build(@NonNull IUsbSerialReader serialReader) {
return new UsbDevice(mName, mVendorId, mProductId, mClass, mSubclass, mProtocol,
mManufacturerName, mProductName, mVersion, mConfigurations, serialReader,
- mHasAudioPlayback, mHasAudioCapture);
+ mHasAudioPlayback, mHasAudioCapture, mHasMidi);
}
}
}
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index d3f48acdd40e..3ec0aeac472b 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -68,6 +68,7 @@ public final class LinkProperties implements Parcelable {
// in the format "rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
private String mTcpBufferSizes;
private IpPrefix mNat64Prefix;
+ private boolean mWakeOnLanSupported;
private static final int MIN_MTU = 68;
private static final int MIN_MTU_V6 = 1280;
@@ -193,6 +194,7 @@ public final class LinkProperties implements Parcelable {
setMtu(source.mMtu);
mTcpBufferSizes = source.mTcpBufferSizes;
mNat64Prefix = source.mNat64Prefix;
+ mWakeOnLanSupported = source.mWakeOnLanSupported;
}
}
@@ -852,6 +854,7 @@ public final class LinkProperties implements Parcelable {
mMtu = 0;
mTcpBufferSizes = null;
mNat64Prefix = null;
+ mWakeOnLanSupported = false;
}
/**
@@ -913,6 +916,10 @@ public final class LinkProperties implements Parcelable {
resultJoiner.add("MTU:");
resultJoiner.add(Integer.toString(mMtu));
+ if (mWakeOnLanSupported) {
+ resultJoiner.add("WakeOnLanSupported: true");
+ }
+
if (mTcpBufferSizes != null) {
resultJoiner.add("TcpBufferSizes:");
resultJoiner.add(mTcpBufferSizes);
@@ -1425,6 +1432,37 @@ public final class LinkProperties implements Parcelable {
}
/**
+ * Compares this {@code LinkProperties} WakeOnLan supported against the target.
+ *
+ * @param target LinkProperties to compare.
+ * @return {@code true} if both are identical, {@code false} otherwise.
+ * @hide
+ */
+ public boolean isIdenticalWakeOnLan(LinkProperties target) {
+ return isWakeOnLanSupported() == target.isWakeOnLanSupported();
+ }
+
+ /**
+ * Set whether the network interface supports WakeOnLAN
+ *
+ * @param supported WakeOnLAN supported value
+ *
+ * @hide
+ */
+ public void setWakeOnLanSupported(boolean supported) {
+ mWakeOnLanSupported = supported;
+ }
+
+ /**
+ * Returns whether the network interface supports WakeOnLAN
+ *
+ * @return {@code true} if interface supports WakeOnLAN, {@code false} otherwise.
+ */
+ public boolean isWakeOnLanSupported() {
+ return mWakeOnLanSupported;
+ }
+
+ /**
* Compares this {@code LinkProperties} instance against the target
* LinkProperties in {@code obj}. Two LinkPropertieses are equal if
* all their fields are equal in values.
@@ -1461,7 +1499,8 @@ public final class LinkProperties implements Parcelable {
&& isIdenticalStackedLinks(target)
&& isIdenticalMtu(target)
&& isIdenticalTcpBufferSizes(target)
- && isIdenticalNat64Prefix(target);
+ && isIdenticalNat64Prefix(target)
+ && isIdenticalWakeOnLan(target);
}
/**
@@ -1577,7 +1616,8 @@ public final class LinkProperties implements Parcelable {
+ (mUsePrivateDns ? 57 : 0)
+ mPcscfs.size() * 67
+ ((null == mPrivateDnsServerName) ? 0 : mPrivateDnsServerName.hashCode())
- + Objects.hash(mNat64Prefix);
+ + Objects.hash(mNat64Prefix)
+ + (mWakeOnLanSupported ? 71 : 0);
}
/**
@@ -1622,6 +1662,8 @@ public final class LinkProperties implements Parcelable {
ArrayList<LinkProperties> stackedLinks = new ArrayList<>(mStackedLinks.values());
dest.writeList(stackedLinks);
+
+ dest.writeBoolean(mWakeOnLanSupported);
}
/**
@@ -1677,6 +1719,7 @@ public final class LinkProperties implements Parcelable {
for (LinkProperties stackedLink: stackedLinks) {
netProp.addStackedLink(stackedLink);
}
+ netProp.setWakeOnLanSupported(in.readBoolean());
return netProp;
}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index b3125d89a1a7..6a709b56f35a 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -243,7 +243,8 @@ public class Build {
public static final String BASE_OS = SystemProperties.get("ro.build.version.base_os", "");
/**
- * The user-visible security patch level.
+ * The user-visible security patch level. This value represents the date when the device
+ * most recently applied a security patch.
*/
public static final String SECURITY_PATCH = SystemProperties.get(
"ro.build.version.security_patch", "");
diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java
index cfb582ef442e..5e8929c6c999 100644
--- a/core/java/android/os/HwParcel.java
+++ b/core/java/android/os/HwParcel.java
@@ -23,6 +23,8 @@ import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
+import dalvik.annotation.optimization.FastNative;
+
import libcore.util.NativeAllocationRegistry;
import java.lang.annotation.Retention;
@@ -72,46 +74,54 @@ public class HwParcel {
/**
* Writes an interface token into the parcel used to verify that
- * a transaction has made it to the write type of interface.
+ * a transaction has made it to the right type of interface.
*
* @param interfaceName fully qualified name of interface message
* is being sent to.
*/
+ @FastNative
public native final void writeInterfaceToken(String interfaceName);
/**
* Writes a boolean value to the end of the parcel.
* @param val to write
*/
+ @FastNative
public native final void writeBool(boolean val);
/**
* Writes a byte value to the end of the parcel.
* @param val to write
*/
+ @FastNative
public native final void writeInt8(byte val);
/**
* Writes a short value to the end of the parcel.
* @param val to write
*/
+ @FastNative
public native final void writeInt16(short val);
/**
* Writes a int value to the end of the parcel.
* @param val to write
*/
+ @FastNative
public native final void writeInt32(int val);
/**
* Writes a long value to the end of the parcel.
* @param val to write
*/
+ @FastNative
public native final void writeInt64(long val);
/**
* Writes a float value to the end of the parcel.
* @param val to write
*/
+ @FastNative
public native final void writeFloat(float val);
/**
* Writes a double value to the end of the parcel.
* @param val to write
*/
+ @FastNative
public native final void writeDouble(double val);
/**
* Writes a String value to the end of the parcel.
@@ -120,6 +130,7 @@ public class HwParcel {
*
* @param val to write
*/
+ @FastNative
public native final void writeString(String val);
/**
* Writes a native handle (without duplicating the underlying
@@ -127,42 +138,50 @@ public class HwParcel {
*
* @param val to write
*/
+ @FastNative
public native final void writeNativeHandle(@Nullable NativeHandle val);
/**
* Writes an array of boolean values to the end of the parcel.
* @param val to write
*/
+ @FastNative
private native final void writeBoolVector(boolean[] val);
/**
* Writes an array of byte values to the end of the parcel.
* @param val to write
*/
+ @FastNative
private native final void writeInt8Vector(byte[] val);
/**
* Writes an array of short values to the end of the parcel.
* @param val to write
*/
+ @FastNative
private native final void writeInt16Vector(short[] val);
/**
* Writes an array of int values to the end of the parcel.
* @param val to write
*/
+ @FastNative
private native final void writeInt32Vector(int[] val);
/**
* Writes an array of long values to the end of the parcel.
* @param val to write
*/
+ @FastNative
private native final void writeInt64Vector(long[] val);
/**
* Writes an array of float values to the end of the parcel.
* @param val to write
*/
+ @FastNative
private native final void writeFloatVector(float[] val);
/**
* Writes an array of double values to the end of the parcel.
* @param val to write
*/
+ @FastNative
private native final void writeDoubleVector(double[] val);
/**
* Writes an array of String values to the end of the parcel.
@@ -171,6 +190,7 @@ public class HwParcel {
*
* @param val to write
*/
+ @FastNative
private native final void writeStringVector(String[] val);
/**
* Writes an array of native handles to the end of the parcel.
@@ -179,6 +199,7 @@ public class HwParcel {
*
* @param val array of {@link NativeHandle} objects to write
*/
+ @FastNative
private native final void writeNativeHandleVector(NativeHandle[] val);
/**
@@ -299,6 +320,7 @@ public class HwParcel {
* Write a hwbinder object to the end of the parcel.
* @param binder value to write
*/
+ @FastNative
public native final void writeStrongBinder(IHwBinder binder);
/**
@@ -314,48 +336,56 @@ public class HwParcel {
* @return value parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final boolean readBool();
/**
* Reads a byte value from the current location in the parcel.
* @return value parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final byte readInt8();
/**
* Reads a short value from the current location in the parcel.
* @return value parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final short readInt16();
/**
* Reads a int value from the current location in the parcel.
* @return value parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final int readInt32();
/**
* Reads a long value from the current location in the parcel.
* @return value parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final long readInt64();
/**
* Reads a float value from the current location in the parcel.
* @return value parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final float readFloat();
/**
* Reads a double value from the current location in the parcel.
* @return value parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final double readDouble();
/**
* Reads a String value from the current location in the parcel.
* @return value parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final String readString();
/**
* Reads a native handle (without duplicating the underlying file
@@ -366,6 +396,7 @@ public class HwParcel {
* @return a {@link NativeHandle} instance parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final @Nullable NativeHandle readNativeHandle();
/**
* Reads an embedded native handle (without duplicating the underlying
@@ -379,6 +410,7 @@ public class HwParcel {
* @return a {@link NativeHandle} instance parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final @Nullable NativeHandle readEmbeddedNativeHandle(
long parentHandle, long offset);
@@ -387,54 +419,63 @@ public class HwParcel {
* @return array of parsed values
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
private native final boolean[] readBoolVectorAsArray();
/**
* Reads an array of byte values from the parcel.
* @return array of parsed values
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
private native final byte[] readInt8VectorAsArray();
/**
* Reads an array of short values from the parcel.
* @return array of parsed values
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
private native final short[] readInt16VectorAsArray();
/**
* Reads an array of int values from the parcel.
* @return array of parsed values
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
private native final int[] readInt32VectorAsArray();
/**
* Reads an array of long values from the parcel.
* @return array of parsed values
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
private native final long[] readInt64VectorAsArray();
/**
* Reads an array of float values from the parcel.
* @return array of parsed values
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
private native final float[] readFloatVectorAsArray();
/**
* Reads an array of double values from the parcel.
* @return array of parsed values
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
private native final double[] readDoubleVectorAsArray();
/**
* Reads an array of String values from the parcel.
* @return array of parsed values
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
private native final String[] readStringVectorAsArray();
/**
* Reads an array of native handles from the parcel.
* @return array of {@link NativeHandle} objects
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
private native final NativeHandle[] readNativeHandleAsArray();
/**
@@ -537,6 +578,7 @@ public class HwParcel {
* @return binder object read from parcel or null if no binder can be read
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final IHwBinder readStrongBinder();
/**
@@ -544,6 +586,7 @@ public class HwParcel {
* @return blob of size expectedSize
* @throws IllegalArgumentException if the parcel has no more data
*/
+ @FastNative
public native final HwBlob readBuffer(long expectedSize);
/**
@@ -559,6 +602,7 @@ public class HwParcel {
* @throws NullPointerException if the transaction specified the blob to be null
* but nullable is false
*/
+ @FastNative
public native final HwBlob readEmbeddedBuffer(
long expectedSize, long parentHandle, long offset,
boolean nullable);
@@ -567,26 +611,31 @@ public class HwParcel {
* Write a buffer into the transaction.
* @param blob blob to write into the parcel.
*/
+ @FastNative
public native final void writeBuffer(HwBlob blob);
/**
* Write a status value into the blob.
* @param status value to write
*/
+ @FastNative
public native final void writeStatus(int status);
/**
* @throws IllegalArgumentException if a success vaue cannot be read
* @throws RemoteException if success value indicates a transaction error
*/
+ @FastNative
public native final void verifySuccess();
/**
* Should be called to reduce memory pressure when this object no longer needs
* to be written to.
*/
+ @FastNative
public native final void releaseTemporaryStorage();
/**
* Should be called when object is no longer needed to reduce possible memory
* pressure if the Java GC does not get to this object in time.
*/
+ @FastNative
public native final void release();
/**
@@ -597,6 +646,7 @@ public class HwParcel {
// Returns address of the "freeFunction".
private static native final long native_init();
+ @FastNative
private native final void native_setup(boolean allocate);
static {
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index b568f157c01d..e371df001151 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -1,2 +1,4 @@
# Zygote
per-file ZygoteProcess.java = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
+
+per-file GraphicsEnvironment.java = chrisforbes@google.com, cnorthrop@google.com, lpy@google.com, timvp@google.com, zzyiwei@google.com
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 50487e9e7a99..783ab44bc4e2 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -305,8 +305,11 @@ public final class Parcel {
private static native void nativeWriteFloat(long nativePtr, float val);
@FastNative
private static native void nativeWriteDouble(long nativePtr, double val);
+ @FastNative
static native void nativeWriteString(long nativePtr, String val);
+ @FastNative
private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
+ @FastNative
private static native long nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);
private static native byte[] nativeCreateByteArray(long nativePtr);
@@ -320,8 +323,11 @@ public final class Parcel {
private static native float nativeReadFloat(long nativePtr);
@CriticalNative
private static native double nativeReadDouble(long nativePtr);
+ @FastNative
static native String nativeReadString(long nativePtr);
+ @FastNative
private static native IBinder nativeReadStrongBinder(long nativePtr);
+ @FastNative
private static native FileDescriptor nativeReadFileDescriptor(long nativePtr);
private static native long nativeCreate();
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 76e728a11e83..43b9c6728868 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -420,10 +420,9 @@ public class Process {
* Background thread group - All threads in
* this group are scheduled with a reduced share of the CPU.
* Value is same as constant SP_BACKGROUND of enum SchedPolicy.
- * FIXME rename to THREAD_GROUP_BACKGROUND.
* @hide
*/
- public static final int THREAD_GROUP_BG_NONINTERACTIVE = 0;
+ public static final int THREAD_GROUP_BACKGROUND = 0;
/**
* Foreground thread group - All threads in
@@ -809,7 +808,7 @@ public class Process {
*
* group == THREAD_GROUP_DEFAULT means to move all non-background priority
* threads to the foreground scheduling group, but to leave background
- * priority threads alone. group == THREAD_GROUP_BG_NONINTERACTIVE moves all
+ * priority threads alone. group == THREAD_GROUP_BACKGROUND moves all
* threads, regardless of priority, to the background scheduling group.
* group == THREAD_GROUP_FOREGROUND is not allowed.
*
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index dd5e20e39904..a9ddffe7d55c 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -22,8 +22,6 @@ import android.os.IUpdateEngine;
import android.os.IUpdateEngineCallback;
import android.os.RemoteException;
-import java.io.FileDescriptor;
-
/**
* UpdateEngine handles calls to the update engine which takes care of A/B OTA
* updates. It wraps up the update engine Binder APIs and exposes them as
@@ -315,16 +313,16 @@ public class UpdateEngine {
}
/**
- * Applies the payload passed as file descriptor {@code fd} instead of
+ * Applies the payload passed as ParcelFileDescriptor {@code pfd} instead of
* using the {@code file://} scheme.
*
* <p>See {@link #applyPayload(String)} for {@code offset}, {@code size} and
* {@code headerKeyValuePairs} parameters.
*/
- public void applyPayload(@NonNull FileDescriptor fd, long offset, long size,
+ public void applyPayload(@NonNull ParcelFileDescriptor pfd, long offset, long size,
@NonNull String[] headerKeyValuePairs) {
try {
- mUpdateEngine.applyPayloadFd(fd, offset, size, headerKeyValuePairs);
+ mUpdateEngine.applyPayloadFd(pfd, offset, size, headerKeyValuePairs);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 0754dc78a629..3558fcd24993 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -39,6 +39,7 @@ public final class UserHandle implements Parcelable {
/** @hide A user id to indicate all users on the device */
@UnsupportedAppUsage
+ @TestApi
public static final @UserIdInt int USER_ALL = -1;
/** @hide A user handle to indicate all users on the device */
@@ -69,8 +70,11 @@ public final class UserHandle implements Parcelable {
/** @hide An undefined user id */
@UnsupportedAppUsage
+ @TestApi
public static final @UserIdInt int USER_NULL = -10000;
+ private static final @NonNull UserHandle NULL = new UserHandle(USER_NULL);
+
/**
* @hide A user id constant to indicate the "owner" user of the device
* @deprecated Consider using either {@link UserHandle#USER_SYSTEM} constant or
@@ -91,6 +95,7 @@ public final class UserHandle implements Parcelable {
/** @hide A user id constant to indicate the "system" user of the device */
@UnsupportedAppUsage
+ @TestApi
public static final @UserIdInt int USER_SYSTEM = 0;
/** @hide A user serial constant to indicate the "system" user of the device */
@@ -110,6 +115,27 @@ public final class UserHandle implements Parcelable {
public static final boolean MU_ENABLED = true;
/** @hide */
+ @TestApi
+ public static final int MIN_SECONDARY_USER_ID = 10;
+
+ /**
+ * Arbitrary user handle cache size. We use the cache even when {@link #MU_ENABLED} is false
+ * anyway, so we can always assume in CTS that UserHandle.of(10) returns a cached instance
+ * even on non-multiuser devices.
+ */
+ private static final int NUM_CACHED_USERS = 4;
+
+ private static final UserHandle[] CACHED_USER_INFOS = new UserHandle[NUM_CACHED_USERS];
+
+ static {
+ // Not lazily initializing the cache, so that we can share them across processes.
+ // (We'll create them in zygote.)
+ for (int i = 0; i < CACHED_USER_INFOS.length; i++) {
+ CACHED_USER_INFOS[i] = new UserHandle(MIN_SECONDARY_USER_ID + i);
+ }
+ }
+
+ /** @hide */
@UnsupportedAppUsage
public static final int ERR_GID = -1;
/** @hide */
@@ -209,6 +235,7 @@ public final class UserHandle implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
+ @TestApi
public static @UserIdInt int getUserId(int uid) {
if (MU_ENABLED) {
return uid / PER_USER_RANGE;
@@ -229,9 +256,31 @@ public final class UserHandle implements Parcelable {
}
/** @hide */
+ @TestApi
@SystemApi
public static UserHandle of(@UserIdInt int userId) {
- return userId == USER_SYSTEM ? SYSTEM : new UserHandle(userId);
+ if (userId == USER_SYSTEM) {
+ return SYSTEM; // Most common.
+ }
+ // These are sequential; so use a switch. Maybe they'll be optimized to a table lookup.
+ switch (userId) {
+ case USER_ALL:
+ return ALL;
+
+ case USER_CURRENT:
+ return CURRENT;
+
+ case USER_CURRENT_OR_SELF:
+ return CURRENT_OR_SELF;
+ }
+ if (userId >= MIN_SECONDARY_USER_ID
+ && userId < (MIN_SECONDARY_USER_ID + CACHED_USER_INFOS.length)) {
+ return CACHED_USER_INFOS[userId - MIN_SECONDARY_USER_ID];
+ }
+ if (userId == USER_NULL) { // Not common.
+ return NULL;
+ }
+ return new UserHandle(userId);
}
/**
@@ -239,6 +288,7 @@ public final class UserHandle implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
+ @TestApi
public static int getUid(@UserIdInt int userId, @AppIdInt int appId) {
if (MU_ENABLED) {
return userId * PER_USER_RANGE + (appId % PER_USER_RANGE);
@@ -404,6 +454,7 @@ public final class UserHandle implements Parcelable {
* @hide
*/
@SystemApi
+ @TestApi
public static @UserIdInt int myUserId() {
return getUserId(Process.myUid());
}
@@ -513,7 +564,9 @@ public final class UserHandle implements Parcelable {
public static final @android.annotation.NonNull Parcelable.Creator<UserHandle> CREATOR
= new Parcelable.Creator<UserHandle>() {
public UserHandle createFromParcel(Parcel in) {
- return new UserHandle(in);
+ // Try to avoid allocation; use of() here. Keep this and the constructor below
+ // in sync.
+ return UserHandle.of(in.readInt());
}
public UserHandle[] newArray(int size) {
@@ -532,6 +585,6 @@ public final class UserHandle implements Parcelable {
* positioned at the location in the buffer where it was written.
*/
public UserHandle(Parcel in) {
- mHandle = in.readInt();
+ mHandle = in.readInt(); // Keep this and createFromParcel() in sync.
}
}
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 81643e90428f..5bda86704d88 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -36,6 +36,7 @@ import android.os.Parcelable;
import android.sysprop.DisplayProperties;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.AccessibilityClickableSpan;
+import android.text.style.AccessibilityReplacementSpan;
import android.text.style.AccessibilityURLSpan;
import android.text.style.AlignmentSpan;
import android.text.style.BackgroundColorSpan;
@@ -735,6 +736,8 @@ public class TextUtils {
/** @hide */
public static final int LINE_HEIGHT_SPAN = 28;
/** @hide */
+ public static final int ACCESSIBILITY_REPLACEMENT_SPAN = 29;
+ /** @hide */
public static final int LAST_SPAN = LINE_HEIGHT_SPAN;
/**
@@ -860,7 +863,7 @@ public class TextUtils {
case LEADING_MARGIN_SPAN:
readSpan(p, sp, new LeadingMarginSpan.Standard(p));
- break;
+ break;
case URL_SPAN:
readSpan(p, sp, new URLSpan(p));
@@ -933,7 +936,11 @@ public class TextUtils {
case LINE_HEIGHT_SPAN:
readSpan(p, sp, new LineHeightSpan.Standard(p));
break;
-
+
+ case ACCESSIBILITY_REPLACEMENT_SPAN:
+ readSpan(p, sp, new AccessibilityReplacementSpan(p));
+ break;
+
default:
throw new RuntimeException("bogus span encoding " + kind);
}
diff --git a/core/java/android/text/style/AccessibilityReplacementSpan.java b/core/java/android/text/style/AccessibilityReplacementSpan.java
new file mode 100644
index 000000000000..07b0975846aa
--- /dev/null
+++ b/core/java/android/text/style/AccessibilityReplacementSpan.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.style;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.ParcelableSpan;
+import android.text.TextUtils;
+
+/**
+ * This class serves as a parcelable placeholder for the ReplacementSpans.
+ *
+ * This span contains content description of original span to let Accessibility service to do the
+ * substitution for it.
+ *
+ * @hide
+ */
+public class AccessibilityReplacementSpan extends ReplacementSpan
+ implements ParcelableSpan {
+ // The content description of the span this one replaces
+ private CharSequence mContentDescription;
+
+ /**
+ * @param contentDescription The content description of the span this one replaces
+ */
+ public AccessibilityReplacementSpan(CharSequence contentDescription) {
+ this.setContentDescription(contentDescription);
+ mContentDescription = contentDescription;
+ }
+
+ public AccessibilityReplacementSpan(Parcel p) {
+ mContentDescription = p.readCharSequence();
+ }
+
+ @Override
+ public int getSpanTypeId() {
+ return getSpanTypeIdInternal();
+ }
+
+ @Override
+ public int getSpanTypeIdInternal() {
+ return TextUtils.ACCESSIBILITY_REPLACEMENT_SPAN;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ writeToParcelInternal(dest, flags);
+ }
+
+ @Override
+ public void writeToParcelInternal(Parcel dest, int flags) {
+ dest.writeCharSequence(mContentDescription);
+ }
+
+ @Override
+ public int getSize(Paint paint, CharSequence text, int start, int end,
+ Paint.FontMetricsInt fm) {
+ return 0;
+ }
+
+ @Override
+ public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y,
+ int bottom, Paint paint) {
+ }
+
+ public static final @android.annotation.NonNull
+ Parcelable.Creator<AccessibilityReplacementSpan> CREATOR =
+ new Parcelable.Creator<AccessibilityReplacementSpan>() {
+ @Override
+ public AccessibilityReplacementSpan createFromParcel(Parcel parcel) {
+ return new AccessibilityReplacementSpan(parcel);
+ }
+
+ @Override
+ public AccessibilityReplacementSpan[] newArray(int size) {
+ return new AccessibilityReplacementSpan[size];
+ }
+ };
+}
diff --git a/core/java/android/text/style/ReplacementSpan.java b/core/java/android/text/style/ReplacementSpan.java
index 5f94ad054b63..05532326cd84 100644
--- a/core/java/android/text/style/ReplacementSpan.java
+++ b/core/java/android/text/style/ReplacementSpan.java
@@ -25,6 +25,8 @@ import android.text.TextPaint;
public abstract class ReplacementSpan extends MetricAffectingSpan {
+ private CharSequence mContentDescription = null;
+
/**
* Returns the width of the span. Extending classes can set the height of the span by updating
* attributes of {@link android.graphics.Paint.FontMetricsInt}. If the span covers the whole
@@ -61,6 +63,27 @@ public abstract class ReplacementSpan extends MetricAffectingSpan {
int top, int y, int bottom, @NonNull Paint paint);
/**
+ * Gets a brief description of this ImageSpan for use in accessibility support.
+ *
+ * @return The content description.
+ */
+ @Nullable
+ public CharSequence getContentDescription() {
+ return mContentDescription;
+ }
+
+ /**
+ * Sets the specific content description into ImageSpan.
+ * ReplacementSpans are shared with accessibility services,
+ * but only the content description is available from them.
+ *
+ * @param contentDescription content description. The default value is null.
+ */
+ public void setContentDescription(@Nullable CharSequence contentDescription) {
+ mContentDescription = contentDescription;
+ }
+
+ /**
* This method does nothing, since ReplacementSpans are measured
* explicitly instead of affecting Paint properties.
*/
diff --git a/core/java/android/util/ArraySet.java b/core/java/android/util/ArraySet.java
index 44c5af20d891..4dda709f285d 100644
--- a/core/java/android/util/ArraySet.java
+++ b/core/java/android/util/ArraySet.java
@@ -16,6 +16,7 @@
package android.util;
+import android.annotation.Nullable;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
@@ -329,6 +330,18 @@ public final class ArraySet<E> implements Collection<E>, Set<E> {
}
/**
+ * Create a new ArraySet with items from the given array
+ */
+ public ArraySet(@Nullable E[] array) {
+ this();
+ if (array != null) {
+ for (E value : array) {
+ add(value);
+ }
+ }
+ }
+
+ /**
* Make the array map empty. All storage is released.
*/
@Override
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index b66764e81e8f..1be57dd489cf 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -59,6 +59,7 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false");
DEFAULT_FLAGS.put("settings_skip_direction_mutable", "true");
DEFAULT_FLAGS.put(SETTINGS_WIFITRACKER2, "false");
+ DEFAULT_FLAGS.put("settings_work_profile", "false");
}
/**
diff --git a/core/java/android/util/OWNERS b/core/java/android/util/OWNERS
index 98297fba8ef3..8f3d9f6f5881 100644
--- a/core/java/android/util/OWNERS
+++ b/core/java/android/util/OWNERS
@@ -1,3 +1,3 @@
per-file FeatureFlagUtils.java = sbasi@google.com
-per-file FeatureFlagUtils.java = zhfan@google.com
+per-file FeatureFlagUtils.java = tmfang@google.com
per-file FeatureFlagUtils.java = asapperstein@google.com
diff --git a/core/java/android/util/StatsEvent.java b/core/java/android/util/StatsEvent.java
new file mode 100644
index 000000000000..91a5ec0303f7
--- /dev/null
+++ b/core/java/android/util/StatsEvent.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * StatsEvent builds and stores the buffer sent over the statsd socket.
+ * This class defines and encapsulates the socket protocol.
+ * @hide
+ **/
+public final class StatsEvent implements AutoCloseable {
+ private static final int POS_NUM_ELEMENTS = 1;
+ private static final int POS_TIMESTAMP = POS_NUM_ELEMENTS + 1;
+
+ private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;
+
+ // Max payload size is 4 KB less 4 bytes which are reserved for statsEventTag.
+ // See android_util_StatsLog.cpp.
+ private static final int MAX_EVENT_PAYLOAD = LOGGER_ENTRY_MAX_PAYLOAD - 4;
+
+ private static final byte INT_TYPE = 0;
+ private static final byte LONG_TYPE = 1;
+ private static final byte STRING_TYPE = 2;
+ private static final byte LIST_TYPE = 3;
+ private static final byte FLOAT_TYPE = 4;
+
+ private static final int INT_TYPE_SIZE = 5;
+ private static final int FLOAT_TYPE_SIZE = 5;
+ private static final int LONG_TYPE_SIZE = 9;
+
+ private static final int STRING_TYPE_OVERHEAD = 5;
+ private static final int LIST_TYPE_OVERHEAD = 2;
+
+ public static final int SUCCESS = 0;
+ public static final int ERROR_BUFFER_LIMIT_EXCEEDED = -1;
+ public static final int ERROR_NO_TIMESTAMP = -2;
+ public static final int ERROR_TIMESTAMP_ALREADY_WRITTEN = -3;
+ public static final int ERROR_NO_ATOM_ID = -4;
+ public static final int ERROR_ATOM_ID_ALREADY_WRITTEN = -5;
+ public static final int ERROR_UID_TAG_COUNT_MISMATCH = -6;
+
+ private static Object sLock = new Object();
+
+ @GuardedBy("sLock")
+ private static StatsEvent sPool;
+
+ private final byte[] mBuffer = new byte[MAX_EVENT_PAYLOAD];
+ private int mPos;
+ private int mNumElements;
+ private int mAtomId;
+
+ private StatsEvent() {
+ // Write LIST_TYPE to buffer
+ mBuffer[0] = LIST_TYPE;
+ reset();
+ }
+
+ private void reset() {
+ // Reset state.
+ mPos = POS_TIMESTAMP;
+ mNumElements = 0;
+ mAtomId = 0;
+ }
+
+ /**
+ * Returns a StatsEvent object from the pool.
+ **/
+ @NonNull
+ public static StatsEvent obtain() {
+ final StatsEvent statsEvent;
+ synchronized (sLock) {
+ statsEvent = null == sPool ? new StatsEvent() : sPool;
+ sPool = null;
+ }
+ statsEvent.reset();
+ return statsEvent;
+ }
+
+ @Override
+ public void close() {
+ synchronized (sLock) {
+ if (null == sPool) {
+ sPool = this;
+ }
+ }
+ }
+
+ /**
+ * Writes the event timestamp to the buffer.
+ **/
+ public int writeTimestampNs(final long timestampNs) {
+ if (hasTimestamp()) {
+ return ERROR_TIMESTAMP_ALREADY_WRITTEN;
+ }
+ return writeLong(timestampNs);
+ }
+
+ private boolean hasTimestamp() {
+ return mPos > POS_TIMESTAMP;
+ }
+
+ private boolean hasAtomId() {
+ return mAtomId != 0;
+ }
+
+ /**
+ * Writes the atom id to the buffer.
+ **/
+ public int writeAtomId(final int atomId) {
+ if (!hasTimestamp()) {
+ return ERROR_NO_TIMESTAMP;
+ } else if (hasAtomId()) {
+ return ERROR_ATOM_ID_ALREADY_WRITTEN;
+ }
+
+ final int writeResult = writeInt(atomId);
+ if (SUCCESS == writeResult) {
+ mAtomId = atomId;
+ }
+ return writeResult;
+ }
+
+ /**
+ * Appends the given int to the StatsEvent buffer.
+ **/
+ public int writeInt(final int value) {
+ if (!hasTimestamp()) {
+ return ERROR_NO_TIMESTAMP;
+ } else if (!hasAtomId()) {
+ return ERROR_NO_ATOM_ID;
+ } else if (mPos + INT_TYPE_SIZE > MAX_EVENT_PAYLOAD) {
+ return ERROR_BUFFER_LIMIT_EXCEEDED;
+ }
+
+ mBuffer[mPos] = INT_TYPE;
+ copyInt(mBuffer, mPos + 1, value);
+ mPos += INT_TYPE_SIZE;
+ mNumElements++;
+ return SUCCESS;
+ }
+
+ /**
+ * Appends the given long to the StatsEvent buffer.
+ **/
+ public int writeLong(final long value) {
+ if (!hasTimestamp()) {
+ return ERROR_NO_TIMESTAMP;
+ } else if (!hasAtomId()) {
+ return ERROR_NO_ATOM_ID;
+ } else if (mPos + LONG_TYPE_SIZE > MAX_EVENT_PAYLOAD) {
+ return ERROR_BUFFER_LIMIT_EXCEEDED;
+ }
+
+ mBuffer[mPos] = LONG_TYPE;
+ copyLong(mBuffer, mPos + 1, value);
+ mPos += LONG_TYPE_SIZE;
+ mNumElements++;
+ return SUCCESS;
+ }
+
+ /**
+ * Appends the given float to the StatsEvent buffer.
+ **/
+ public int writeFloat(final float value) {
+ if (!hasTimestamp()) {
+ return ERROR_NO_TIMESTAMP;
+ } else if (!hasAtomId()) {
+ return ERROR_NO_ATOM_ID;
+ } else if (mPos + FLOAT_TYPE_SIZE > MAX_EVENT_PAYLOAD) {
+ return ERROR_BUFFER_LIMIT_EXCEEDED;
+ }
+
+ mBuffer[mPos] = FLOAT_TYPE;
+ copyInt(mBuffer, mPos + 1, Float.floatToIntBits(value));
+ mPos += FLOAT_TYPE_SIZE;
+ mNumElements++;
+ return SUCCESS;
+ }
+
+ /**
+ * Appends the given boolean to the StatsEvent buffer.
+ **/
+ public int writeBoolean(final boolean value) {
+ return writeInt(value ? 1 : 0);
+ }
+
+ /**
+ * Appends the given byte array to the StatsEvent buffer.
+ **/
+ public int writeByteArray(@NonNull final byte[] value) {
+ if (!hasTimestamp()) {
+ return ERROR_NO_TIMESTAMP;
+ } else if (!hasAtomId()) {
+ return ERROR_NO_ATOM_ID;
+ } else if (mPos + STRING_TYPE_OVERHEAD + value.length > MAX_EVENT_PAYLOAD) {
+ return ERROR_BUFFER_LIMIT_EXCEEDED;
+ }
+
+ mBuffer[mPos] = STRING_TYPE;
+ copyInt(mBuffer, mPos + 1, value.length);
+ System.arraycopy(value, 0, mBuffer, mPos + STRING_TYPE_OVERHEAD, value.length);
+ mPos += STRING_TYPE_OVERHEAD + value.length;
+ mNumElements++;
+ return SUCCESS;
+ }
+
+ /**
+ * Appends the given String to the StatsEvent buffer.
+ **/
+ public int writeString(@NonNull final String value) {
+ final byte[] valueBytes = stringToBytes(value);
+ return writeByteArray(valueBytes);
+ }
+
+ /**
+ * Appends the AttributionNode specified as array of uids and array of tags.
+ **/
+ public int writeAttributionNode(@NonNull final int[] uids, @NonNull final String[] tags) {
+ if (!hasTimestamp()) {
+ return ERROR_NO_TIMESTAMP;
+ } else if (!hasAtomId()) {
+ return ERROR_NO_ATOM_ID;
+ } else if (mPos + LIST_TYPE_OVERHEAD > MAX_EVENT_PAYLOAD) {
+ return ERROR_BUFFER_LIMIT_EXCEEDED;
+ }
+
+ final int numTags = tags.length;
+ final int numUids = uids.length;
+ if (numTags != numUids) {
+ return ERROR_UID_TAG_COUNT_MISMATCH;
+ }
+
+ int pos = mPos;
+ mBuffer[pos] = LIST_TYPE;
+ mBuffer[pos + 1] = (byte) numTags;
+ pos += LIST_TYPE_OVERHEAD;
+ for (int i = 0; i < numTags; i++) {
+ final byte[] tagBytes = stringToBytes(tags[i]);
+
+ if (pos + LIST_TYPE_OVERHEAD + INT_TYPE_SIZE
+ + STRING_TYPE_OVERHEAD + tagBytes.length > MAX_EVENT_PAYLOAD) {
+ return ERROR_BUFFER_LIMIT_EXCEEDED;
+ }
+
+ mBuffer[pos] = LIST_TYPE;
+ mBuffer[pos + 1] = 2;
+ pos += LIST_TYPE_OVERHEAD;
+ mBuffer[pos] = INT_TYPE;
+ copyInt(mBuffer, pos + 1, uids[i]);
+ pos += INT_TYPE_SIZE;
+ mBuffer[pos] = STRING_TYPE;
+ copyInt(mBuffer, pos + 1, tagBytes.length);
+ System.arraycopy(tagBytes, 0, mBuffer, pos + STRING_TYPE_OVERHEAD, tagBytes.length);
+ pos += STRING_TYPE_OVERHEAD + tagBytes.length;
+ }
+ mPos = pos;
+ mNumElements++;
+ return SUCCESS;
+ }
+
+ /**
+ * Returns the byte array containing data in the statsd socket format.
+ * @hide
+ **/
+ @NonNull
+ public byte[] getBuffer() {
+ // Encode number of elements in the buffer.
+ mBuffer[POS_NUM_ELEMENTS] = (byte) mNumElements;
+ return mBuffer;
+ }
+
+ /**
+ * Returns number of bytes used by the buffer.
+ * @hide
+ **/
+ public int size() {
+ return mPos;
+ }
+
+ /**
+ * Getter for atom id.
+ * @hide
+ **/
+ public int getAtomId() {
+ return mAtomId;
+ }
+
+ @NonNull
+ private static byte[] stringToBytes(@Nullable final String value) {
+ return (null == value ? "" : value).getBytes(UTF_8);
+ }
+
+ // Helper methods for copying primitives
+ private static void copyInt(@NonNull byte[] buff, int pos, int value) {
+ buff[pos] = (byte) (value);
+ buff[pos + 1] = (byte) (value >> 8);
+ buff[pos + 2] = (byte) (value >> 16);
+ buff[pos + 3] = (byte) (value >> 24);
+ }
+
+ private static void copyLong(@NonNull byte[] buff, int pos, long value) {
+ buff[pos] = (byte) (value);
+ buff[pos + 1] = (byte) (value >> 8);
+ buff[pos + 2] = (byte) (value >> 16);
+ buff[pos + 3] = (byte) (value >> 24);
+ buff[pos + 4] = (byte) (value >> 32);
+ buff[pos + 5] = (byte) (value >> 40);
+ buff[pos + 6] = (byte) (value >> 48);
+ buff[pos + 7] = (byte) (value >> 56);
+ }
+}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 82a5fa979fd2..853a30226982 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2615,7 +2615,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|| actionMasked == MotionEvent.ACTION_CANCEL;
// Update list of touch targets for pointer down, if needed.
- final boolean split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0;
+ final boolean isMouseEvent = ev.getSource() == InputDevice.SOURCE_MOUSE;
+ final boolean split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0
+ && !isMouseEvent;
TouchTarget newTouchTarget = null;
boolean alreadyDispatchedToNewTouchTarget = false;
if (!canceled && !intercepted) {
@@ -2632,8 +2634,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final int childrenCount = mChildrenCount;
if (newTouchTarget == null && childrenCount != 0) {
- final float x = ev.getX(actionIndex);
- final float y = ev.getY(actionIndex);
+ final float x =
+ isMouseEvent ? ev.getXCursorPosition() : ev.getX(actionIndex);
+ final float y =
+ isMouseEvent ? ev.getYCursorPosition() : ev.getY(actionIndex);
// Find a child that can receive the event.
// Scan children from front to back.
final ArrayList<View> preorderedList = buildTouchDispatchChildList();
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index cf29ed712793..06e9d0dbf6d6 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -39,8 +39,10 @@ import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.AccessibilityClickableSpan;
+import android.text.style.AccessibilityReplacementSpan;
import android.text.style.AccessibilityURLSpan;
import android.text.style.ClickableSpan;
+import android.text.style.ReplacementSpan;
import android.text.style.URLSpan;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -2641,37 +2643,86 @@ public class AccessibilityNodeInfo implements Parcelable {
public void setText(CharSequence text) {
enforceNotSealed();
mOriginalText = text;
- // Replace any ClickableSpans in mText with placeholders
if (text instanceof Spanned) {
- ClickableSpan[] spans =
- ((Spanned) text).getSpans(0, text.length(), ClickableSpan.class);
- if (spans.length > 0) {
- Spannable spannable = new SpannableStringBuilder(text);
- for (int i = 0; i < spans.length; i++) {
- ClickableSpan span = spans[i];
- if ((span instanceof AccessibilityClickableSpan)
- || (span instanceof AccessibilityURLSpan)) {
- // We've already done enough
- break;
- }
- int spanToReplaceStart = spannable.getSpanStart(span);
- int spanToReplaceEnd = spannable.getSpanEnd(span);
- int spanToReplaceFlags = spannable.getSpanFlags(span);
- spannable.removeSpan(span);
- ClickableSpan replacementSpan = (span instanceof URLSpan)
- ? new AccessibilityURLSpan((URLSpan) span)
- : new AccessibilityClickableSpan(span.getId());
- spannable.setSpan(replacementSpan, spanToReplaceStart, spanToReplaceEnd,
- spanToReplaceFlags);
- }
- mText = spannable;
- return;
- }
+ CharSequence tmpText = text;
+ tmpText = replaceClickableSpan(tmpText);
+ tmpText = replaceReplacementSpan(tmpText);
+ mText = tmpText;
+ return;
}
mText = (text == null) ? null : text.subSequence(0, text.length());
}
/**
+ * Replaces any ClickableSpans in mText with placeholders.
+ *
+ * @param text The text.
+ *
+ * @return The spannable with ClickableSpan replacement.
+ */
+ private CharSequence replaceClickableSpan(CharSequence text) {
+ ClickableSpan[] clickableSpans =
+ ((Spanned) text).getSpans(0, text.length(), ClickableSpan.class);
+ Spannable spannable = new SpannableStringBuilder(text);
+ if (clickableSpans.length == 0) {
+ return text;
+ }
+ for (int i = 0; i < clickableSpans.length; i++) {
+ ClickableSpan span = clickableSpans[i];
+ if ((span instanceof AccessibilityClickableSpan)
+ || (span instanceof AccessibilityURLSpan)) {
+ // We've already done enough
+ break;
+ }
+ int spanToReplaceStart = spannable.getSpanStart(span);
+ int spanToReplaceEnd = spannable.getSpanEnd(span);
+ int spanToReplaceFlags = spannable.getSpanFlags(span);
+ spannable.removeSpan(span);
+ ClickableSpan replacementSpan = (span instanceof URLSpan)
+ ? new AccessibilityURLSpan((URLSpan) span)
+ : new AccessibilityClickableSpan(span.getId());
+ spannable.setSpan(replacementSpan, spanToReplaceStart, spanToReplaceEnd,
+ spanToReplaceFlags);
+ }
+ return spannable;
+ }
+
+ /**
+ * Replace any ImageSpans in mText with its content description.
+ *
+ * @param text The text.
+ *
+ * @return The spannable with ReplacementSpan replacement.
+ */
+ private CharSequence replaceReplacementSpan(CharSequence text) {
+ ReplacementSpan[] replacementSpans =
+ ((Spanned) text).getSpans(0, text.length(), ReplacementSpan.class);
+ SpannableStringBuilder spannable = new SpannableStringBuilder(text);
+ if (replacementSpans.length == 0) {
+ return text;
+ }
+ for (int i = 0; i < replacementSpans.length; i++) {
+ ReplacementSpan span = replacementSpans[i];
+ CharSequence replacementText = span.getContentDescription();
+ if (span instanceof AccessibilityReplacementSpan) {
+ // We've already done enough
+ break;
+ }
+ if (replacementText == null) {
+ continue;
+ }
+ int spanToReplaceStart = spannable.getSpanStart(span);
+ int spanToReplaceEnd = spannable.getSpanEnd(span);
+ int spanToReplaceFlags = spannable.getSpanFlags(span);
+ spannable.removeSpan(span);
+ ReplacementSpan replacementSpan = new AccessibilityReplacementSpan(replacementText);
+ spannable.setSpan(replacementSpan, spanToReplaceStart, spanToReplaceEnd,
+ spanToReplaceFlags);
+ }
+ return spannable;
+ }
+
+ /**
* Gets the hint text of this node. Only applies to nodes where text can be entered.
*
* @return The hint text.
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index fe88a9140b37..6d60366dc72d 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2569,7 +2569,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (isItemClickable(view)) {
addAccessibilityActionIfEnabled(info, isItemEnabled, AccessibilityAction.ACTION_CLICK);
- info.setClickable(true);
+ // A disabled item is a separator which should not be clickable.
+ info.setClickable(isItemEnabled);
}
if (isLongClickable()) {
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 5f92cddbaa38..a390611be20b 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -115,14 +115,6 @@ public class ResolverListController {
flags |= PackageManager.MATCH_INSTANT;
}
final List<ResolveInfo> infos = mpm.queryIntentActivities(intent, flags);
- // Remove any activities that are not exported.
- int totalSize = infos.size();
- for (int j = totalSize - 1; j >= 0 ; j--) {
- ResolveInfo info = infos.get(j);
- if (info.activityInfo != null && !info.activityInfo.exported) {
- infos.remove(j);
- }
- }
if (infos != null) {
if (resolvedComponents == null) {
resolvedComponents = new ArrayList<>();
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index d80c071c3e26..483b455965f7 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -721,8 +721,11 @@ static const JNINativeMethod gParcelMethods[] = {
{"nativeWriteFloat", "(JF)V", (void*)android_os_Parcel_writeFloat},
// @FastNative
{"nativeWriteDouble", "(JD)V", (void*)android_os_Parcel_writeDouble},
+ // @FastNative
{"nativeWriteString", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString},
+ // @FastNative
{"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
+ // @FastNative
{"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)J", (void*)android_os_Parcel_writeFileDescriptor},
{"nativeCreateByteArray", "(J)[B", (void*)android_os_Parcel_createByteArray},
@@ -736,8 +739,11 @@ static const JNINativeMethod gParcelMethods[] = {
{"nativeReadFloat", "(J)F", (void*)android_os_Parcel_readFloat},
// @CriticalNative
{"nativeReadDouble", "(J)D", (void*)android_os_Parcel_readDouble},
+ // @FastNative
{"nativeReadString", "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString},
+ // @FastNative
{"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
+ // @FastNative
{"nativeReadFileDescriptor", "(J)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
{"nativeCreate", "()J", (void*)android_os_Parcel_create},
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 0afbaa0e174c..e406e2257c67 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -697,6 +697,9 @@ BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
// same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
+ // N.B. This function is called from a @FastNative JNI method, so don't take locks around
+ // calls to Java code or block the calling thread for a long time for any reason.
+
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)) {
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 3cefeea68406..0fada1bae8ed 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -35,6 +35,7 @@
#include <limits>
#include <memory>
#include <string>
+#include <unordered_map>
#include <vector>
#include "core_jni_helpers.h"
@@ -81,6 +82,25 @@ Mutex gKeyCreateMutex;
static pthread_key_t gBgKey = -1;
#endif
+/*
+ * cpuset/sched aggregate profile mappings
+ */
+static const std::unordered_map<int, std::string> kCpusetProfileMap = {
+ {SP_DEFAULT, "CPUSET_SP_DEFAULT"}, {SP_BACKGROUND, "CPUSET_SP_BACKGROUND"},
+ {SP_FOREGROUND, "CPUSET_SP_FOREGROUND"},{SP_SYSTEM, "CPUSET_SP_SYSTEM"},
+ {SP_AUDIO_APP, "CPUSET_SP_FOREGROUND"}, {SP_AUDIO_SYS, "CPUSET_SP_FOREGROUND"},
+ {SP_TOP_APP, "CPUSET_SP_TOP_APP"}, {SP_RT_APP, "CPUSET_SP_DEFAULT"},
+ {SP_RESTRICTED, "CPUSET_SP_RESTRICTED"}
+};
+
+static const std::unordered_map<int, std::string> kSchedProfileMap = {
+ {SP_DEFAULT, "SCHED_SP_DEFAULT"}, {SP_BACKGROUND, "SCHED_SP_BACKGROUND"},
+ {SP_FOREGROUND, "SCHED_SP_FOREGROUND"}, {SP_SYSTEM, "SCHED_SP_DEFAULT"},
+ {SP_AUDIO_APP, "SCHED_SP_FOREGROUND"}, {SP_AUDIO_SYS, "SCHED_SP_FOREGROUND"},
+ {SP_TOP_APP, "SCHED_SP_TOP_APP"}, {SP_RT_APP, "SCHED_SP_RT_APP"},
+ {SP_RESTRICTED, "SCHED_SP_DEFAULT"}
+};
+
// For both of these, err should be in the errno range (positive), not a status_t (negative)
static void signalExceptionForError(JNIEnv* env, int err, int tid) {
switch (err) {
@@ -206,8 +226,9 @@ void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int tid, jint
if (!verifyGroup(env, grp)) {
return;
}
- SchedPolicy sp = (SchedPolicy) grp;
- int res = set_sched_policy(tid, sp);
+
+ int res = SetTaskProfiles(tid, {kSchedProfileMap.at(grp)}, true) ? 0 : -1;
+
if (res != NO_ERROR) {
signalExceptionForGroupError(env, -res, tid);
}
@@ -219,14 +240,9 @@ void android_os_Process_setThreadGroupAndCpuset(JNIEnv* env, jobject clazz, int
if (!verifyGroup(env, grp)) {
return;
}
- SchedPolicy sp = (SchedPolicy) grp;
- int res = set_sched_policy(tid, sp);
- if (res != NO_ERROR) {
- signalExceptionForGroupError(env, -res, tid);
- }
+ int res = SetTaskProfiles(tid, {kCpusetProfileMap.at(grp)}, true) ? 0 : -1;
- res = set_cpuset_policy(tid, sp);
if (res != NO_ERROR) {
signalExceptionForGroupError(env, -res, tid);
}
@@ -239,7 +255,11 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
char proc_path[255];
struct dirent *de;
- if ((grp == SP_FOREGROUND) || (grp > SP_MAX)) {
+ if (!verifyGroup(env, grp)) {
+ return;
+ }
+
+ if (grp == SP_FOREGROUND) {
signalExceptionForGroupError(env, EINVAL, pid);
return;
}
@@ -249,10 +269,6 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
grp = SP_FOREGROUND;
isDefault = true;
}
- if (!verifyGroup(env, grp)) {
- return;
- }
- SchedPolicy sp = (SchedPolicy) grp;
if (kDebugPolicy) {
char cmdline[32];
@@ -268,7 +284,7 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
close(fd);
}
- if (sp == SP_BACKGROUND) {
+ if (grp == SP_BACKGROUND) {
ALOGD("setProcessGroup: vvv pid %d (%s)", pid, cmdline);
} else {
ALOGD("setProcessGroup: ^^^ pid %d (%s)", pid, cmdline);
@@ -286,6 +302,7 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
while ((de = readdir(d))) {
int t_pid;
int t_pri;
+ int err;
if (de->d_name[0] == '.')
continue;
@@ -311,28 +328,16 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
if (t_pri >= ANDROID_PRIORITY_BACKGROUND) {
// This task wants to stay at background
// update its cpuset so it doesn't only run on bg core(s)
- if (cpusets_enabled()) {
- int err = set_cpuset_policy(t_pid, sp);
- if (err != NO_ERROR) {
- signalExceptionForGroupError(env, -err, t_pid);
- break;
- }
+ err = SetTaskProfiles(t_pid, {kCpusetProfileMap.at(grp)}, true) ? 0 : -1;
+ if (err != NO_ERROR) {
+ signalExceptionForGroupError(env, -err, t_pid);
+ break;
}
continue;
}
}
- int err;
-
- if (cpusets_enabled()) {
- // set both cpuset and cgroup for general threads
- err = set_cpuset_policy(t_pid, sp);
- if (err != NO_ERROR) {
- signalExceptionForGroupError(env, -err, t_pid);
- break;
- }
- }
- err = set_sched_policy(t_pid, sp);
+ err = SetTaskProfiles(t_pid, {kCpusetProfileMap.at(grp)}, true) ? 0 : -1;
if (err != NO_ERROR) {
signalExceptionForGroupError(env, -err, t_pid);
break;
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 3ea8a778ba9b..381ed7f80602 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -349,10 +349,10 @@
will be given a single shared user ID, so they can for example run
in the same process. Note that for them to actually get the same
user ID, they must also be signed with the same signature.
- @deprecated Shared user id's cause non-deterministic behaviour within the
- package manager. As such, it's use is discouraged, deprecated, and will
- be removed altogether in a future version of Android. Instead, proper
- communication mechanisms such as services and providers should be used
+ @deprecated Shared user IDs cause non-deterministic behavior within the
+ package manager. As such, its use is strongly discouraged and may be
+ removed in a future version of Android. Instead, apps should use proper
+ communication mechanisms, such as services and content providers,
to facilitate interoperability between shared components. -->
<attr name="sharedUserId" format="string" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7eca699d9eca..3fef7a2dffae 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -433,6 +433,14 @@
-->
</string-array>
+ <!-- Configuration of network interfaces that support WakeOnLAN -->
+ <string-array translatable="false" name="config_wakeonlan_supported_interfaces">
+ <!--
+ <item>wlan0</item>
+ <item>eth0</item>
+ -->
+ </string-array>
+
<!-- Package name for the default CellBroadcastService module [DO NOT TRANSLATE] -->
<string name="cellbroadcast_default_package" translatable="false">com.android.cellbroadcastreceiver
</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a8b534061aeb..363bc9ddd75c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -747,6 +747,7 @@
<java-symbol type="string" name="config_default_dns_server" />
<java-symbol type="string" name="config_ethernet_iface_regex" />
<java-symbol type="array" name="config_ethernet_interfaces" />
+ <java-symbol type="array" name="config_wakeonlan_supported_interfaces" />
<java-symbol type="string" name="cellbroadcast_default_package" />
<java-symbol type="string" name="config_forceVoiceInteractionServicePackage" />
<java-symbol type="string" name="config_mms_user_agent" />
diff --git a/core/tests/coretests/src/android/view/ViewGroupTest.java b/core/tests/coretests/src/android/view/ViewGroupTest.java
index 979a839d2ffe..506cc2d3ff97 100644
--- a/core/tests/coretests/src/android/view/ViewGroupTest.java
+++ b/core/tests/coretests/src/android/view/ViewGroupTest.java
@@ -16,9 +16,14 @@
package android.view;
-import static androidx.test.InstrumentationRegistry.getContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import android.content.Context;
import android.graphics.Region;
@@ -39,6 +44,60 @@ import org.junit.Test;
@SmallTest
public class ViewGroupTest {
+ @Test
+ public void testDispatchMouseEventsUnderCursor() {
+ final Context context = getInstrumentation().getContext();
+ final TestView viewGroup = new TestView(context, 0 /* left */, 0 /* top */,
+ 200 /* right */, 200 /* bottom */);
+ final TestView viewA = spy(new TestView(context, 0 /* left */, 0 /* top */,
+ 100 /* right */, 200 /* bottom */));
+ final TestView viewB = spy(new TestView(context, 100 /* left */, 0 /* top */,
+ 200 /* right */, 200 /* bottom */));
+
+ viewGroup.addView(viewA);
+ viewGroup.addView(viewB);
+
+ // Make sure all of them handle touch events dispatched to them.
+ doReturn(true).when(viewA).dispatchTouchEvent(any());
+ doReturn(true).when(viewB).dispatchTouchEvent(any());
+
+ MotionEvent.PointerProperties[] properties = new MotionEvent.PointerProperties[2];
+ properties[0] = new MotionEvent.PointerProperties();
+ properties[0].id = 0;
+ properties[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
+ properties[1] = new MotionEvent.PointerProperties();
+ properties[1].id = 1;
+ properties[1].toolType = MotionEvent.TOOL_TYPE_FINGER;
+
+ MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[2];
+ coords[0] = new MotionEvent.PointerCoords();
+ coords[0].x = 80;
+ coords[0].y = 100;
+ coords[1] = new MotionEvent.PointerCoords();
+ coords[1].x = 240;
+ coords[1].y = 100;
+
+ MotionEvent event;
+ // Make sure the down event is active with a pointer which coordinate is different from the
+ // cursor position, which is the midpoint of all 2 pointers above.
+ event = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */, MotionEvent.ACTION_DOWN,
+ 2 /* pointerCount */, properties, coords, 0 /* metaState */, 0 /* buttonState */,
+ 0 /* xPrecision */, 0 /* yPrecision */, 0 /* deviceId */, 0 /* edgeFlags */,
+ InputDevice.SOURCE_MOUSE, 0 /* flags */);
+ viewGroup.dispatchTouchEvent(event);
+ verify(viewB).dispatchTouchEvent(event);
+
+ event = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */,
+ MotionEvent.ACTION_POINTER_DOWN | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT),
+ 2 /* pointerCount */, properties, coords, 0 /* metaState */, 0 /* buttonState */,
+ 0 /* xPrecision */, 0 /* yPrecision */, 0 /* deviceId */, 0 /* edgeFlags */,
+ InputDevice.SOURCE_MOUSE, 0 /* flags */);
+ viewGroup.dispatchTouchEvent(event);
+ verify(viewB).dispatchTouchEvent(event);
+
+ verify(viewA, never()).dispatchTouchEvent(any());
+ }
+
/**
* Test if {@link ViewGroup#subtractObscuredTouchableRegion} works as expected.
*
@@ -59,7 +118,7 @@ public class ViewGroupTest {
*/
@Test
public void testSubtractObscuredTouchableRegion() {
- final Context context = getContext();
+ final Context context = getInstrumentation().getContext();
final TestView viewA = new TestView(context, 8 /* right */);
final TestView viewB = new TestView(context, 6 /* right */);
final TestView viewC = new TestView(context, 10 /* right */);
@@ -119,10 +178,14 @@ public class ViewGroupTest {
(contain ? "" : " not"), x), contain, region.contains(x, 0 /* y */));
}
- private static class TestView extends ViewGroup {
+ public static class TestView extends ViewGroup {
TestView(Context context, int right) {
+ this(context, 0 /* left */, 0 /* top */, right, 1 /* bottom */);
+ }
+
+ TestView(Context context, int left, int top, int right, int bottom) {
super(context);
- setFrame(0 /* left */, 0 /* top */, right, 1 /* bottom */);
+ setFrame(left, top, right, bottom);
}
@Override
diff --git a/core/tests/featureflagtests/OWNERS b/core/tests/featureflagtests/OWNERS
index 1a8fd2b62f9a..2ff4f5ab8807 100644
--- a/core/tests/featureflagtests/OWNERS
+++ b/core/tests/featureflagtests/OWNERS
@@ -1,2 +1,2 @@
sbasi@google.com
-zhfan@google.com \ No newline at end of file
+tmfang@google.com \ No newline at end of file
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 1829d2f406b4..bf2363481f73 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -343,6 +343,16 @@ public final class KeyChain {
public static final int KEY_ATTESTATION_FAILURE = 4;
/**
+ * Used by DPC or delegated app in
+ * {@link android.app.admin.DeviceAdminReceiver#onChoosePrivateKeyAlias} or
+ * {@link android.app.admin.DelegatedAdminReceiver#onChoosePrivateKeyAlias} to identify that
+ * the requesting app is not granted access to any key, and nor will the user be able to grant
+ * access manually.
+ */
+ public static final String KEY_ALIAS_SELECTION_DENIED =
+ "alias-selection-denied-ef829e15-210a-409d-96c9-ee684fc41972";
+
+ /**
* Returns an {@code Intent} that can be used for credential
* installation. The intent may be used without any extras, in
* which case the user will be able to install credentials from
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index fc268138e071..8eb81533fda8 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -39,7 +39,7 @@ namespace renderthread {
// to the screen resolution. This is meant to be a conservative default based on
// that analysis. The 4.0f is used because the default pixel format is assumed to
// be ARGB_8888.
-#define SURFACE_SIZE_MULTIPLIER (12.0f * 4.0f)
+#define SURFACE_SIZE_MULTIPLIER (5.0f * 4.0f)
#define BACKGROUND_RETENTION_PERCENTAGE (0.5f)
CacheManager::CacheManager(const DisplayInfo& display)
diff --git a/mms/OWNERS b/mms/OWNERS
new file mode 100644
index 000000000000..ba00d5d75010
--- /dev/null
+++ b/mms/OWNERS
@@ -0,0 +1,14 @@
+set noparent
+
+tgunn@google.com
+breadley@google.com
+hallliu@google.com
+rgreenwalt@google.com
+amitmahajan@google.com
+fionaxu@google.com
+jackyu@google.com
+jminjie@google.com
+satk@google.com
+shuoq@google.com
+refuhoo@google.com
+nazaninb@google.com
diff --git a/telephony/java/android/telephony/MmsManager.java b/mms/java/android/telephony/MmsManager.java
index 4bcf04691652..4bcf04691652 100644
--- a/telephony/java/android/telephony/MmsManager.java
+++ b/mms/java/android/telephony/MmsManager.java
diff --git a/telephony/java/com/android/internal/telephony/IMms.aidl b/mms/java/com/android/internal/telephony/IMms.aidl
index fa5073ef1c7e..fa5073ef1c7e 100644
--- a/telephony/java/com/android/internal/telephony/IMms.aidl
+++ b/mms/java/com/android/internal/telephony/IMms.aidl
diff --git a/packages/CarSystemUI/res/layout/super_status_bar.xml b/packages/CarSystemUI/res/layout/super_status_bar.xml
index e1bcc2e5f86c..08d48bfb1230 100644
--- a/packages/CarSystemUI/res/layout/super_status_bar.xml
+++ b/packages/CarSystemUI/res/layout/super_status_bar.xml
@@ -93,7 +93,7 @@
android:layout_height="match_parent"
android:visibility="invisible"/>
- <include layout="@layout/status_bar_expanded"
+ <ViewStub android:id="@+id/status_bar_expanded"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"/>
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index d21f09ce160a..cc6e84259893 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -120,6 +120,7 @@ import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -294,7 +295,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
AssistManager assistManager,
NotificationListener notificationListener,
ConfigurationController configurationController,
- StatusBarWindowController statusBarWindowController) {
+ StatusBarWindowController statusBarWindowController,
+ StatusBarWindowViewController.Builder statusBarWindowViewControllerBuild) {
super(
lightBarController,
autoHideController,
@@ -347,7 +349,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
assistManager,
notificationListener,
configurationController,
- statusBarWindowController);
+ statusBarWindowController,
+ statusBarWindowViewControllerBuild);
mNavigationBarController = navigationBarController;
}
@@ -778,7 +781,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
return;
}
mStatusBarWindowController.setStatusBarFocusable(false);
- mStatusBarWindow.cancelExpandHelper();
+ mStatusBarWindowViewController.cancelExpandHelper();
mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);
animateNotificationPanel(mClosingVelocity, true);
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index b8372adfa074..67062b78e0de 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -100,8 +100,6 @@ public class SecureSettings {
Settings.Secure.DOZE_PICK_UP_GESTURE,
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
Settings.Secure.DOZE_TAP_SCREEN_GESTURE,
- Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
- Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED,
@@ -144,12 +142,9 @@ public class SecureSettings {
Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK,
Settings.Secure.UI_NIGHT_MODE,
Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST,
- Settings.Secure.SKIP_GESTURE,
Settings.Secure.SKIP_DIRECTION,
- Settings.Secure.SILENCE_GESTURE,
Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
Settings.Secure.NAVIGATION_MODE,
- Settings.Secure.AWARE_ENABLED,
Settings.Secure.SKIP_GESTURE_COUNT,
Settings.Secure.SKIP_TOUCH_COUNT,
Settings.Secure.SILENCE_ALARMS_GESTURE_COUNT,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 86625faab4d6..ebb9e86e1151 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -720,6 +720,11 @@ public class SettingsBackupTest {
Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED,
Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED,
Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED,
+ Settings.Secure.AWARE_ENABLED,
+ Settings.Secure.SKIP_GESTURE,
+ Settings.Secure.SILENCE_GESTURE,
+ Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
+ Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
Settings.Secure.FACE_UNLOCK_RE_ENROLL);
@Test
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index e7c6b2574f5f..0e59a41a8e2c 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -17,14 +17,9 @@
*/
-->
-<com.android.systemui.statusbar.phone.NotificationPanelView
+<merge
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:id="@+id/notification_panel"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@android:color/transparent" >
-
+ xmlns:systemui="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:id="@+id/big_clock_container"
android:layout_width="match_parent"
@@ -112,5 +107,4 @@
android:background="@drawable/qs_navbar_scrim" />
<include layout="@layout/status_bar_expanded_plugin_frame"/>
-
-</com.android.systemui.statusbar.phone.NotificationPanelView>
+</merge> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 9716a00a7f72..57834da76285 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -64,7 +64,7 @@
sysui:ignoreRightInset="true"
/>
- <include layout="@layout/status_bar_expanded"
+ <ViewStub android:id="@+id/status_bar_expanded"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 372718139886..04640f418e97 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -141,5 +141,8 @@
<!-- Global Actions Menu -->
<item type="id" name="global_actions_view" />
+
+ <!-- NotificationPanelView -->
+ <item type="id" name="notification_panel" />
</resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
index 5ddf89c08887..6186589ab086 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
@@ -17,6 +17,7 @@
package com.android.systemui.shared.system;
import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ITaskStackListener;
import android.content.ComponentName;
import android.os.IBinder;
import android.os.UserHandle;
@@ -106,6 +107,9 @@ public abstract class TaskStackChangeListener {
*/
public void onRecentTaskListUpdated() { }
+ /** @see ITaskStackListener#onRecentTaskListFrozenChanged(boolean) */
+ public void onRecentTaskListFrozenChanged(boolean frozen) { }
+
/**
* Checks that the current user matches the process. Since
* {@link android.app.ITaskStackListener} is not multi-user aware, handlers of
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index 820057a168a0..8d823ca34b39 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -224,6 +224,12 @@ public class TaskStackChangeListeners extends TaskStackListener {
mHandler.obtainMessage(H.ON_TASK_LIST_UPDATED).sendToTarget();
}
+ @Override
+ public void onRecentTaskListFrozenChanged(boolean frozen) {
+ mHandler.obtainMessage(H.ON_TASK_LIST_FROZEN_UNFROZEN, frozen ? 1 : 0, 0 /* unused */)
+ .sendToTarget();
+ }
+
private final class H extends Handler {
private static final int ON_TASK_STACK_CHANGED = 1;
private static final int ON_TASK_SNAPSHOT_CHANGED = 2;
@@ -247,6 +253,7 @@ public class TaskStackChangeListeners extends TaskStackListener {
private static final int ON_TASK_DISPLAY_CHANGED = 20;
private static final int ON_TASK_LIST_UPDATED = 21;
private static final int ON_SINGLE_TASK_DISPLAY_EMPTY = 22;
+ private static final int ON_TASK_LIST_FROZEN_UNFROZEN = 23;
public H(Looper looper) {
@@ -408,6 +415,12 @@ public class TaskStackChangeListeners extends TaskStackListener {
}
break;
}
+ case ON_TASK_LIST_FROZEN_UNFROZEN: {
+ for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+ mTaskStackListeners.get(i).onRecentTaskListFrozenChanged(msg.arg1 != 0);
+ }
+ break;
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index a97ec6442e14..ef9538dbef38 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -35,6 +35,7 @@ import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.internal.telephony.IccCardConstants;
@@ -66,6 +67,7 @@ public class CarrierTextController {
private WifiManager mWifiManager;
private boolean[] mSimErrorState;
private final int mSimSlotsNumber;
+ @Nullable // Check for nullability before dispatching
private CarrierTextCallback mCarrierTextCallback;
private Context mContext;
private CharSequence mSeparator;
@@ -74,12 +76,12 @@ public class CarrierTextController {
new WakefulnessLifecycle.Observer() {
@Override
public void onFinishedWakingUp() {
- mCarrierTextCallback.finishedWakingUp();
+ if (mCarrierTextCallback != null) mCarrierTextCallback.finishedWakingUp();
}
@Override
public void onStartedGoingToSleep() {
- mCarrierTextCallback.startedGoingToSleep();
+ if (mCarrierTextCallback != null) mCarrierTextCallback.startedGoingToSleep();
}
};
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 63da5339efe7..5a1c9976f021 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -22,7 +22,6 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Handler;
-import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -135,7 +134,7 @@ public class KeyguardStatusView extends GridLayout implements
super(context, attrs, defStyle);
mIActivityManager = ActivityManager.getService();
mLockPatternUtils = new LockPatternUtils(getContext());
- mHandler = new Handler(Looper.myLooper());
+ mHandler = new Handler();
onDensityOrFontScaleChanged();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index dc8ee16e8645..9bcccbc903dc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -118,12 +118,14 @@ import java.util.function.Consumer;
import javax.inject.Inject;
import javax.inject.Named;
+import javax.inject.Singleton;
/**
* Watches for updates that may be interesting to the keyguard, and provides
* the up to date information as well as a registration for callbacks that care
* to be updated.
*/
+@Singleton
public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private static final String TAG = "KeyguardUpdateMonitor";
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java
index 72831e99e122..176bcbfd9500 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java
@@ -19,8 +19,6 @@ package com.android.systemui;
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
-import android.content.Context;
-
import androidx.annotation.Nullable;
import com.android.systemui.dock.DockManager;
@@ -72,11 +70,8 @@ abstract class SystemUIDefaultModule {
abstract NotificationData.KeyguardEnvironment bindKeyguardEnvironment(
KeyguardEnvironmentImpl keyguardEnvironment);
- @Singleton
- @Provides
- static ShadeController provideShadeController(Context context) {
- return SysUiServiceProvider.getComponent(context, StatusBar.class);
- }
+ @Binds
+ abstract ShadeController provideShadeController(StatusBar statusBar);
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index 1e0a9f157ff5..176676fcb9b3 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -152,6 +152,20 @@ public class BrightnessController implements ToggleSlider.Listener {
private final Runnable mStartListeningRunnable = new Runnable() {
@Override
public void run() {
+ if (mListening) {
+ return;
+ }
+ mListening = true;
+
+ if (mVrManager != null) {
+ try {
+ mVrManager.registerListener(mVrStateCallbacks);
+ mIsVrModeEnabled = mVrManager.getVrModeState();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register VR mode state listener: ", e);
+ }
+ }
+
mBrightnessObserver.startObserving();
mUserTracker.startTracking();
@@ -167,6 +181,19 @@ public class BrightnessController implements ToggleSlider.Listener {
private final Runnable mStopListeningRunnable = new Runnable() {
@Override
public void run() {
+ if (!mListening) {
+ return;
+ }
+ mListening = false;
+
+ if (mVrManager != null) {
+ try {
+ mVrManager.unregisterListener(mVrStateCallbacks);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to unregister VR mode state listener: ", e);
+ }
+ }
+
mBrightnessObserver.stopObserving();
mUserTracker.stopTracking();
@@ -297,39 +324,12 @@ public class BrightnessController implements ToggleSlider.Listener {
}
public void registerCallbacks() {
- if (mListening) {
- return;
- }
-
- if (mVrManager != null) {
- try {
- mVrManager.registerListener(mVrStateCallbacks);
- mIsVrModeEnabled = mVrManager.getVrModeState();
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to register VR mode state listener: ", e);
- }
- }
-
mBackgroundHandler.post(mStartListeningRunnable);
- mListening = true;
}
/** Unregister all call backs, both to and from the controller */
public void unregisterCallbacks() {
- if (!mListening) {
- return;
- }
-
- if (mVrManager != null) {
- try {
- mVrManager.unregisterListener(mVrStateCallbacks);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to unregister VR mode state listener: ", e);
- }
- }
-
mBackgroundHandler.post(mStopListeningRunnable);
- mListening = false;
mControlValueInitialized = false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index 13c6f2730d08..9b312341c583 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -38,7 +38,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.NotificationPanelView;
-import com.android.systemui.statusbar.phone.StatusBarWindowView;
+import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
/**
* A class that allows activities to be launched in a seamless way where the notification
@@ -55,8 +55,8 @@ public class ActivityLaunchAnimator {
private static final long LAUNCH_TIMEOUT = 500;
private final NotificationPanelView mNotificationPanel;
private final NotificationListContainer mNotificationContainer;
- private final StatusBarWindowView mStatusBarWindow;
private final float mWindowCornerRadius;
+ private final StatusBarWindowViewController mStatusBarWindowViewController;
private Callback mCallback;
private final Runnable mTimeoutRunnable = () -> {
setAnimationPending(false);
@@ -66,16 +66,17 @@ public class ActivityLaunchAnimator {
private boolean mAnimationRunning;
private boolean mIsLaunchForActivity;
- public ActivityLaunchAnimator(StatusBarWindowView statusBarWindow,
+ public ActivityLaunchAnimator(
+ StatusBarWindowViewController statusBarWindowViewController,
Callback callback,
NotificationPanelView notificationPanel,
NotificationListContainer container) {
mNotificationPanel = notificationPanel;
mNotificationContainer = container;
- mStatusBarWindow = statusBarWindow;
+ mStatusBarWindowViewController = statusBarWindowViewController;
mCallback = callback;
mWindowCornerRadius = ScreenDecorationsUtils
- .getWindowCornerRadius(statusBarWindow.getResources());
+ .getWindowCornerRadius(mStatusBarWindowViewController.getView().getResources());
}
public RemoteAnimationAdapter getLaunchAnimation(
@@ -112,11 +113,11 @@ public class ActivityLaunchAnimator {
private void setAnimationPending(boolean pending) {
mAnimationPending = pending;
- mStatusBarWindow.setExpandAnimationPending(pending);
+ mStatusBarWindowViewController.setExpandAnimationPending(pending);
if (pending) {
- mStatusBarWindow.postDelayed(mTimeoutRunnable, LAUNCH_TIMEOUT);
+ mStatusBarWindowViewController.getView().postDelayed(mTimeoutRunnable, LAUNCH_TIMEOUT);
} else {
- mStatusBarWindow.removeCallbacks(mTimeoutRunnable);
+ mStatusBarWindowViewController.getView().removeCallbacks(mTimeoutRunnable);
}
}
@@ -246,7 +247,7 @@ public class ActivityLaunchAnimator {
private void setExpandAnimationRunning(boolean running) {
mNotificationPanel.setLaunchingNotification(running);
mSourceNotification.setExpandAnimationRunning(running);
- mStatusBarWindow.setExpandAnimationRunning(running);
+ mStatusBarWindowViewController.setExpandAnimationRunning(running);
mNotificationContainer.setExpandingNotification(running ? mSourceNotification : null);
mAnimationRunning = running;
if (!running) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index cee1d5da42cd..00736b73f12e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -408,14 +408,11 @@ public class NotificationPanelView extends PanelView implements
.setDuration(200)
.setAnimationFinishListener(mAnimatorListenerAdapter)
.setCustomInterpolator(PANEL_ALPHA.getProperty(), Interpolators.ALPHA_IN);
- private final NotificationEntryManager mEntryManager =
- Dependency.get(NotificationEntryManager.class);
+ private final NotificationEntryManager mEntryManager;
private final CommandQueue mCommandQueue;
- private final NotificationLockscreenUserManager mLockscreenUserManager =
- Dependency.get(NotificationLockscreenUserManager.class);
- private final ShadeController mShadeController =
- Dependency.get(ShadeController.class);
+ private final NotificationLockscreenUserManager mLockscreenUserManager;
+ private final ShadeController mShadeController;
private int mDisplayId;
/**
@@ -461,6 +458,9 @@ public class NotificationPanelView extends PanelView implements
KeyguardBypassController bypassController,
FalsingManager falsingManager,
PluginManager pluginManager,
+ ShadeController shadeController,
+ NotificationLockscreenUserManager notificationLockscreenUserManager,
+ NotificationEntryManager notificationEntryManager,
DozeLog dozeLog) {
super(context, attrs, falsingManager, dozeLog);
setWillNotDraw(!DEBUG);
@@ -495,6 +495,11 @@ public class NotificationPanelView extends PanelView implements
mBottomAreaShadeAlphaAnimator.setDuration(160);
mBottomAreaShadeAlphaAnimator.setInterpolator(Interpolators.ALPHA_OUT);
mPluginManager = pluginManager;
+ mShadeController = shadeController;
+ mLockscreenUserManager = notificationLockscreenUserManager;
+ mEntryManager = notificationEntryManager;
+
+ setBackgroundColor(Color.TRANSPARENT);
}
/**
@@ -509,9 +514,11 @@ public class NotificationPanelView extends PanelView implements
mKeyguardBottomArea.setStatusBar(mStatusBar);
}
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
+ /**
+ * Call after this view has been fully inflated and had its children attached.
+ */
+ public void onChildrenAttached() {
+ loadDimens();
mKeyguardStatusBar = findViewById(R.id.keyguard_header);
mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
@@ -554,7 +561,7 @@ public class NotificationPanelView extends PanelView implements
}
});
- Dependency.get(PluginManager.class).addPluginListener(
+ mPluginManager.addPluginListener(
new PluginListener<HomeControlsPlugin>() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index b1825c8ce667..6ce6dfaf3c20 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -243,9 +243,11 @@ import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
+import javax.inject.Singleton;
import dagger.Subcomponent;
+@Singleton
public class StatusBar extends SystemUI implements DemoMode,
ActivityStarter, KeyguardStateController.Callback,
OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
@@ -354,6 +356,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private final Point mCurrentDisplaySize = new Point();
+ protected StatusBarWindowViewController mStatusBarWindowViewController;
protected StatusBarWindowView mStatusBarWindow;
protected PhoneStatusBarView mStatusBarView;
private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
@@ -381,6 +384,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private final FalsingManager mFalsingManager;
private final BroadcastDispatcher mBroadcastDispatcher;
private final ConfigurationController mConfigurationController;
+ private final StatusBarWindowViewController.Builder mStatusBarWindowViewControllerBuilder;
// expanded notifications
protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -664,7 +668,8 @@ public class StatusBar extends SystemUI implements DemoMode,
AssistManager assistManager,
NotificationListener notificationListener,
ConfigurationController configurationController,
- StatusBarWindowController statusBarWindowController) {
+ StatusBarWindowController statusBarWindowController,
+ StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder) {
mLightBarController = lightBarController;
mAutoHideController = autoHideController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -717,6 +722,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mNotificationListener = notificationListener;
mConfigurationController = configurationController;
mStatusBarWindowController = statusBarWindowController;
+ mStatusBarWindowViewControllerBuilder = statusBarWindowViewControllerBuilder;
mBubbleExpandListener =
(isExpanding, key) -> {
@@ -882,8 +888,7 @@ public class StatusBar extends SystemUI implements DemoMode,
updateTheme();
inflateStatusBarWindow(context);
- mStatusBarWindow.setService(this);
- mStatusBarWindow.setBypassController(mKeyguardBypassController);
+ mStatusBarWindowViewController.setService(this);
mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
// TODO: Deal with the ugliness that comes from having some of the statusbar broken out
@@ -951,7 +956,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarStateController, mKeyguardBypassController,
mWakeUpCoordinator);
mHeadsUpAppearanceController.readFrom(oldController);
- mStatusBarWindow.setStatusBarView(mStatusBarView);
+ mStatusBarWindowViewController.setStatusBarView(mStatusBarView);
updateAreThereNotifications();
checkBarModes();
}).getFragmentManager()
@@ -1018,7 +1023,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarWindowController.setScrimsVisibility(scrimsVisible);
}
if (mStatusBarWindow != null) {
- mStatusBarWindow.onScrimVisibilityChanged(scrimsVisible);
+ mStatusBarWindowViewController.onScrimVisibilityChanged(scrimsVisible);
}
}, DozeParameters.getInstance(mContext),
mContext.getSystemService(AlarmManager.class),
@@ -1041,7 +1046,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
mNotificationPanel.setLaunchAffordanceListener(
- mStatusBarWindow::onShowingLaunchAffordanceChanged);
+ mStatusBarWindowViewController::onShowingLaunchAffordanceChanged);
// Set up the quick settings tile panel
View container = mStatusBarWindow.findViewById(R.id.qs_frame);
@@ -1147,7 +1152,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private void setUpPresenter() {
// Set up the initial notification state.
mActivityLaunchAnimator = new ActivityLaunchAnimator(
- mStatusBarWindow, this, mNotificationPanel,
+ mStatusBarWindowViewController, this, mNotificationPanel,
(NotificationListContainer) mStackScroller);
final NotificationRowBinderImpl rowBinder =
@@ -1319,6 +1324,10 @@ public class StatusBar extends SystemUI implements DemoMode,
protected void inflateStatusBarWindow(Context context) {
mStatusBarWindow = (StatusBarWindowView) mInjectionInflater.injectable(
LayoutInflater.from(context)).inflate(R.layout.super_status_bar, null);
+ mStatusBarWindowViewController = mStatusBarWindowViewControllerBuilder
+ .setStatusBarWindowView(mStatusBarWindow)
+ .setShadeController(this)
+ .build();
}
protected void startKeyguard() {
@@ -2021,7 +2030,7 @@ public class StatusBar extends SystemUI implements DemoMode,
// release focus immediately to kick off focus change transition
mStatusBarWindowController.setStatusBarFocusable(false);
- mStatusBarWindow.cancelExpandHelper();
+ mStatusBarWindowViewController.cancelExpandHelper();
mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);
} else {
mBubbleController.collapseStack();
@@ -2412,8 +2421,8 @@ public class StatusBar extends SystemUI implements DemoMode,
dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
}
pw.println(" StatusBarWindowView: ");
- if (mStatusBarWindow != null) {
- mStatusBarWindow.dump(fd, pw, args);
+ if (mStatusBarWindowViewController != null) {
+ mStatusBarWindowViewController.dump(fd, pw, args);
}
pw.println(" mMediaManager: ");
@@ -3707,7 +3716,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mBouncerShowing = bouncerShowing;
mKeyguardBypassController.setBouncerShowing(bouncerShowing);
mPulseExpansionHandler.setBouncerShowing(bouncerShowing);
- mStatusBarWindow.setBouncerShowingScrimmed(isBouncerShowingScrimmed());
+ mStatusBarWindowViewController.setBouncerShowingScrimmed(isBouncerShowingScrimmed());
if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing);
updateHideIconsForBouncer(true /* animate */);
mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
@@ -3722,7 +3731,7 @@ public class StatusBar extends SystemUI implements DemoMode,
*/
public void collapseShade() {
if (mNotificationPanel.isTracking()) {
- mStatusBarWindow.cancelCurrentTouch();
+ mStatusBarWindowViewController.cancelCurrentTouch();
}
if (mPanelExpanded && mState == StatusBarState.SHADE) {
animateCollapsePanels();
@@ -3743,7 +3752,7 @@ public class StatusBar extends SystemUI implements DemoMode,
updateVisibleToUser();
updateNotificationPanelTouchState();
- mStatusBarWindow.cancelCurrentTouch();
+ mStatusBarWindowViewController.cancelCurrentTouch();
if (mLaunchCameraOnFinishedGoingToSleep) {
mLaunchCameraOnFinishedGoingToSleep = false;
@@ -3961,7 +3970,8 @@ public class StatusBar extends SystemUI implements DemoMode,
public void notifyBiometricAuthModeChanged() {
updateDozing();
updateScrimController();
- mStatusBarWindow.onBiometricAuthModeChanged(mBiometricUnlockController.isWakeAndUnlock(),
+ mStatusBarWindowViewController.onBiometricAuthModeChanged(
+ mBiometricUnlockController.isWakeAndUnlock(),
mBiometricUnlockController.isBiometricUnlock());
}
@@ -4082,7 +4092,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
if (reason == DozeEvent.PULSE_REASON_DOCKING && mStatusBarWindow != null) {
- mStatusBarWindow.suppressWakeUpGesture(true);
+ mStatusBarWindowViewController.suppressWakeUpGesture(true);
}
boolean passiveAuthInterrupt = reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
@@ -4106,7 +4116,7 @@ public class StatusBar extends SystemUI implements DemoMode,
updateNotificationPanelTouchState();
mScrimController.setWakeLockScreenSensorActive(false);
if (mStatusBarWindow != null) {
- mStatusBarWindow.suppressWakeUpGesture(false);
+ mStatusBarWindowViewController.suppressWakeUpGesture(false);
}
setPulsing(false);
}
@@ -4117,7 +4127,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mKeyguardViewMediator.setPulsing(pulsing);
mNotificationPanel.setPulsing(pulsing);
mVisualStabilityManager.setPulsing(pulsing);
- mStatusBarWindow.setPulsing(pulsing);
+ mStatusBarWindowViewController.setPulsing(pulsing);
mIgnoreTouchWhilePulsing = false;
if (mKeyguardUpdateMonitor != null && passiveAuthInterrupt) {
mKeyguardUpdateMonitor.onAuthInterruptDetected(pulsing /* active */);
@@ -4148,7 +4158,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
mIgnoreTouchWhilePulsing = ignore;
if (isDozing() && ignore) {
- mStatusBarWindow.cancelCurrentTouch();
+ mStatusBarWindowViewController.cancelCurrentTouch();
}
}
@@ -4603,7 +4613,7 @@ public class StatusBar extends SystemUI implements DemoMode,
*/
public void onBouncerPreHideAnimation() {
mNotificationPanel.onBouncerPreHideAnimation();
- mStatusBarWindow.onBouncerPreHideAnimation();
+ mStatusBarWindowViewController.onBouncerPreHideAnimation();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index a9e818df6bc3..d04c7bd38320 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -19,29 +19,18 @@ package com.android.systemui.statusbar.phone;
import android.annotation.ColorInt;
import android.annotation.DrawableRes;
import android.annotation.LayoutRes;
-import android.app.StatusBarManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.hardware.display.AmbientDisplayConfiguration;
-import android.media.AudioManager;
-import android.media.session.MediaSessionLegacyHelper;
import android.net.Uri;
import android.os.Bundle;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.DisplayCutout;
-import android.view.GestureDetector;
-import android.view.InputDevice;
import android.view.InputQueue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -56,21 +45,9 @@ import android.view.Window;
import android.view.WindowInsetsController;
import android.widget.FrameLayout;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.view.FloatingActionMode;
import com.android.internal.widget.FloatingToolbar;
-import com.android.systemui.Dependency;
-import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
-import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.DragDownHelper;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
-import com.android.systemui.statusbar.phone.ScrimController.ScrimVisibility;
-import com.android.systemui.tuner.TunerService;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
/**
* Combined status bar and notification panel view. Also holding backdrop and scrims.
@@ -79,87 +56,21 @@ public class StatusBarWindowView extends FrameLayout {
public static final String TAG = "StatusBarWindowView";
public static final boolean DEBUG = StatusBar.DEBUG;
- private final GestureDetector mGestureDetector;
- private final StatusBarStateController mStatusBarStateController;
- private boolean mDoubleTapEnabled;
- private boolean mSingleTapEnabled;
- private DragDownHelper mDragDownHelper;
- private NotificationStackScrollLayout mStackScrollLayout;
- private NotificationPanelView mNotificationPanel;
- private View mBrightnessMirror;
- private LockIcon mLockIcon;
- private PhoneStatusBarView mStatusBarView;
-
private int mRightInset = 0;
private int mLeftInset = 0;
- private StatusBar mService;
- private final Paint mTransparentSrcPaint = new Paint();
- private FalsingManager mFalsingManager;
-
// Implements the floating action mode for TextView's Cut/Copy/Past menu. Normally provided by
// DecorView, but since this is a special window we have to roll our own.
private View mFloatingActionModeOriginatingView;
private ActionMode mFloatingActionMode;
private FloatingToolbar mFloatingToolbar;
private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener;
- private boolean mTouchCancelled;
- private boolean mTouchActive;
- private boolean mExpandAnimationRunning;
- private boolean mExpandAnimationPending;
- private boolean mSuppressingWakeUpGesture;
-
- private final GestureDetector.SimpleOnGestureListener mGestureListener =
- new GestureDetector.SimpleOnGestureListener() {
- @Override
- public boolean onSingleTapConfirmed(MotionEvent e) {
- if (mSingleTapEnabled && !mSuppressingWakeUpGesture) {
- mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this,
- "SINGLE_TAP");
- return true;
- }
- return false;
- }
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- if (mDoubleTapEnabled || mSingleTapEnabled) {
- mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this,
- "DOUBLE_TAP");
- return true;
- }
- return false;
- }
- };
- private final TunerService.Tunable mTunable = (key, newValue) -> {
- AmbientDisplayConfiguration configuration = new AmbientDisplayConfiguration(mContext);
- switch (key) {
- case Settings.Secure.DOZE_DOUBLE_TAP_GESTURE:
- mDoubleTapEnabled = configuration.doubleTapGestureEnabled(UserHandle.USER_CURRENT);
- break;
- case Settings.Secure.DOZE_TAP_SCREEN_GESTURE:
- mSingleTapEnabled = configuration.tapGestureEnabled(UserHandle.USER_CURRENT);
- }
- };
-
- /**
- * If set to true, the current gesture started below the notch and we need to dispatch touch
- * events manually as it's outside of the regular view bounds.
- */
- private boolean mExpandingBelowNotch;
- private KeyguardBypassController mBypassController;
+ private InteractionEventHandler mInteractionEventHandler;
public StatusBarWindowView(Context context, AttributeSet attrs) {
super(context, attrs);
setMotionEventSplittingEnabled(false);
- mTransparentSrcPaint.setColor(0);
- mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
- mFalsingManager = Dependency.get(FalsingManager.class); // TODO: inject into a controller.
- mGestureDetector = new GestureDetector(context, mGestureListener);
- mStatusBarStateController = Dependency.get(StatusBarStateController.class);
- Dependency.get(TunerService.class).addTunable(mTunable,
- Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
- Settings.Secure.DOZE_TAP_SCREEN_GESTURE);
}
@Override
@@ -226,11 +137,6 @@ public class StatusBarWindowView extends FrameLayout {
}
}
- @VisibleForTesting
- protected NotificationStackScrollLayout getStackScrollLayout() {
- return mStackScrollLayout;
- }
-
@Override
public FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
@@ -242,61 +148,6 @@ public class StatusBarWindowView extends FrameLayout {
}
@Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mStackScrollLayout = findViewById(R.id.notification_stack_scroller);
- mNotificationPanel = findViewById(R.id.notification_panel);
- mBrightnessMirror = findViewById(R.id.brightness_mirror);
- mLockIcon = findViewById(R.id.lock_icon);
- }
-
- @Override
- public void onViewAdded(View child) {
- super.onViewAdded(child);
- if (child.getId() == R.id.brightness_mirror) {
- mBrightnessMirror = child;
- }
- }
-
- /**
- * Propagate {@link StatusBar} pulsing state.
- */
- public void setPulsing(boolean pulsing) {
- if (mLockIcon != null) {
- mLockIcon.setPulsing(pulsing);
- }
- }
-
- /**
- * Called when the biometric authentication mode changes.
- * @param wakeAndUnlock If the type is {@link BiometricUnlockController#isWakeAndUnlock()}
- * @param isUnlock If the type is {@link BiometricUnlockController#isBiometricUnlock()} ()
- */
- public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
- if (mLockIcon != null) {
- mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock, isUnlock);
- }
- }
-
- public void setStatusBarView(PhoneStatusBarView statusBarView) {
- mStatusBarView = statusBarView;
- }
-
- public void setService(StatusBar service) {
- mService = service;
- NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
- ExpandHelper.Callback expandHelperCallback = stackScrollLayout.getExpandHelperCallback();
- DragDownHelper.DragDownCallback dragDownCallback = stackScrollLayout.getDragDownCallback();
- setDragDownHelper(new DragDownHelper(getContext(), this, expandHelperCallback,
- dragDownCallback, mFalsingManager));
- }
-
- @VisibleForTesting
- void setDragDownHelper(DragDownHelper dragDownHelper) {
- mDragDownHelper = dragDownHelper;
- }
-
- @Override
protected void onAttachedToWindow () {
super.onAttachedToWindow();
setWillNotDraw(!DEBUG);
@@ -304,152 +155,53 @@ public class StatusBarWindowView extends FrameLayout {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- if (mService.interceptMediaKey(event)) {
+ if (mInteractionEventHandler.interceptMediaKey(event)) {
return true;
}
+
if (super.dispatchKeyEvent(event)) {
return true;
}
- boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
- switch (event.getKeyCode()) {
- case KeyEvent.KEYCODE_BACK:
- if (!down) {
- mService.onBackPressed();
- }
- return true;
- case KeyEvent.KEYCODE_MENU:
- if (!down) {
- return mService.onMenuPressed();
- }
- case KeyEvent.KEYCODE_SPACE:
- if (!down) {
- return mService.onSpacePressed();
- }
- break;
- case KeyEvent.KEYCODE_VOLUME_DOWN:
- case KeyEvent.KEYCODE_VOLUME_UP:
- if (mService.isDozing()) {
- MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(
- event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
- return true;
- }
- break;
- }
- return false;
- }
- public void setTouchActive(boolean touchActive) {
- mTouchActive = touchActive;
+ return mInteractionEventHandler.dispatchKeyEvent(event);
}
- void suppressWakeUpGesture(boolean suppress) {
- mSuppressingWakeUpGesture = suppress;
+ protected void setInteractionEventHandler(InteractionEventHandler listener) {
+ mInteractionEventHandler = listener;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
- boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
- boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
- boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;
-
- // Reset manual touch dispatch state here but make sure the UP/CANCEL event still gets
- // delivered.
- boolean expandingBelowNotch = mExpandingBelowNotch;
- if (isUp || isCancel) {
- mExpandingBelowNotch = false;
- }
+ Boolean result = mInteractionEventHandler.handleDispatchTouchEvent(ev);
- if (!isCancel && mService.shouldIgnoreTouch()) {
- return false;
- }
- if (isDown && mNotificationPanel.isFullyCollapsed()) {
- mNotificationPanel.startExpandLatencyTracking();
- }
- if (isDown) {
- setTouchActive(true);
- mTouchCancelled = false;
- } else if (ev.getActionMasked() == MotionEvent.ACTION_UP
- || ev.getActionMasked() == MotionEvent.ACTION_CANCEL) {
- setTouchActive(false);
- }
- if (mTouchCancelled || mExpandAnimationRunning || mExpandAnimationPending) {
- return false;
- }
- mFalsingManager.onTouchEvent(ev, getWidth(), getHeight());
- mGestureDetector.onTouchEvent(ev);
- if (mBrightnessMirror != null && mBrightnessMirror.getVisibility() == VISIBLE) {
- // Disallow new pointers while the brightness mirror is visible. This is so that you
- // can't touch anything other than the brightness slider while the mirror is showing
- // and the rest of the panel is transparent.
- if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
- return false;
- }
- }
- if (isDown) {
- getStackScrollLayout().closeControlsIfOutsideTouch(ev);
- }
- if (mService.isDozing()) {
- mService.mDozeScrimController.extendPulse();
- }
-
- // In case we start outside of the view bounds (below the status bar), we need to dispatch
- // the touch manually as the view system can't accomodate for touches outside of the
- // regular view bounds.
- if (isDown && ev.getY() >= mBottom) {
- mExpandingBelowNotch = true;
- expandingBelowNotch = true;
- }
- if (expandingBelowNotch) {
- return mStatusBarView.dispatchTouchEvent(ev);
- }
-
- return super.dispatchTouchEvent(ev);
+ return result != null ? result : super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
- NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
- if (mService.isDozing() && !mService.isPulsing()) {
- // Capture all touch events in always-on.
- return true;
- }
- boolean intercept = false;
- if (mNotificationPanel.isFullyExpanded()
- && mDragDownHelper.isDragDownEnabled()
- && !mService.isBouncerShowing()
- && !mService.isDozing()) {
- intercept = mDragDownHelper.onInterceptTouchEvent(ev);
- }
+ boolean intercept = mInteractionEventHandler.shouldInterceptTouchEvent(ev);
if (!intercept) {
- super.onInterceptTouchEvent(ev);
+ intercept = super.onInterceptTouchEvent(ev);
}
if (intercept) {
- MotionEvent cancellation = MotionEvent.obtain(ev);
- cancellation.setAction(MotionEvent.ACTION_CANCEL);
- stackScrollLayout.onInterceptTouchEvent(cancellation);
- mNotificationPanel.onInterceptTouchEvent(cancellation);
- cancellation.recycle();
+ mInteractionEventHandler.didIntercept(ev);
}
+
return intercept;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
- boolean handled = false;
- if (mService.isDozing()) {
- handled = !mService.isPulsing();
- }
- if ((mDragDownHelper.isDragDownEnabled() && !handled) || mDragDownHelper.isDraggingDown()) {
- // we still want to finish our drag down gesture when locking the screen
- handled = mDragDownHelper.onTouchEvent(ev);
- }
+ boolean handled = mInteractionEventHandler.handleTouchEvent(ev);
+
if (!handled) {
handled = super.onTouchEvent(ev);
}
- final int action = ev.getAction();
- if (!handled && (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL)) {
- mService.setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
+
+ if (!handled) {
+ mInteractionEventHandler.didNotHandleTouchEvent(ev);
}
+
return handled;
}
@@ -465,77 +217,6 @@ public class StatusBarWindowView extends FrameLayout {
}
}
- public void cancelExpandHelper() {
- NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
- if (stackScrollLayout != null) {
- stackScrollLayout.cancelExpandHelper();
- }
- }
-
- public void cancelCurrentTouch() {
- if (mTouchActive) {
- final long now = SystemClock.uptimeMillis();
- MotionEvent event = MotionEvent.obtain(now, now,
- MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
- event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
- dispatchTouchEvent(event);
- event.recycle();
- mTouchCancelled = true;
- }
- }
-
- public void setExpandAnimationRunning(boolean expandAnimationRunning) {
- mExpandAnimationRunning = expandAnimationRunning;
- }
-
- public void setExpandAnimationPending(boolean pending) {
- mExpandAnimationPending = pending;
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.print(" mExpandAnimationPending="); pw.println(mExpandAnimationPending);
- pw.print(" mExpandAnimationRunning="); pw.println(mExpandAnimationRunning);
- pw.print(" mTouchCancelled="); pw.println(mTouchCancelled);
- pw.print(" mTouchActive="); pw.println(mTouchActive);
- }
-
- /**
- * Called whenever the scrims become opaque, transparent or semi-transparent.
- */
- public void onScrimVisibilityChanged(@ScrimVisibility int scrimsVisible) {
- if (mLockIcon != null) {
- mLockIcon.onScrimVisibilityChanged(scrimsVisible);
- }
- }
-
- /**
- * When we're launching an affordance, like double pressing power to open camera.
- */
- public void onShowingLaunchAffordanceChanged(boolean showing) {
- if (mLockIcon != null) {
- mLockIcon.onShowingLaunchAffordanceChanged(showing);
- }
- }
-
- public void setBypassController(KeyguardBypassController bypassController) {
- mBypassController = bypassController;
- }
-
- public void setBouncerShowingScrimmed(boolean bouncerShowing) {
- if (mLockIcon != null) {
- mLockIcon.setBouncerShowingScrimmed(bouncerShowing);
- }
- }
-
- /**
- * When {@link KeyguardBouncer} starts to be dismissed and starts to play its animation.
- */
- public void onBouncerPreHideAnimation() {
- if (mLockIcon != null) {
- mLockIcon.onBouncerPreHideAnimation();
- }
- }
-
public class LayoutParams extends FrameLayout.LayoutParams {
public boolean ignoreRightInset;
@@ -657,6 +338,35 @@ public class StatusBarWindowView extends FrameLayout {
}
}
+ interface InteractionEventHandler {
+ /**
+ * Returns a result for {@link ViewGroup#dispatchTouchEvent(MotionEvent)} or null to defer
+ * to the super method.
+ */
+ Boolean handleDispatchTouchEvent(MotionEvent ev);
+
+ /**
+ * Returns if the view should intercept the touch event.
+ *
+ * The touch event may still be interecepted if
+ * {@link ViewGroup#onInterceptTouchEvent(MotionEvent)} decides to do so.
+ */
+ boolean shouldInterceptTouchEvent(MotionEvent ev);
+
+ /**
+ * Called when the view decides to intercept the touch event.
+ */
+ void didIntercept(MotionEvent ev);
+
+ boolean handleTouchEvent(MotionEvent ev);
+
+ void didNotHandleTouchEvent(MotionEvent ev);
+
+ boolean interceptMediaKey(KeyEvent event);
+
+ boolean dispatchKeyEvent(KeyEvent event);
+ }
+
/**
* Minimal window to satisfy FloatingToolbar.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
new file mode 100644
index 000000000000..f21085ef0b1d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.app.StatusBarManager;
+import android.hardware.display.AmbientDisplayConfiguration;
+import android.media.AudioManager;
+import android.media.session.MediaSessionLegacyHelper;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.view.GestureDetector;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewStub;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.ExpandHelper;
+import com.android.systemui.R;
+import com.android.systemui.doze.DozeLog;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.DragDownHelper;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.InjectionInflationController;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import javax.inject.Inject;
+
+/**
+ * Controller for {@link StatusBarWindowView}.
+ */
+public class StatusBarWindowViewController {
+ private final StatusBarWindowView mView;
+ private final FalsingManager mFalsingManager;
+ private final GestureDetector mGestureDetector;
+ private View mBrightnessMirror;
+ private boolean mTouchActive;
+ private boolean mTouchCancelled;
+ private boolean mExpandAnimationPending;
+ private boolean mExpandAnimationRunning;
+ private NotificationStackScrollLayout mStackScrollLayout;
+ private LockIcon mLockIcon;
+ private PhoneStatusBarView mStatusBarView;
+ private StatusBar mService;
+ private DragDownHelper mDragDownHelper;
+ private boolean mSuppressingWakeUpGesture;
+ private boolean mDoubleTapEnabled;
+ private boolean mSingleTapEnabled;
+ private boolean mExpandingBelowNotch;
+
+ private StatusBarWindowViewController(
+ StatusBarWindowView view,
+ InjectionInflationController injectionInflationController,
+ NotificationWakeUpCoordinator coordinator,
+ PulseExpansionHandler pulseExpansionHandler,
+ DynamicPrivacyController dynamicPrivacyController,
+ KeyguardBypassController bypassController,
+ FalsingManager falsingManager,
+ PluginManager pluginManager,
+ TunerService tunerService,
+ ShadeController shadeController,
+ NotificationLockscreenUserManager notificationLockscreenUserManager,
+ NotificationEntryManager notificationEntryManager,
+ DozeLog dozeLog) {
+ mView = view;
+ mFalsingManager = falsingManager;
+
+ // TODO: create controller for NotificationPanelView
+ NotificationPanelView notificationPanelView = new NotificationPanelView(
+ view.getContext(),
+ null,
+ injectionInflationController,
+ coordinator,
+ pulseExpansionHandler,
+ dynamicPrivacyController,
+ bypassController,
+ falsingManager,
+ pluginManager,
+ shadeController,
+ notificationLockscreenUserManager,
+ notificationEntryManager,
+ dozeLog);
+ ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ notificationPanelView.setVisibility(View.INVISIBLE);
+ notificationPanelView.setId(R.id.notification_panel);
+ LayoutInflater li = injectionInflationController.injectable(
+ LayoutInflater.from(mView.getContext()));
+
+ li.inflate(R.layout.status_bar_expanded, notificationPanelView);
+ notificationPanelView.onChildrenAttached();
+
+ ViewStub statusBarExpanded = view.findViewById(R.id.status_bar_expanded);
+ mView.addView(notificationPanelView, mView.indexOfChild(statusBarExpanded), lp);
+ mView.removeView(statusBarExpanded);
+
+ mStackScrollLayout = mView.findViewById(R.id.notification_stack_scroller);
+ mLockIcon = mView.findViewById(R.id.lock_icon);
+ mBrightnessMirror = mView.findViewById(R.id.brightness_mirror);
+
+ TunerService.Tunable tunable = (key, newValue) -> {
+ AmbientDisplayConfiguration configuration =
+ new AmbientDisplayConfiguration(mView.getContext());
+ switch (key) {
+ case Settings.Secure.DOZE_DOUBLE_TAP_GESTURE:
+ mDoubleTapEnabled = configuration.doubleTapGestureEnabled(
+ UserHandle.USER_CURRENT);
+ break;
+ case Settings.Secure.DOZE_TAP_SCREEN_GESTURE:
+ mSingleTapEnabled = configuration.tapGestureEnabled(UserHandle.USER_CURRENT);
+ }
+ };
+ tunerService.addTunable(tunable,
+ Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
+ Settings.Secure.DOZE_TAP_SCREEN_GESTURE);
+
+ GestureDetector.SimpleOnGestureListener gestureListener =
+ new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent e) {
+ if (mSingleTapEnabled && !mSuppressingWakeUpGesture) {
+ mService.wakeUpIfDozing(
+ SystemClock.uptimeMillis(), mView, "SINGLE_TAP");
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ if (mDoubleTapEnabled || mSingleTapEnabled) {
+ mService.wakeUpIfDozing(
+ SystemClock.uptimeMillis(), mView, "DOUBLE_TAP");
+ return true;
+ }
+ return false;
+ }
+ };
+ mGestureDetector = new GestureDetector(mView.getContext(), gestureListener);
+
+ mView.setInteractionEventHandler(new StatusBarWindowView.InteractionEventHandler() {
+ @Override
+ public Boolean handleDispatchTouchEvent(MotionEvent ev) {
+ boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
+ boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
+ boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;
+
+ if (isUp || isCancel) {
+ mExpandingBelowNotch = false;
+ }
+
+ // Reset manual touch dispatch state here but make sure the UP/CANCEL event still
+ // gets
+ // delivered.
+
+ if (!isCancel && mService.shouldIgnoreTouch()) {
+ return false;
+ }
+ if (isDown && notificationPanelView.isFullyCollapsed()) {
+ notificationPanelView.startExpandLatencyTracking();
+ }
+ if (isDown) {
+ setTouchActive(true);
+ mTouchCancelled = false;
+ } else if (ev.getActionMasked() == MotionEvent.ACTION_UP
+ || ev.getActionMasked() == MotionEvent.ACTION_CANCEL) {
+ setTouchActive(false);
+ }
+ if (mTouchCancelled || mExpandAnimationRunning || mExpandAnimationPending) {
+ return false;
+ }
+ mFalsingManager.onTouchEvent(ev, mView.getWidth(), mView.getHeight());
+ mGestureDetector.onTouchEvent(ev);
+ if (mBrightnessMirror != null
+ && mBrightnessMirror.getVisibility() == View.VISIBLE) {
+ // Disallow new pointers while the brightness mirror is visible. This is so that
+ // you can't touch anything other than the brightness slider while the mirror is
+ // showing and the rest of the panel is transparent.
+ if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
+ return false;
+ }
+ }
+ if (isDown) {
+ getStackScrollLayout().closeControlsIfOutsideTouch(ev);
+ }
+ if (mService.isDozing()) {
+ mService.mDozeScrimController.extendPulse();
+ }
+ // In case we start outside of the view bounds (below the status bar), we need to
+ // dispatch
+ // the touch manually as the view system can't accommodate for touches outside of
+ // the
+ // regular view bounds.
+ if (isDown && ev.getY() >= mView.getBottom()) {
+ mExpandingBelowNotch = true;
+ }
+ if (mExpandingBelowNotch) {
+ return mStatusBarView.dispatchTouchEvent(ev);
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean shouldInterceptTouchEvent(MotionEvent ev) {
+ if (mService.isDozing() && !mService.isPulsing()) {
+ // Capture all touch events in always-on.
+ return true;
+ }
+ boolean intercept = false;
+ if (notificationPanelView.isFullyExpanded()
+ && mDragDownHelper.isDragDownEnabled()
+ && !mService.isBouncerShowing()
+ && !mService.isDozing()) {
+ intercept = mDragDownHelper.onInterceptTouchEvent(ev);
+ }
+
+ return intercept;
+
+ }
+
+ @Override
+ public void didIntercept(MotionEvent ev) {
+ NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
+ MotionEvent cancellation = MotionEvent.obtain(ev);
+ cancellation.setAction(MotionEvent.ACTION_CANCEL);
+ stackScrollLayout.onInterceptTouchEvent(cancellation);
+ notificationPanelView.onInterceptTouchEvent(cancellation);
+ cancellation.recycle();
+ }
+
+ @Override
+ public boolean handleTouchEvent(MotionEvent ev) {
+ boolean handled = false;
+ if (mService.isDozing()) {
+ handled = !mService.isPulsing();
+ }
+ if ((mDragDownHelper.isDragDownEnabled() && !handled)
+ || mDragDownHelper.isDraggingDown()) {
+ // we still want to finish our drag down gesture when locking the screen
+ handled = mDragDownHelper.onTouchEvent(ev);
+ }
+
+ return handled;
+ }
+
+ @Override
+ public void didNotHandleTouchEvent(MotionEvent ev) {
+ final int action = ev.getActionMasked();
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ mService.setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
+ }
+ }
+
+ @Override
+ public boolean interceptMediaKey(KeyEvent event) {
+ return mService.interceptMediaKey(event);
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
+ switch (event.getKeyCode()) {
+ case KeyEvent.KEYCODE_BACK:
+ if (!down) {
+ mService.onBackPressed();
+ }
+ return true;
+ case KeyEvent.KEYCODE_MENU:
+ if (!down) {
+ return mService.onMenuPressed();
+ }
+ break;
+ case KeyEvent.KEYCODE_SPACE:
+ if (!down) {
+ return mService.onSpacePressed();
+ }
+ break;
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ if (mService.isDozing()) {
+ MediaSessionLegacyHelper.getHelper(mView.getContext())
+ .sendVolumeKeyEvent(
+ event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
+ return true;
+ }
+ break;
+ }
+ return false;
+ }
+ });
+
+ mView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
+ @Override
+ public void onChildViewAdded(View parent, View child) {
+ if (child.getId() == R.id.brightness_mirror) {
+ mBrightnessMirror = child;
+ }
+ }
+
+ @Override
+ public void onChildViewRemoved(View parent, View child) {
+ }
+ });
+ }
+
+ public StatusBarWindowView getView() {
+ return mView;
+ }
+
+ public void setTouchActive(boolean touchActive) {
+ mTouchActive = touchActive;
+ }
+
+ public void cancelCurrentTouch() {
+ if (mTouchActive) {
+ final long now = SystemClock.uptimeMillis();
+ MotionEvent event = MotionEvent.obtain(now, now,
+ MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
+ event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ mView.dispatchTouchEvent(event);
+ event.recycle();
+ mTouchCancelled = true;
+ }
+ }
+
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.print(" mExpandAnimationPending=");
+ pw.println(mExpandAnimationPending);
+ pw.print(" mExpandAnimationRunning=");
+ pw.println(mExpandAnimationRunning);
+ pw.print(" mTouchCancelled=");
+ pw.println(mTouchCancelled);
+ pw.print(" mTouchActive=");
+ pw.println(mTouchActive);
+ }
+
+ public void setExpandAnimationPending(boolean pending) {
+ mExpandAnimationPending = pending;
+ }
+
+ public void setExpandAnimationRunning(boolean running) {
+ mExpandAnimationRunning = running;
+ }
+
+ public void cancelExpandHelper() {
+ NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
+ if (stackScrollLayout != null) {
+ stackScrollLayout.cancelExpandHelper();
+ }
+ }
+
+ @VisibleForTesting
+ protected NotificationStackScrollLayout getStackScrollLayout() {
+ return mStackScrollLayout;
+ }
+
+ /**
+ * Called whenever the scrims become opaque, transparent or semi-transparent.
+ */
+ public void onScrimVisibilityChanged(Integer scrimsVisible) {
+ if (mLockIcon != null) {
+ mLockIcon.onScrimVisibilityChanged(scrimsVisible);
+ }
+ }
+
+ /**
+ * Propagate {@link StatusBar} pulsing state.
+ */
+ public void setPulsing(boolean pulsing) {
+ if (mLockIcon != null) {
+ mLockIcon.setPulsing(pulsing);
+ }
+ }
+
+ /**
+ * Called when the biometric authentication mode changes.
+ *
+ * @param wakeAndUnlock If the type is {@link BiometricUnlockController#isWakeAndUnlock()}
+ * @param isUnlock If the type is {@link BiometricUnlockController#isBiometricUnlock()} ()
+ */
+ public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
+ if (mLockIcon != null) {
+ mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock, isUnlock);
+ }
+ }
+
+ public void setStatusBarView(PhoneStatusBarView statusBarView) {
+ mStatusBarView = statusBarView;
+ }
+
+ public void setService(StatusBar statusBar) {
+ mService = statusBar;
+ NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
+ ExpandHelper.Callback expandHelperCallback = stackScrollLayout.getExpandHelperCallback();
+ DragDownHelper.DragDownCallback dragDownCallback = stackScrollLayout.getDragDownCallback();
+ setDragDownHelper(
+ new DragDownHelper(
+ mView.getContext(), mView, expandHelperCallback,
+ dragDownCallback, mFalsingManager));
+ }
+
+ @VisibleForTesting
+ void setDragDownHelper(DragDownHelper dragDownHelper) {
+ mDragDownHelper = dragDownHelper;
+ }
+
+ public void suppressWakeUpGesture(boolean suppress) {
+ mSuppressingWakeUpGesture = suppress;
+ }
+
+ /**
+ * When we're launching an affordance, like double pressing power to open camera.
+ */
+ public void onShowingLaunchAffordanceChanged(Boolean showing) {
+ if (mLockIcon != null) {
+ mLockIcon.onShowingLaunchAffordanceChanged(showing);
+ }
+ }
+
+ public void setBouncerShowingScrimmed(boolean bouncerShowing) {
+ if (mLockIcon != null) {
+ mLockIcon.setBouncerShowingScrimmed(bouncerShowing);
+ }
+ }
+
+ /**
+ * When {@link KeyguardBouncer} starts to be dismissed and starts to play its animation.
+ */
+ public void onBouncerPreHideAnimation() {
+ if (mLockIcon != null) {
+ mLockIcon.onBouncerPreHideAnimation();
+ }
+ }
+
+ /**
+ * Builder for {@link StatusBarWindowViewController}.
+ */
+ public static class Builder {
+ private final InjectionInflationController mInjectionInflationController;
+ private final NotificationWakeUpCoordinator mCoordinator;
+ private final PulseExpansionHandler mPulseExpansionHandler;
+ private final DynamicPrivacyController mDynamicPrivacyController;
+ private final KeyguardBypassController mBypassController;
+ private final FalsingManager mFalsingManager;
+ private final PluginManager mPluginManager;
+ private final TunerService mTunerService;
+ private ShadeController mShadeController;
+ private final NotificationLockscreenUserManager mNotificationLockScreenUserManager;
+ private final NotificationEntryManager mNotificationEntryManager;
+ private final DozeLog mDozeLog;
+ private StatusBarWindowView mView;
+
+ @Inject
+ public Builder(
+ InjectionInflationController injectionInflationController,
+ NotificationWakeUpCoordinator coordinator,
+ PulseExpansionHandler pulseExpansionHandler,
+ DynamicPrivacyController dynamicPrivacyController,
+ KeyguardBypassController bypassController,
+ FalsingManager falsingManager,
+ PluginManager pluginManager,
+ TunerService tunerService,
+ NotificationLockscreenUserManager notificationLockscreenUserManager,
+ NotificationEntryManager notificationEntryManager,
+ DozeLog dozeLog) {
+ mInjectionInflationController = injectionInflationController;
+ mCoordinator = coordinator;
+ mPulseExpansionHandler = pulseExpansionHandler;
+ mDynamicPrivacyController = dynamicPrivacyController;
+ mBypassController = bypassController;
+ mFalsingManager = falsingManager;
+ mPluginManager = pluginManager;
+ mTunerService = tunerService;
+ mNotificationLockScreenUserManager = notificationLockscreenUserManager;
+ mNotificationEntryManager = notificationEntryManager;
+ mDozeLog = dozeLog;
+ }
+
+ /**
+ * Provide {@link StatusBarWindowView} to attach this controller to.
+ */
+ public Builder setStatusBarWindowView(StatusBarWindowView view) {
+ mView = view;
+ return this;
+ }
+
+ /**
+ * Provide {@link ShadeController} that this view needs.
+ */
+ public Builder setShadeController(ShadeController shadeController) {
+ mShadeController = shadeController;
+ return this;
+ }
+
+ /**
+ * Build a {@link StatusBarWindowView}.
+ */
+ public StatusBarWindowViewController build() {
+ return new StatusBarWindowViewController(
+ mView,
+ mInjectionInflationController,
+ mCoordinator,
+ mPulseExpansionHandler,
+ mDynamicPrivacyController,
+ mBypassController,
+ mFalsingManager,
+ mPluginManager,
+ mTunerService,
+ mShadeController,
+ mNotificationLockScreenUserManager,
+ mNotificationEntryManager,
+ mDozeLog);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index cc91bc082871..392094d0288e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -154,13 +154,17 @@ public class KeyguardStateControllerImpl extends KeyguardUpdateMonitorCallback
}
private void notifyKeyguardChanged() {
+ Trace.beginSection("KeyguardStateController#notifyKeyguardChanged");
// Copy the list to allow removal during callback.
new ArrayList<>(mCallbacks).forEach(Callback::onKeyguardShowingChanged);
+ Trace.endSection();
}
private void notifyUnlockedChanged() {
+ Trace.beginSection("KeyguardStateController#notifyUnlockedChanged");
// Copy the list to allow removal during callback.
new ArrayList<>(mCallbacks).forEach(Callback::onUnlockedChanged);
+ Trace.endSection();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
index fa7af0be77f1..be5e0a0b12c5 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
@@ -36,6 +36,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -53,7 +54,7 @@ public class DumpTruck {
private final Context context;
private Uri hprofUri;
- private long pss;
+ private long rss;
final StringBuilder body = new StringBuilder();
public DumpTruck(Context context) {
@@ -66,7 +67,7 @@ public class DumpTruck {
* @param pids
* @return this, for chaining
*/
- public DumpTruck captureHeaps(int[] pids) {
+ public DumpTruck captureHeaps(List<Long> pids) {
final GarbageMonitor gm = Dependency.get(GarbageMonitor.class);
final File dumpDir = new File(context.getCacheDir(), FILEPROVIDER_PATH);
@@ -79,8 +80,8 @@ public class DumpTruck {
final ArrayList<String> paths = new ArrayList<String>();
final int myPid = android.os.Process.myPid();
- final int[] pids_copy = Arrays.copyOf(pids, pids.length);
- for (int pid : pids_copy) {
+ for (Long pidL : pids) {
+ final int pid = pidL.intValue();
body.append(" pid ").append(pid);
if (gm != null) {
GarbageMonitor.ProcessMemInfo info = gm.getMemInfo(pid);
@@ -88,11 +89,9 @@ public class DumpTruck {
body.append(":")
.append(" up=")
.append(info.getUptime())
- .append(" pss=")
- .append(info.currentPss)
- .append(" uss=")
- .append(info.currentUss);
- pss = info.currentPss;
+ .append(" rss=")
+ .append(info.currentRss);
+ rss = info.currentRss;
}
}
if (pid == myPid) {
@@ -147,7 +146,7 @@ public class DumpTruck {
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_SUBJECT,
- String.format("SystemUI memory dump (pss=%dM)", pss / 1024));
+ String.format("SystemUI memory dump (rss=%dM)", rss / 1024));
shareIntent.putExtra(Intent.EXTRA_TEXT, body.toString());
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index db4390686cd9..2d5ebc4875cb 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -35,7 +35,6 @@ import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
-import android.os.Debug;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -57,6 +56,7 @@ import com.android.systemui.qs.tileimpl.QSTileImpl;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
@@ -102,7 +102,6 @@ public class GarbageMonitor implements Dumpable {
private final LongSparseArray<ProcessMemInfo> mData = new LongSparseArray<>();
private final ArrayList<Long> mPids = new ArrayList<>();
- private int[] mPidsArray = new int[1];
private long mHeapLimit;
@@ -164,8 +163,8 @@ public class GarbageMonitor implements Dumpable {
return mData.get(pid);
}
- public int[] getTrackedProcesses() {
- return mPidsArray;
+ public List<Long> getTrackedProcesses() {
+ return mPids;
}
public void startTrackingProcess(long pid, String name, long start) {
@@ -173,43 +172,40 @@ public class GarbageMonitor implements Dumpable {
if (mPids.contains(pid)) return;
mPids.add(pid);
- updatePidsArrayL();
+ logPids();
mData.put(pid, new ProcessMemInfo(pid, name, start));
}
}
- private void updatePidsArrayL() {
- final int N = mPids.size();
- mPidsArray = new int[N];
- StringBuffer sb = new StringBuffer("Now tracking processes: ");
- for (int i = 0; i < N; i++) {
- final int p = mPids.get(i).intValue();
- mPidsArray[i] = p;
- sb.append(p);
- sb.append(" ");
- }
- if (DEBUG) Log.v(TAG, sb.toString());
+ private void logPids() {
+ if (DEBUG) {
+ StringBuffer sb = new StringBuffer("Now tracking processes: ");
+ for (int i = 0; i < mPids.size(); i++) {
+ final int p = mPids.get(i).intValue();
+ sb.append(" ");
+ }
+ Log.v(TAG, sb.toString());
+ }
}
private void update() {
synchronized (mPids) {
- Debug.MemoryInfo[] dinfos = mAm.getProcessMemoryInfo(mPidsArray);
- for (int i = 0; i < dinfos.length; i++) {
- Debug.MemoryInfo dinfo = dinfos[i];
- if (i > mPids.size()) {
- if (DEBUG) Log.e(TAG, "update: unknown process info received: " + dinfo);
+ for (int i = 0; i < mPids.size(); i++) {
+ final int pid = mPids.get(i).intValue();
+ // rssValues contains [VmRSS, RssFile, RssAnon, VmSwap].
+ long[] rssValues = Process.getRss(pid);
+ if (rssValues == null && rssValues.length == 0) {
+ if (DEBUG) Log.e(TAG, "update: Process.getRss() didn't provide any values.");
break;
}
- final long pid = mPids.get(i).intValue();
+ long rss = rssValues[0];
final ProcessMemInfo info = mData.get(pid);
- info.pss[info.head] = info.currentPss = dinfo.getTotalPss();
- info.uss[info.head] = info.currentUss = dinfo.getTotalPrivateDirty();
- info.head = (info.head + 1) % info.pss.length;
- if (info.currentPss > info.max) info.max = info.currentPss;
- if (info.currentUss > info.max) info.max = info.currentUss;
- if (info.currentPss == 0) {
- if (DEBUG) Log.v(TAG, "update: pid " + pid + " has pss=0, it probably died");
+ info.rss[info.head] = info.currentRss = rss;
+ info.head = (info.head + 1) % info.rss.length;
+ if (info.currentRss > info.max) info.max = info.currentRss;
+ if (info.currentRss == 0) {
+ if (DEBUG) Log.v(TAG, "update: pid " + pid + " has rss=0, it probably died");
mData.remove(pid);
}
}
@@ -217,7 +213,7 @@ public class GarbageMonitor implements Dumpable {
final long pid = mPids.get(i).intValue();
if (mData.get(pid) == null) {
mPids.remove(i);
- updatePidsArrayL();
+ logPids();
}
}
}
@@ -270,7 +266,7 @@ public class GarbageMonitor implements Dumpable {
private static class MemoryIconDrawable extends Drawable {
- long pss, limit;
+ long rss, limit;
final Drawable baseIcon;
final Paint paint = new Paint();
final float dp;
@@ -281,9 +277,9 @@ public class GarbageMonitor implements Dumpable {
paint.setColor(QSTileImpl.getColorForState(context, STATE_ACTIVE));
}
- public void setPss(long pss) {
- if (pss != this.pss) {
- this.pss = pss;
+ public void setRss(long rss) {
+ if (rss != this.rss) {
+ this.rss = rss;
invalidateSelf();
}
}
@@ -299,8 +295,8 @@ public class GarbageMonitor implements Dumpable {
public void draw(Canvas canvas) {
baseIcon.draw(canvas);
- if (limit > 0 && pss > 0) {
- float frac = Math.min(1f, (float) pss / limit);
+ if (limit > 0 && rss > 0) {
+ float frac = Math.min(1f, (float) rss / limit);
final Rect bounds = getBounds();
canvas.translate(bounds.left + 8 * dp, bounds.top + 5 * dp);
@@ -361,10 +357,10 @@ public class GarbageMonitor implements Dumpable {
}
private static class MemoryGraphIcon extends QSTile.Icon {
- long pss, limit;
+ long rss, limit;
- public void setPss(long pss) {
- this.pss = pss;
+ public void setRss(long rss) {
+ this.rss = rss;
}
public void setHeapLimit(long limit) {
@@ -374,7 +370,7 @@ public class GarbageMonitor implements Dumpable {
@Override
public Drawable getDrawable(Context context) {
final MemoryIconDrawable drawable = new MemoryIconDrawable(context);
- drawable.setPss(pss);
+ drawable.setRss(rss);
drawable.setLimit(limit);
return drawable;
}
@@ -464,14 +460,14 @@ public class GarbageMonitor implements Dumpable {
? "Dumping..."
: mContext.getString(R.string.heap_dump_tile_name);
if (pmi != null) {
- icon.setPss(pmi.currentPss);
+ icon.setRss(pmi.currentRss);
state.secondaryLabel =
String.format(
- "pss: %s / %s",
- formatBytes(pmi.currentPss * 1024),
+ "rss: %s / %s",
+ formatBytes(pmi.currentRss * 1024),
formatBytes(gm.mHeapLimit * 1024));
} else {
- icon.setPss(0);
+ icon.setRss(0);
state.secondaryLabel = null;
}
state.icon = icon;
@@ -481,8 +477,8 @@ public class GarbageMonitor implements Dumpable {
refreshState();
}
- public long getPss() {
- return pmi != null ? pmi.currentPss : 0;
+ public long getRss() {
+ return pmi != null ? pmi.currentRss : 0;
}
public long getHeapLimit() {
@@ -495,9 +491,8 @@ public class GarbageMonitor implements Dumpable {
public long pid;
public String name;
public long startTime;
- public long currentPss, currentUss;
- public long[] pss = new long[HEAP_TRACK_HISTORY_LEN];
- public long[] uss = new long[HEAP_TRACK_HISTORY_LEN];
+ public long currentRss;
+ public long[] rss = new long[HEAP_TRACK_HISTORY_LEN];
public long max = 1;
public int head = 0;
@@ -519,17 +514,12 @@ public class GarbageMonitor implements Dumpable {
pw.print(name.replace('"', '-'));
pw.print("\", \"start\": ");
pw.print(startTime);
- pw.print(", \"pss\": [");
- // write pss values starting from the oldest, which is pss[head], wrapping around to
- // pss[(head-1) % pss.length]
- for (int i = 0; i < pss.length; i++) {
- if (i > 0) pw.print(",");
- pw.print(pss[(head + i) % pss.length]);
- }
- pw.print("], \"uss\": [");
- for (int i = 0; i < uss.length; i++) {
+ pw.print(", \"rss\": [");
+ // write rss values starting from the oldest, which is rss[head], wrapping around to
+ // rss[(head-1) % rss.length]
+ for (int i = 0; i < rss.length; i++) {
if (i > 0) pw.print(",");
- pw.print(uss[(head + i) % uss.length]);
+ pw.print(rss[(head + i) % rss.length]);
}
pw.println("] }");
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
index a245d4112798..cf778504190a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
@@ -24,6 +24,7 @@ import android.testing.DexmakerShareClassLoaderRule;
import androidx.test.InstrumentationRegistry;
+import com.android.systemui.assist.AssistManager;
import com.android.systemui.utils.leaks.LeakCheckedTest;
import com.android.systemui.utils.leaks.LeakCheckedTest.SysuiLeakCheck;
@@ -64,6 +65,7 @@ public abstract class SysuiBaseFragmentTest extends BaseFragmentTest {
when(inst.getTargetContext()).thenThrow(new RuntimeException(
"SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments());
+ mDependency.injectMockDependency(AssistManager.class);
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index 07fbbcf4f152..77520140b1a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -60,6 +60,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
+import java.util.Objects;
import javax.inject.Provider;
@@ -190,8 +191,7 @@ public class QSTileHostTest extends SysuiTestCase {
// changed
String newSetting = Settings.Secure.getStringForUser(getContext().getContentResolver(),
TILES_SETTING, ActivityManager.getCurrentUser());
- // newSetting is not null, as it has just been set.
- if (!newSetting.equals(previousSetting)) {
+ if (!Objects.equals(newSetting, previousSetting)) {
onTuningChanged(TILES_SETTING, newSetting);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java
index 55583931af43..145a25caf95d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java
@@ -17,11 +17,8 @@
package com.android.systemui.statusbar.notification;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyObject;
import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -30,23 +27,20 @@ import android.app.ActivityManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
import android.view.RemoteAnimationAdapter;
import android.view.View;
-import android.widget.FrameLayout;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.StatusBarWindowView;
+import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.stubbing.Answer;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -55,6 +49,8 @@ public class ActivityLaunchAnimatorTest extends SysuiTestCase {
private ActivityLaunchAnimator mLaunchAnimator;
private ActivityLaunchAnimator.Callback mCallback = mock(ActivityLaunchAnimator.Callback.class);
+ private StatusBarWindowViewController mStatusBarWindowViewController = mock(
+ StatusBarWindowViewController.class);
private StatusBarWindowView mStatusBarWindowView = mock(StatusBarWindowView.class);
private NotificationListContainer mNotificationContainer
= mock(NotificationListContainer.class);
@@ -62,10 +58,11 @@ public class ActivityLaunchAnimatorTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
+ when(mStatusBarWindowViewController.getView()).thenReturn(mStatusBarWindowView);
when(mStatusBarWindowView.getResources()).thenReturn(mContext.getResources());
when(mCallback.areLaunchAnimationsEnabled()).thenReturn(true);
mLaunchAnimator = new ActivityLaunchAnimator(
- mStatusBarWindowView,
+ mStatusBarWindowViewController,
mCallback,
mock(NotificationPanelView.class),
mNotificationContainer);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 52f7e679b49c..866ea5112794 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -68,6 +68,7 @@ import com.android.systemui.statusbar.NotificationEntryBuilder;
import com.android.systemui.statusbar.NotificationLifetimeExtender;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationRemoveInterceptor;
@@ -224,6 +225,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
mDependency.injectTestDependency(SmartReplyController.class, mSmartReplyController);
mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment);
+ mDependency.injectMockDependency(NotificationMediaManager.class);
mCountDownLatch = new CountDownLatch(1);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index f1da4e8a2905..98485b311d17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -40,8 +40,8 @@ import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.doze.DozeLog;
import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.doze.DozeLog;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.plugins.PluginManager;
@@ -52,7 +52,10 @@ import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -122,8 +125,6 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mDependency.injectTestDependency(StatusBarStateController.class,
mStatusBarStateController);
mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mUpdateMonitor);
- mDependency.injectMockDependency(ShadeController.class);
- mDependency.injectMockDependency(NotificationLockscreenUserManager.class);
mDependency.injectMockDependency(ConfigurationController.class);
mDependency.injectMockDependency(ZenModeController.class);
NotificationWakeUpCoordinator coordinator =
@@ -217,12 +218,22 @@ public class NotificationPanelViewTest extends SysuiTestCase {
TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator,
PulseExpansionHandler expansionHandler,
KeyguardBypassController bypassController) {
- super(NotificationPanelViewTest.this.mContext, null,
+ super(
+ NotificationPanelViewTest.this.mContext,
+ null,
new InjectionInflationController(
SystemUIFactory.getInstance().getRootComponent()),
- coordinator, expansionHandler, mock(DynamicPrivacyController.class),
+ coordinator,
+ expansionHandler,
+ mock(DynamicPrivacyController.class),
bypassController,
- mFalsingManager, mock(PluginManager.class), mock(DozeLog.class));
+ mFalsingManager,
+ mock(PluginManager.class),
+ mock(ShadeController.class),
+ mock(NotificationLockscreenUserManager.class),
+ new NotificationEntryManager(new NotificationData(mock(
+ NotificationSectionsFeatureManager.class))),
+ mock(DozeLog.class));
mNotificationStackScroller = mNotificationStackScrollLayout;
mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 2631ced77972..914717c0266d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -216,6 +216,8 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
@Mock private StatusBarWindowController mStatusBarWindowController;
@Mock private NotificationIconAreaController mNotificationIconAreaController;
+ @Mock private StatusBarWindowViewController.Builder mStatusBarWindowViewControllerBuilder;
+ @Mock private StatusBarWindowViewController mStatusBarWindowViewController;
@Before
public void setup() throws Exception {
@@ -278,6 +280,9 @@ public class StatusBarTest extends SysuiTestCase {
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
ConfigurationController configurationController = new ConfigurationControllerImpl(mContext);
+ when(mStatusBarWindowViewControllerBuilder.build())
+ .thenReturn(mStatusBarWindowViewController);
+
mStatusBar = new StatusBar(
mLightBarController,
mAutoHideController,
@@ -333,7 +338,8 @@ public class StatusBarTest extends SysuiTestCase {
mAssistManager,
mNotificationListener,
configurationController,
- mStatusBarWindowController);
+ mStatusBarWindowController,
+ mStatusBarWindowViewControllerBuilder);
// TODO: we should be able to call mStatusBar.start() and have all the below values
// initialized automatically.
mStatusBar.mContext = mContext;
@@ -351,6 +357,7 @@ public class StatusBarTest extends SysuiTestCase {
mStatusBar.mPowerManager = mPowerManager;
mStatusBar.mBarService = mBarService;
mStatusBar.mStackScroller = mStackScroller;
+ mStatusBar.mStatusBarWindowViewController = mStatusBarWindowViewController;
mStatusBar.putComponent(StatusBar.class, mStatusBar);
Dependency.get(InitController.class).executePostInitTasks();
entryManager.setUpForTest(mock(NotificationPresenter.class), mStackScroller,
@@ -784,11 +791,11 @@ public class StatusBarTest extends SysuiTestCase {
// Starting a pulse while docking should suppress wakeup gesture
mStatusBar.mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class),
DozeEvent.PULSE_REASON_DOCKING);
- verify(mStatusBarWindowView).suppressWakeUpGesture(eq(true));
+ verify(mStatusBarWindowViewController).suppressWakeUpGesture(eq(true));
// Ending a pulse should restore wakeup gesture
pulseCallback[0].onPulseFinished();
- verify(mStatusBarWindowView).suppressWakeUpGesture(eq(false));
+ verify(mStatusBarWindowViewController).suppressWakeUpGesture(eq(false));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
index 00d87c399293..9f4dfb4453fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
@@ -16,55 +16,89 @@
package com.android.systemui.statusbar.phone;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.os.SystemClock;
+import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-import com.android.systemui.Dependency;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.doze.DozeLog;
+import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.DragDownHelper;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
-@RunWith(AndroidJUnit4.class)
-@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class StatusBarWindowViewTest extends SysuiTestCase {
private StatusBarWindowView mView;
- private StatusBar mStatusBar;
- private DragDownHelper mDragDownHelper;
- private NotificationStackScrollLayout mStackScrollLayout;
+ private StatusBarWindowViewController mController;
+
+ @Mock private NotificationWakeUpCoordinator mCoordinator;
+ @Mock private PulseExpansionHandler mPulseExpansionHandler;
+ @Mock private DynamicPrivacyController mDynamicPrivacyController;
+ @Mock private KeyguardBypassController mBypassController;
+ @Mock private PluginManager mPluginManager;
+ @Mock private TunerService mTunerService;
+ @Mock private DragDownHelper mDragDownHelper;
+ @Mock private ShadeController mShadeController;
+ @Mock private NotificationLockscreenUserManager mNotificationLockScreenUserManager;
+ @Mock private NotificationEntryManager mNotificationEntryManager;
+ @Mock private StatusBar mStatusBar;
+ @Mock private DozeLog mDozeLog;
@Before
public void setUp() {
- mDependency.injectMockDependency(StatusBarStateController.class);
- mView = spy(new StatusBarWindowView(getContext(), null));
- mStackScrollLayout = mock(NotificationStackScrollLayout.class);
- when(mView.getStackScrollLayout()).thenReturn(mStackScrollLayout);
- mStatusBar = mock(StatusBar.class);
- mView.setService(mStatusBar);
- mDragDownHelper = mock(DragDownHelper.class);
- mView.setDragDownHelper(mDragDownHelper);
+ MockitoAnnotations.initMocks(this);
+
+ mView = new StatusBarWindowView(getContext(), null);
+ mContext.putComponent(StatusBar.class, mStatusBar);
+ when(mStatusBar.isDozing()).thenReturn(false);
+ mDependency.injectTestDependency(ShadeController.class, mShadeController);
+
+ mController = new StatusBarWindowViewController.Builder(
+ new InjectionInflationController(
+ SystemUIFactory.getInstance().getRootComponent()),
+ mCoordinator,
+ mPulseExpansionHandler,
+ mDynamicPrivacyController,
+ mBypassController,
+ new FalsingManagerFake(),
+ mPluginManager,
+ mTunerService,
+ mNotificationLockScreenUserManager,
+ mNotificationEntryManager,
+ mDozeLog)
+ .setShadeController(mShadeController)
+ .setStatusBarWindowView(mView)
+ .build();
+ mController.setService(mStatusBar);
+ mController.setDragDownHelper(mDragDownHelper);
+
}
@Test
- public void testDragDownHelperCalledWhenDraggingDown() throws Exception {
- when(Dependency.get(StatusBarStateController.class).getState())
- .thenReturn(StatusBarState.SHADE);
+ public void testDragDownHelperCalledWhenDraggingDown() {
when(mDragDownHelper.isDraggingDown()).thenReturn(true);
long now = SystemClock.elapsedRealtime();
MotionEvent ev = MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, 0 /* x */, 0 /* y */,
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 9acafaec185e..e0f60b43f8c8 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -579,6 +579,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// the set of network types that can only be enabled by system/sig apps
private List mProtectedNetworks;
+ private Set<String> mWolSupportedInterfaces;
+
private TelephonyManager mTelephonyManager;
private KeepaliveTracker mKeepaliveTracker;
@@ -1055,6 +1057,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ mWolSupportedInterfaces = new ArraySet(
+ mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_wakeonlan_supported_interfaces));
+
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mTethering = deps.makeTethering(mContext, mNMS, mStatsService, mPolicyManager,
@@ -3268,7 +3274,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
final NetworkRequestInfo nri = mNetworkRequests.get(request);
if (nri != null) {
- if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) {
+ if (Process.SYSTEM_UID != callingUid && Process.NETWORK_STACK_UID != callingUid
+ && nri.mUid != callingUid) {
log(String.format("UID %d attempted to %s for unowned request %s",
callingUid, requestedOperation, nri));
return null;
@@ -5599,6 +5606,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
} else {
updateProxy(newLp, oldLp);
}
+
+ updateWakeOnLan(newLp);
+
// TODO - move this check to cover the whole function
if (!Objects.equals(newLp, oldLp)) {
synchronized (networkAgent) {
@@ -5769,6 +5779,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ private void updateWakeOnLan(@NonNull LinkProperties lp) {
+ lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName()));
+ }
+
private int getNetworkPermission(NetworkCapabilities nc) {
if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
return INetd.PERMISSION_SYSTEM;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 08f75e600bc5..9209a21a61d7 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -192,34 +192,38 @@ public final class ActiveServices {
@Override
public void stopForegroundServicesForUidPackage(final int uid, final String packageName) {
synchronized (mAm) {
- final ServiceMap smap = getServiceMapLocked(UserHandle.getUserId(uid));
- final int N = smap.mServicesByInstanceName.size();
- final ArrayList<ServiceRecord> toStop = new ArrayList<>(N);
- for (int i = 0; i < N; i++) {
- final ServiceRecord r = smap.mServicesByInstanceName.valueAt(i);
- if (uid == r.serviceInfo.applicationInfo.uid
- || packageName.equals(r.serviceInfo.packageName)) {
- if (r.isForeground) {
- toStop.add(r);
- }
- }
- }
+ stopAllForegroundServicesLocked(uid, packageName);
+ }
+ }
+ }
- // Now stop them all
- final int numToStop = toStop.size();
- if (numToStop > 0 && DEBUG_FOREGROUND_SERVICE) {
- Slog.i(TAG, "Package " + packageName + "/" + uid
- + " entering FAS with foreground services");
- }
- for (int i = 0; i < numToStop; i++) {
- final ServiceRecord r = toStop.get(i);
- if (DEBUG_FOREGROUND_SERVICE) {
- Slog.i(TAG, " Stopping fg for service " + r);
- }
- setServiceForegroundInnerLocked(r, 0, null, 0, 0);
+ void stopAllForegroundServicesLocked(final int uid, final String packageName) {
+ final ServiceMap smap = getServiceMapLocked(UserHandle.getUserId(uid));
+ final int N = smap.mServicesByInstanceName.size();
+ final ArrayList<ServiceRecord> toStop = new ArrayList<>(N);
+ for (int i = 0; i < N; i++) {
+ final ServiceRecord r = smap.mServicesByInstanceName.valueAt(i);
+ if (uid == r.serviceInfo.applicationInfo.uid
+ || packageName.equals(r.serviceInfo.packageName)) {
+ if (r.isForeground) {
+ toStop.add(r);
}
}
}
+
+ // Now stop them all
+ final int numToStop = toStop.size();
+ if (numToStop > 0 && DEBUG_FOREGROUND_SERVICE) {
+ Slog.i(TAG, "Package " + packageName + "/" + uid
+ + " in FAS with foreground services");
+ }
+ for (int i = 0; i < numToStop; i++) {
+ final ServiceRecord r = toStop.get(i);
+ if (DEBUG_FOREGROUND_SERVICE) {
+ Slog.i(TAG, " Stopping fg for service " + r);
+ }
+ setServiceForegroundInnerLocked(r, 0, null, 0, 0);
+ }
}
/**
@@ -1019,12 +1023,23 @@ public final class ActiveServices {
}
}
if (!aa.mAppOnTop) {
- if (active == null) {
- active = new ArrayList<>();
+ // Transitioning a fg-service host app out of top: if it's bg restricted,
+ // it loses the fg service state now.
+ if (!appRestrictedAnyInBackground(aa.mUid, aa.mPackageName)) {
+ if (active == null) {
+ active = new ArrayList<>();
+ }
+ if (DEBUG_FOREGROUND_SERVICE) Slog.d(TAG, "Adding active: pkg="
+ + aa.mPackageName + ", uid=" + aa.mUid);
+ active.add(aa);
+ } else {
+ if (DEBUG_FOREGROUND_SERVICE) {
+ Slog.d(TAG, "bg-restricted app "
+ + aa.mPackageName + "/" + aa.mUid
+ + " exiting top; demoting fg services ");
+ }
+ stopAllForegroundServicesLocked(aa.mUid, aa.mPackageName);
}
- if (DEBUG_FOREGROUND_SERVICE) Slog.d(TAG, "Adding active: pkg="
- + aa.mPackageName + ", uid=" + aa.mUid);
- active.add(aa);
}
}
smap.removeMessages(ServiceMap.MSG_UPDATE_FOREGROUND_APPS);
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 3c2aee40b4fd..bb214bd740a4 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -30,7 +30,7 @@ import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
import static android.os.Process.SCHED_OTHER;
-import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
+import static android.os.Process.THREAD_GROUP_BACKGROUND;
import static android.os.Process.THREAD_GROUP_DEFAULT;
import static android.os.Process.THREAD_GROUP_RESTRICTED;
import static android.os.Process.THREAD_GROUP_TOP_APP;
@@ -1759,7 +1759,7 @@ public final class OomAdjuster {
int processGroup;
switch (curSchedGroup) {
case ProcessList.SCHED_GROUP_BACKGROUND:
- processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
+ processGroup = THREAD_GROUP_BACKGROUND;
break;
case ProcessList.SCHED_GROUP_TOP_APP:
case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index c0af814cdb38..af126f289fc2 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -215,7 +215,7 @@ public final class ProcessList {
// Memory pages are 4K.
static final int PAGE_SIZE = 4 * 1024;
- // Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE
+ // Activity manager's version of Process.THREAD_GROUP_BACKGROUND
static final int SCHED_GROUP_BACKGROUND = 0;
// Activity manager's version of Process.THREAD_GROUP_RESTRICTED
static final int SCHED_GROUP_RESTRICTED = 1;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index f20003a2ee04..b7fcd3f19334 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -3569,9 +3569,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (!calledWithValidTokenLocked(token)) {
return;
}
- if (mCurClient != null && mCurClient.client != null) {
- executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
- MSG_APPLY_IME_VISIBILITY, setVisible ? 1 : 0, mCurClient));
+ if (!setVisible) {
+ // Client hides the IME directly.
+ if (mCurClient != null && mCurClient.client != null) {
+ executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
+ MSG_APPLY_IME_VISIBILITY, setVisible ? 1 : 0, mCurClient));
+ }
+ } else {
+ // Send to window manager to show IME after IME layout finishes.
+ mWindowManagerInternal.showImePostLayout(mLastImeTargetWindow);
}
}
}
diff --git a/services/core/java/com/android/server/integrity/model/AppInstallMetadata.java b/services/core/java/com/android/server/integrity/model/AppInstallMetadata.java
index 814b8e1d783b..660bd2e0d62e 100644
--- a/services/core/java/com/android/server/integrity/model/AppInstallMetadata.java
+++ b/services/core/java/com/android/server/integrity/model/AppInstallMetadata.java
@@ -16,29 +16,154 @@
package com.android.server.integrity.model;
+import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.Nullable;
+
/**
* The app install metadata.
*
* <p>The integrity component retrieves metadata for app installs from package manager, passing it
* to the rule evaluation engine to evaluate the metadata against the rules.
+ *
+ * <p>Instances of this class are immutable.
*/
public final class AppInstallMetadata {
- final String mPackageName;
+ private final String mPackageName;
// Raw string encoding for the SHA-256 hash of the certificate of the app.
- final String mAppCertificate;
- final String mInstallerName;
+ private final String mAppCertificate;
+ private final String mInstallerName;
// Raw string encoding for the SHA-256 hash of the certificate of the installer.
- final String mInstallerCertificate;
- final int mVersionCode;
- final boolean mIsPreInstalled;
-
- public AppInstallMetadata(String packageName, String appCertificate, String installerName,
- String installerCertificate, int versionCode, boolean isPreInstalled) {
- this.mPackageName = packageName;
- this.mAppCertificate = appCertificate;
- this.mInstallerName = installerName;
- this.mInstallerCertificate = installerCertificate;
- this.mVersionCode = versionCode;
- this.mIsPreInstalled = isPreInstalled;
+ private final String mInstallerCertificate;
+ private final int mVersionCode;
+ private final boolean mIsPreInstalled;
+
+ private AppInstallMetadata(Builder builder) {
+ this.mPackageName = builder.mPackageName;
+ this.mAppCertificate = builder.mAppCertificate;
+ this.mInstallerName = builder.mInstallerName;
+ this.mInstallerCertificate = builder.mInstallerCertificate;
+ this.mVersionCode = builder.mVersionCode;
+ this.mIsPreInstalled = builder.mIsPreInstalled;
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public String getAppCertificate() {
+ return mAppCertificate;
+ }
+
+ @Nullable
+ public String getInstallerName() {
+ return mInstallerName;
+ }
+
+ @Nullable
+ public String getInstallerCertificate() {
+ return mInstallerCertificate;
+ }
+
+ /**
+ * @see AppInstallMetadata.Builder#setVersionCode(int)
+ */
+ public int getVersionCode() {
+ return mVersionCode;
+ }
+
+ /**
+ * @see AppInstallMetadata.Builder#setIsPreInstalled(boolean)
+ */
+ public boolean isPreInstalled() {
+ return mIsPreInstalled;
+ }
+
+ /**
+ * Builder class for constructing {@link AppInstallMetadata} objects.
+ */
+ public static final class Builder {
+ private String mPackageName;
+ private String mAppCertificate;
+ private String mInstallerName;
+ private String mInstallerCertificate;
+ private int mVersionCode;
+ private boolean mIsPreInstalled;
+
+ /**
+ * Set package name of the app to be installed.
+ *
+ * @see AppInstallMetadata#getPackageName()
+ */
+ public Builder setPackageName(String packageName) {
+ this.mPackageName = checkNotNull(packageName);
+ return this;
+ }
+
+ /**
+ * Set certificate of the app to be installed.
+ *
+ * <p>It is represented as the raw string encoding for the SHA-256 hash of the certificate
+ * of the app.
+ *
+ * @see AppInstallMetadata#getAppCertificate()
+ */
+ public Builder setAppCertificate(String appCertificate) {
+ this.mAppCertificate = checkNotNull(appCertificate);
+ return this;
+ }
+
+ /**
+ * Set name of the installer installing the app.
+ *
+ * @see AppInstallMetadata#getInstallerName()
+ */
+ public Builder setInstallerName(String installerName) {
+ this.mInstallerName = checkNotNull(installerName);
+ return this;
+ }
+
+ /**
+ * Set certificate of the installer installing the app.
+ *
+ * <p>It is represented as the raw string encoding for the SHA-256 hash of the certificate
+ * of the installer.
+ *
+ * @see AppInstallMetadata#getInstallerCertificate()
+ */
+ public Builder setInstallerCertificate(String installerCertificate) {
+ this.mInstallerCertificate = checkNotNull(installerCertificate);
+ return this;
+ }
+
+ /**
+ * Set version code of the app to be installed.
+ *
+ * @see AppInstallMetadata#getVersionCode()
+ */
+ public Builder setVersionCode(int versionCode) {
+ this.mVersionCode = versionCode;
+ return this;
+ }
+
+ /**
+ * Set whether the app is pre-installed on the device or not.
+ *
+ * @see AppInstallMetadata#isPreInstalled()
+ */
+ public Builder setIsPreInstalled(boolean isPreInstalled) {
+ this.mIsPreInstalled = isPreInstalled;
+ return this;
+ }
+
+ /**
+ * Build {@link AppInstallMetadata}.
+ */
+ public AppInstallMetadata build() {
+ checkArgument(mPackageName != null);
+ checkArgument(mAppCertificate != null);
+ return new AppInstallMetadata(this);
+ }
}
}
diff --git a/services/core/java/com/android/server/integrity/model/AtomicFormula.java b/services/core/java/com/android/server/integrity/model/AtomicFormula.java
new file mode 100644
index 000000000000..a9cc62a4daf0
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/model/AtomicFormula.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.integrity.model;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.Nullable;
+
+/**
+ * Represents a simple formula consisting of an app install metadata field and a value.
+ *
+ * <p>Instances of this class are immutable.
+ */
+public final class AtomicFormula extends Formula {
+
+ enum Key {
+ PACKAGE_NAME,
+ APP_CERTIFICATE,
+ INSTALLER_NAME,
+ INSTALLER_CERTIFICATE,
+ VERSION_CODE,
+ PRE_INSTALLED
+ }
+
+ enum Operator {
+ EQ,
+ LT,
+ LE,
+ GT,
+ GE
+ }
+
+ private final Key mKey;
+ private final Operator mOperator;
+
+ // The value of a key can take either 1 of 3 forms: String, Integer, or Boolean.
+ // It cannot have multiple values.
+ @Nullable
+ private final String mStringValue;
+ @Nullable
+ private final Integer mIntValue;
+ @Nullable
+ private final Boolean mBoolValue;
+
+ public AtomicFormula(Key key, Operator operator, String stringValue) {
+ validateOperator(key, operator);
+ checkArgument(
+ key == Key.PACKAGE_NAME || key == Key.APP_CERTIFICATE || key == Key.INSTALLER_NAME
+ || key == Key.INSTALLER_CERTIFICATE,
+ String.format("Key %s cannot have string value", key));
+ this.mKey = checkNotNull(key);
+ this.mOperator = checkNotNull(operator);
+ this.mStringValue = checkNotNull(stringValue);
+ this.mIntValue = null;
+ this.mBoolValue = null;
+ }
+
+ public AtomicFormula(Key key, Operator operator, Integer intValue) {
+ validateOperator(key, operator);
+ checkArgument(key == Key.VERSION_CODE,
+ String.format("Key %s cannot have integer value", key));
+ this.mKey = checkNotNull(key);
+ this.mOperator = checkNotNull(operator);
+ this.mStringValue = null;
+ this.mIntValue = checkNotNull(intValue);
+ this.mBoolValue = null;
+ }
+
+ public AtomicFormula(Key key, Operator operator, Boolean boolValue) {
+ validateOperator(key, operator);
+ checkArgument(key == Key.PRE_INSTALLED,
+ String.format("Key %s cannot have boolean value", key));
+ this.mKey = checkNotNull(key);
+ this.mOperator = checkNotNull(operator);
+ this.mStringValue = null;
+ this.mIntValue = null;
+ this.mBoolValue = checkNotNull(boolValue);
+ }
+
+ public Key getKey() {
+ return mKey;
+ }
+
+ public Operator getOperator() {
+ return mOperator;
+ }
+
+ public String getStringValue() {
+ return mStringValue;
+ }
+
+ public Integer getIntValue() {
+ return mIntValue;
+ }
+
+ public Boolean getBoolValue() {
+ return mBoolValue;
+ }
+
+ private void validateOperator(Key key, Operator operator) {
+ boolean validOperator;
+ switch (key) {
+ case PACKAGE_NAME:
+ case APP_CERTIFICATE:
+ case INSTALLER_NAME:
+ case INSTALLER_CERTIFICATE:
+ case PRE_INSTALLED:
+ validOperator = (operator == Operator.EQ);
+ break;
+ case VERSION_CODE:
+ validOperator = true;
+ break;
+ default:
+ validOperator = false;
+ }
+ if (!validOperator) {
+ throw new IllegalArgumentException(
+ String.format("Invalid operator %s used for key %s", operator, key));
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/model/Formula.java b/services/core/java/com/android/server/integrity/model/Formula.java
new file mode 100644
index 000000000000..4cfa2c76adf2
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/model/Formula.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.integrity.model;
+
+/**
+ * Represents a rule logic/content.
+ */
+abstract class Formula {
+
+}
diff --git a/services/core/java/com/android/server/integrity/model/OpenFormula.java b/services/core/java/com/android/server/integrity/model/OpenFormula.java
new file mode 100644
index 000000000000..218cdc99c016
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/model/OpenFormula.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.integrity.model;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.Nullable;
+
+/**
+ * Represents a complex formula consisting of other simple and complex formulas.
+ *
+ * <p>Instances of this class are immutable.
+ */
+public final class OpenFormula extends Formula {
+
+ enum Connector {
+ AND,
+ OR,
+ NOT
+ }
+
+ private final Connector mConnector;
+ private final Formula mMainFormula;
+ private final Formula mAuxiliaryFormula;
+
+ public OpenFormula(Connector connector, Formula mainFormula,
+ @Nullable Formula auxiliaryFormula) {
+ validateAuxiliaryFormula(connector, auxiliaryFormula);
+ this.mConnector = checkNotNull(connector);
+ this.mMainFormula = checkNotNull(mainFormula);
+ // TODO: Add validators on auxiliary formula
+ this.mAuxiliaryFormula = auxiliaryFormula;
+ }
+
+ public Connector getConnector() {
+ return mConnector;
+ }
+
+ public Formula getMainFormula() {
+ return mMainFormula;
+ }
+
+ public Formula getAuxiliaryFormula() {
+ return mAuxiliaryFormula;
+ }
+
+ private void validateAuxiliaryFormula(Connector connector, Formula auxiliaryFormula) {
+ boolean validAuxiliaryFormula;
+ switch (connector) {
+ case AND:
+ case OR:
+ validAuxiliaryFormula = (auxiliaryFormula != null);
+ break;
+ case NOT:
+ validAuxiliaryFormula = (auxiliaryFormula == null);
+ break;
+ default:
+ validAuxiliaryFormula = false;
+ }
+ if (!validAuxiliaryFormula) {
+ throw new IllegalArgumentException(
+ String.format("Invalid formulas used for connector %s", connector));
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/model/Rule.java b/services/core/java/com/android/server/integrity/model/Rule.java
index a6e08d8504ed..4fd40c1e0365 100644
--- a/services/core/java/com/android/server/integrity/model/Rule.java
+++ b/services/core/java/com/android/server/integrity/model/Rule.java
@@ -18,8 +18,6 @@ package com.android.server.integrity.model;
import static com.android.internal.util.Preconditions.checkNotNull;
-import android.annotation.Nullable;
-
/**
* Represent rules to be used in the rule evaluation engine to match against app installs.
*
@@ -27,35 +25,12 @@ import android.annotation.Nullable;
*/
public final class Rule {
- // Holds an empty rule instance.
- public static final Rule EMPTY = new Rule();
-
- enum Key {
- PACKAGE_NAME,
- APP_CERTIFICATE,
- INSTALLER_NAME,
- INSTALLER_CERTIFICATE,
- VERSION_CODE,
- PRE_INSTALLED
- }
-
enum Effect {
DENY
}
- enum Operator {
- EQ,
- LT,
- LE,
- GT,
- GE
- }
-
- enum Connector {
- AND,
- OR,
- NOT
- }
+ // Holds an empty rule instance.
+ public static final Rule EMPTY = new Rule();
private final Formula mFormula;
private final Effect mEffect;
@@ -86,75 +61,4 @@ public final class Rule {
public Effect getEffect() {
return mEffect;
}
-
- // TODO: Consider moving the sub-components to their respective model class.
-
- /**
- * Represents a rule logic/content.
- */
- abstract static class Formula {
-
- }
-
- /**
- * Represents a simple formula consisting of an app install metadata field and a value.
- */
- public static final class AtomicFormula extends Formula {
-
- final Key mKey;
- final Operator mOperator;
-
- // The value of a key can take either 1 of 3 forms: String, Integer, or Boolean.
- // It cannot have multiple values.
- @Nullable
- final String mStringValue;
- @Nullable
- final Integer mIntValue;
- @Nullable
- final Boolean mBoolValue;
-
- public AtomicFormula(Key key, Operator operator, String stringValue) {
- // TODO: Add validators
- this.mKey = key;
- this.mOperator = operator;
- this.mStringValue = stringValue;
- this.mIntValue = null;
- this.mBoolValue = null;
- }
-
- public AtomicFormula(Key key, Operator operator, Integer intValue) {
- // TODO: Add validators
- this.mKey = key;
- this.mOperator = operator;
- this.mStringValue = null;
- this.mIntValue = intValue;
- this.mBoolValue = null;
- }
-
- public AtomicFormula(Key key, Operator operator, Boolean boolValue) {
- // TODO: Add validators
- this.mKey = key;
- this.mOperator = operator;
- this.mStringValue = null;
- this.mIntValue = null;
- this.mBoolValue = boolValue;
- }
- }
-
- /**
- * Represents a complex formula consisting of other simple and complex formulas.
- */
- public static final class OpenFormula extends Formula {
-
- final Connector mConnector;
- final Formula mMainFormula;
- final Formula mAuxiliaryFormula;
-
- public OpenFormula(Connector connector, Formula mainFormula,
- @Nullable Formula auxiliaryFormula) {
- this.mConnector = checkNotNull(connector);
- this.mMainFormula = checkNotNull(mainFormula);
- this.mAuxiliaryFormula = auxiliaryFormula;
- }
- }
}
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index b1cd62788073..9cb8a0105286 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -16,9 +16,13 @@
package com.android.server.notification;
import android.service.notification.StatusBarNotification;
+import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -37,6 +41,11 @@ public class GroupHelper {
private final Callback mCallback;
private final int mAutoGroupAtCount;
+ // count the number of ongoing notifications per group
+ // userId -> (package name -> (group Id -> (set of notification keys)))
+ final ArrayMap<String, ArraySet<String>>
+ mOngoingGroupCount = new ArrayMap<>();
+
// Map of user : <Map of package : notification keys>. Only contains notifications that are not
// grouped by the app (aka no group or sort key).
Map<Integer, Map<String, LinkedHashSet<String>>> mUngroupedNotifications = new HashMap<>();
@@ -46,10 +55,52 @@ public class GroupHelper {
mCallback = callback;
}
+ private String generatePackageGroupKey(int userId, String pkg, String group) {
+ return userId + "|" + pkg + "|" + group;
+ }
+
+ @VisibleForTesting
+ protected int getOngoingGroupCount(int userId, String pkg, String group) {
+ String key = generatePackageGroupKey(userId, pkg, group);
+ return mOngoingGroupCount.getOrDefault(key, new ArraySet<>(0)).size();
+ }
+
+ private void addToOngoingGroupCount(StatusBarNotification sbn, boolean add) {
+ if (sbn.getNotification().isGroupSummary()) return;
+ if (!sbn.isOngoing() && add) return;
+ String group = sbn.getGroup();
+ if (group == null) return;
+ int userId = sbn.getUser().getIdentifier();
+ String key = generatePackageGroupKey(userId, sbn.getPackageName(), group);
+ ArraySet<String> notifications = mOngoingGroupCount.getOrDefault(key, new ArraySet<>(0));
+ if (add) {
+ notifications.add(sbn.getKey());
+ mOngoingGroupCount.put(key, notifications);
+ } else {
+ notifications.remove(sbn.getKey());
+ // we dont need to put it back if it is default
+ }
+ String combinedKey = generatePackageGroupKey(userId, sbn.getPackageName(), group);
+ boolean needsOngoingFlag = notifications.size() > 0;
+ mCallback.updateAutogroupSummary(sbn.getKey(), needsOngoingFlag);
+ }
+
+ public void onNotificationUpdated(StatusBarNotification childSbn,
+ boolean autogroupSummaryExists) {
+ if (childSbn.getGroup() != AUTOGROUP_KEY
+ || childSbn.getNotification().isGroupSummary()) return;
+ if (childSbn.isOngoing()) {
+ addToOngoingGroupCount(childSbn, true);
+ } else {
+ addToOngoingGroupCount(childSbn, false);
+ }
+ }
+
public void onNotificationPosted(StatusBarNotification sbn, boolean autogroupSummaryExists) {
if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey());
try {
List<String> notificationsToGroup = new ArrayList<>();
+ if (autogroupSummaryExists) addToOngoingGroupCount(sbn, true);
if (!sbn.isAppGroup()) {
// Not grouped by the app, add to the list of notifications for the app;
// send grouping update if app exceeds the autogrouping limit.
@@ -90,6 +141,7 @@ public class GroupHelper {
public void onNotificationRemoved(StatusBarNotification sbn) {
try {
+ addToOngoingGroupCount(sbn, false);
maybeUngroup(sbn, true, sbn.getUserId());
} catch (Exception e) {
Slog.e(TAG, "Error processing canceled notification", e);
@@ -159,5 +211,6 @@ public class GroupHelper {
void removeAutoGroup(String key);
void addAutoGroupSummary(int userId, String pkg, String triggeringKey);
void removeAutoGroupSummary(int user, String pkg);
+ void updateAutogroupSummary(String key, boolean needsOngoingFlag);
}
}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 48b0fd6e86d1..8560ae6d2e3a 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -185,7 +185,7 @@ abstract public class ManagedServices {
}
protected void addDefaultComponentOrPackage(String packageOrComponent) {
- if (packageOrComponent != null) {
+ if (!TextUtils.isEmpty(packageOrComponent)) {
synchronized (mDefaultsLock) {
ComponentName cn = ComponentName.unflattenFromString(packageOrComponent);
if (cn == null) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 3341991aa0ae..d7efa1b733fd 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -522,7 +522,6 @@ public class NotificationManagerService extends SystemService {
}
-
void loadDefaultApprovedServices(int userId) {
String defaultListenerAccess = getContext().getResources().getString(
com.android.internal.R.string.config_defaultListenerAccessPackages);
@@ -530,6 +529,9 @@ public class NotificationManagerService extends SystemService {
String[] listeners =
defaultListenerAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR);
for (int i = 0; i < listeners.length; i++) {
+ if (TextUtils.isEmpty(listeners[i])) {
+ continue;
+ }
ArraySet<ComponentName> approvedListeners =
mListeners.queryPackageForServices(listeners[i],
MATCH_DIRECT_BOOT_AWARE
@@ -546,6 +548,9 @@ public class NotificationManagerService extends SystemService {
if (defaultDndAccess != null) {
String[] dnds = defaultDndAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR);
for (int i = 0; i < dnds.length; i++) {
+ if (TextUtils.isEmpty(dnds[i])) {
+ continue;
+ }
mConditionProviders.addDefaultComponentOrPackage(dnds[i]);
}
}
@@ -564,12 +569,14 @@ public class NotificationManagerService extends SystemService {
.split(ManagedServices.ENABLED_SERVICES_SEPARATOR)));
for (int i = 0; i < assistants.size(); i++) {
String cnString = assistants.valueAt(i);
+ if (TextUtils.isEmpty(cnString)) {
+ continue;
+ }
mAssistants.addDefaultComponentOrPackage(cnString);
}
}
protected void allowDefaultApprovedServices(int userId) {
-
ArraySet<ComponentName> defaultListeners = mListeners.getDefaultComponents();
for (int i = 0; i < defaultListeners.size(); i++) {
ComponentName cn = defaultListeners.valueAt(i);
@@ -594,6 +601,40 @@ public class NotificationManagerService extends SystemService {
}
}
+ /**
+ * This method will update the flags of the summary.
+ * It will set it to FLAG_ONGOING_EVENT if any of its group members
+ * has the same flag. It will delete the flag otherwise
+ * @param userId user id of the autogroup summary
+ * @param pkg package of the autogroup summary
+ * @param needsOngoingFlag true if the group has at least one ongoing notification
+ */
+ @GuardedBy("mNotificationLock")
+ protected void updateAutobundledSummaryFlags(int userId, String pkg, boolean needsOngoingFlag) {
+ ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId);
+ if (summaries == null) {
+ return;
+ }
+ String summaryKey = summaries.get(pkg);
+ if (summaryKey == null) {
+ return;
+ }
+ NotificationRecord summary = mNotificationsByKey.get(summaryKey);
+ if (summary == null) {
+ return;
+ }
+ int oldFlags = summary.sbn.getNotification().flags;
+ if (needsOngoingFlag) {
+ summary.sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+ } else {
+ summary.sbn.getNotification().flags &= ~FLAG_ONGOING_EVENT;
+ }
+
+ if (summary.sbn.getNotification().flags != oldFlags) {
+ mHandler.post(new EnqueueNotificationRunnable(userId, summary));
+ }
+ }
+
private void allowDndPackage(String packageName) {
try {
getBinderService().setNotificationPolicyAccessGranted(packageName, true);
@@ -1910,7 +1951,6 @@ public class NotificationManagerService extends SystemService {
});
}
-
private GroupHelper getGroupHelper() {
mAutoGroupAtCount =
getContext().getResources().getInteger(R.integer.config_autoGroupAtCount);
@@ -1940,6 +1980,15 @@ public class NotificationManagerService extends SystemService {
clearAutogroupSummaryLocked(userId, pkg);
}
}
+
+ @Override
+ public void updateAutogroupSummary(String key, boolean needsOngoingFlag) {
+ synchronized (mNotificationLock) {
+ NotificationRecord r = mNotificationsByKey.get(key);
+ updateAutobundledSummaryFlags(r.getUser().getIdentifier(),
+ r.sbn.getPackageName(), needsOngoingFlag);
+ }
+ }
});
}
@@ -5007,12 +5056,13 @@ public class NotificationManagerService extends SystemService {
final int contentViewSize = contentView.estimateMemoryUsage();
if (contentViewSize > mWarnRemoteViewsSizeBytes
&& contentViewSize < mStripRemoteViewsSizeBytes) {
- Slog.w(TAG, "RemoteViews too large on tag: " + tag + " id: " + id
+ Slog.w(TAG, "RemoteViews too large on pkg: " + pkg + " tag: " + tag + " id: " + id
+ " this might be stripped in a future release");
}
if (contentViewSize >= mStripRemoteViewsSizeBytes) {
mUsageStats.registerImageRemoved(pkg);
- Slog.w(TAG, "Removed too large RemoteViews on tag: " + tag + " id: " + id);
+ Slog.w(TAG,
+ "Removed too large RemoteViews on pkg: " + pkg + " tag: " + tag + " id: " + id);
return true;
}
return false;
@@ -5754,6 +5804,10 @@ public class NotificationManagerService extends SystemService {
n, hasAutoGroupSummaryLocked(n));
}
});
+ } else if (oldSbn != null) {
+ final NotificationRecord finalRecord = r;
+ mHandler.post(() -> mGroupHelper.onNotificationUpdated(
+ finalRecord.sbn, hasAutoGroupSummaryLocked(n)));
}
} else {
Slog.e(TAG, "Not posting notification without small icon: " + notification);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b85009b8eac1..e0697a636498 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -13247,22 +13247,18 @@ public class PackageManagerService extends IPackageManager.Stub
return false;
}
- boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
-
// Check if installing from ADB
if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
// Do not run verification in a test harness environment
if (ActivityManager.isRunningInTestHarness()) {
return false;
}
- if (ensureVerifyAppsEnabled) {
+ if (isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS)) {
return true;
}
// Check if the developer does not want package verification for ADB installs
- if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
- android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
- return false;
- }
+ return Global.getInt(mContext.getContentResolver(),
+ Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0;
} else {
// only when not installed from ADB, skip verification for instant apps when
// the installer and verifier are the same.
@@ -13280,14 +13276,8 @@ public class PackageManagerService extends IPackageManager.Stub
} catch (SecurityException ignore) { }
}
}
- }
-
- if (ensureVerifyAppsEnabled) {
return true;
}
-
- return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
- android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
}
@Override
@@ -15080,19 +15070,6 @@ public class PackageManagerService extends IPackageManager.Stub
return disabled;
}
- @GuardedBy("mLock")
- private void setInstallerPackageNameLPw(PackageParser.Package pkg,
- String installerPackageName) {
- // Enable the parent package
- mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
- // Enable the child packages
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
- }
- }
-
private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
// Update the parent package setting
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index ebba128b5f28..8253b392768f 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -1200,12 +1200,20 @@ public class ShortcutService extends IShortcutService.Stub {
return mUsers.get(userId) != null;
}
+ private int mLastLockedUser = -1;
+
/** Return the per-user state. */
@GuardedBy("mLock")
@NonNull
ShortcutUser getUserShortcutsLocked(@UserIdInt int userId) {
if (!isUserUnlockedL(userId)) {
- wtf("User still locked");
+ // Only do wtf once for each user. (until the user is unlocked)
+ if (userId != mLastLockedUser) {
+ wtf("User still locked");
+ mLastLockedUser = userId;
+ }
+ } else {
+ mLastLockedUser = -1;
}
ShortcutUser userPackages = mUsers.get(userId);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 8431fa36c04c..95baa01923f5 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -209,7 +209,8 @@ public class UserManagerService extends IUserManager.Stub {
| UserInfo.FLAG_DEMO;
@VisibleForTesting
- static final int MIN_USER_ID = 10;
+ static final int MIN_USER_ID = UserHandle.MIN_SECONDARY_USER_ID;
+
// We need to keep process uid within Integer.MAX_VALUE.
@VisibleForTesting
static final int MAX_USER_ID = Integer.MAX_VALUE / UserHandle.PER_USER_RANGE;
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 4213168b6ec7..89908f04a6b3 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -53,7 +53,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
-import android.app.AppOpsManager;
import android.app.ApplicationPackageManager;
import android.app.IActivityManager;
import android.content.Context;
@@ -793,13 +792,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final CheckPermissionDelegate checkPermissionDelegate;
synchronized (mLock) {
- if (mCheckPermissionDelegate == null) {
- return checkPermissionImpl(permName, pkgName, userId);
- }
checkPermissionDelegate = mCheckPermissionDelegate;
}
+ if (checkPermissionDelegate == null) {
+ return checkPermissionImpl(permName, pkgName, userId);
+ }
return checkPermissionDelegate.checkPermission(permName, pkgName, userId,
- PermissionManagerService.this::checkPermissionImpl);
+ this::checkPermissionImpl);
}
private int checkPermissionImpl(String permName, String pkgName, int userId) {
@@ -845,23 +844,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
private boolean checkSinglePermissionInternal(int uid,
@NonNull PermissionsState permissionsState, @NonNull String permissionName) {
- boolean hasPermission = permissionsState.hasPermission(permissionName,
- UserHandle.getUserId(uid));
-
- if (!hasPermission && mSettings.isPermissionRuntime(permissionName)) {
- final String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
- final int packageNamesSize = packageNames != null ? packageNames.length : 0;
- for (int i = 0; i < packageNamesSize; i++) {
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageNames[i]);
- if (pkg != null && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
- && pkg.requestedPermissions.contains(permissionName)) {
- hasPermission = true;
- break;
- }
- }
- }
-
- if (!hasPermission) {
+ if (!permissionsState.hasPermission(permissionName, UserHandle.getUserId(uid))) {
return false;
}
@@ -885,13 +868,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final CheckPermissionDelegate checkPermissionDelegate;
synchronized (mLock) {
- if (mCheckPermissionDelegate == null) {
- return checkUidPermissionImpl(permName, uid);
- }
checkPermissionDelegate = mCheckPermissionDelegate;
}
+ if (checkPermissionDelegate == null) {
+ return checkUidPermissionImpl(permName, uid);
+ }
return checkPermissionDelegate.checkUidPermission(permName, uid,
- PermissionManagerService.this::checkUidPermissionImpl);
+ this::checkUidPermissionImpl);
}
private int checkUidPermissionImpl(String permName, int uid) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 88b17936d93d..ef31ef151d26 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -23,6 +23,7 @@ import static android.app.AppOpsManager.OP_TOAST_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.Context.CONTEXT_RESTRICTED;
import static android.content.Context.WINDOW_SERVICE;
+import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
@@ -385,6 +386,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
BurnInProtectionHelper mBurnInProtectionHelper;
private DisplayFoldController mDisplayFoldController;
AppOpsManager mAppOpsManager;
+ private boolean mHasFeatureAuto;
private boolean mHasFeatureWatch;
private boolean mHasFeatureLeanback;
private boolean mHasFeatureHdmiCec;
@@ -1753,6 +1755,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mDisplayManager = mContext.getSystemService(DisplayManager.class);
mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH);
mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK);
+ mHasFeatureAuto = mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE);
mHasFeatureHdmiCec = mContext.getPackageManager().hasSystemFeature(FEATURE_HDMI_CEC);
mAccessibilityShortcutController =
new AccessibilityShortcutController(mContext, new Handler(), mCurrentUserId);
@@ -4572,7 +4575,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// ... eventually calls finishWindowsDrawn which will finalize our screen turn on
// as well as enabling the orientation change logic/sensor.
mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,
- WAITING_FOR_DRAWN_TIMEOUT);
+ WAITING_FOR_DRAWN_TIMEOUT, INVALID_DISPLAY);
}
// Called on the DisplayManager's DisplayPowerController thread.
@@ -5222,7 +5225,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
awakenDreams();
}
- if (!isUserSetupComplete()) {
+ if (!mHasFeatureAuto && !isUserSetupComplete()) {
Slog.i(TAG, "Not going home because user setup is in progress.");
return;
}
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 9c19aeccd59a..83891f60d4f7 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -370,7 +370,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
private void checkAndMitigateNativeCrashes() {
mNumberOfNativeCrashPollsRemaining--;
// Check if native watchdog reported a crash
- if ("1".equals(SystemProperties.get("ro.init.updatable_crashing"))) {
+ if ("1".equals(SystemProperties.get("sys.init.updatable_crashing"))) {
execute(getModuleMetadataPackage());
// we stop polling after an attempt to execute rollback, regardless of whether the
// attempt succeeds or not
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index 5fd2ab87f410..3b2f32479ed2 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -180,8 +180,13 @@ public class SliceManagerService extends ISliceManager.Stub {
verifyCaller(pkg);
enforceAccess(pkg, uri);
uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
- if (getPinnedSlice(uri).unpin(pkg, token)) {
- removePinnedSlice(uri);
+ try {
+ PinnedSliceState slice = getPinnedSlice(uri);
+ if (slice != null && slice.unpin(pkg, token)) {
+ removePinnedSlice(uri);
+ }
+ } catch (IllegalStateException exception) {
+ Slog.w(TAG, exception.getMessage());
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index e54daf28677f..976fd52f17e5 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -90,7 +90,6 @@ import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
import static com.android.server.am.ActivityRecordProto.APP_WINDOW_TOKEN;
-import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
import static com.android.server.am.ActivityRecordProto.PROC_ID;
@@ -145,9 +144,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
-import static com.android.server.wm.IdentifierProto.HASH_CODE;
-import static com.android.server.wm.IdentifierProto.TITLE;
-import static com.android.server.wm.IdentifierProto.USER_ID;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
@@ -1578,7 +1574,7 @@ final class ActivityRecord extends AppWindowToken {
final TaskRecord task = getTaskRecord();
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
mUserId, System.identityHashCode(this),
- task.taskId, shortComponentName, reason);
+ task.mTaskId, shortComponentName, reason);
final ArrayList<ActivityRecord> activities = task.mActivities;
final int index = activities.indexOf(this);
if (index < (activities.size() - 1)) {
@@ -1838,7 +1834,7 @@ final class ActivityRecord extends AppWindowToken {
}
EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY, mUserId,
- System.identityHashCode(this), getTaskRecord().taskId, shortComponentName, reason);
+ System.identityHashCode(this), getTaskRecord().mTaskId, shortComponentName, reason);
boolean removedFromHistory = false;
@@ -1976,7 +1972,7 @@ final class ActivityRecord extends AppWindowToken {
// work.
// TODO: If the callers to removeTask() changes such that we have multiple places
// where we are destroying the task, move this back into removeTask()
- mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */,
+ mStackSupervisor.removeTaskByIdLocked(task.mTaskId, false /* killProcess */,
!REMOVE_FROM_RECENTS, reason);
}
@@ -2090,7 +2086,7 @@ final class ActivityRecord extends AppWindowToken {
final String strData = data != null ? data.toSafeString() : null;
EventLog.writeEvent(tag,
- mUserId, System.identityHashCode(this), task.taskId,
+ mUserId, System.identityHashCode(this), task.mTaskId,
shortComponentName, intent.getAction(),
intent.getType(), strData, intent.getFlags());
}
@@ -3244,7 +3240,7 @@ final class ActivityRecord extends AppWindowToken {
|| (onlyRoot && activityNdx > task.findRootIndex(true /* effectiveRoot */))) {
return INVALID_TASK_ID;
}
- return task.taskId;
+ return task.mTaskId;
}
static ActivityRecord isInStackLocked(IBinder token) {
@@ -3299,8 +3295,8 @@ final class ActivityRecord extends AppWindowToken {
Bitmap icon;
if (_taskDescription.getIconFilename() == null &&
(icon = _taskDescription.getIcon()) != null) {
- final String iconFilename = createImageFilename(createTime, task.taskId);
- final File iconFile = new File(TaskPersister.getUserImagesDir(task.userId),
+ final String iconFilename = createImageFilename(createTime, task.mTaskId);
+ final File iconFile = new File(TaskPersister.getUserImagesDir(task.mUserId),
iconFilename);
final String iconFilePath = iconFile.getAbsolutePath();
mAtmService.getRecentTasks().saveImage(icon, iconFilePath);
@@ -3359,7 +3355,7 @@ final class ActivityRecord extends AppWindowToken {
void setRequestedOrientation(int requestedOrientation) {
setOrientation(requestedOrientation, mayFreezeScreenLocked());
mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
- task.taskId, requestedOrientation);
+ task.mTaskId, requestedOrientation);
}
private void setOrientation(int requestedOrientation, boolean freezeScreenIfNeeded) {
@@ -4065,7 +4061,7 @@ final class ActivityRecord extends AppWindowToken {
+ " preserveWindow=" + preserveWindow);
EventLog.writeEvent(andResume ? AM_RELAUNCH_RESUME_ACTIVITY
: AM_RELAUNCH_ACTIVITY, mUserId, System.identityHashCode(this),
- task.taskId, shortComponentName);
+ task.mTaskId, shortComponentName);
startFreezingScreenLocked(0);
@@ -4400,7 +4396,7 @@ final class ActivityRecord extends AppWindowToken {
@Override
public String toString() {
if (stringName != null) {
- return stringName + " t" + (task == null ? INVALID_TASK_ID : task.taskId) +
+ return stringName + " t" + (task == null ? INVALID_TASK_ID : task.mTaskId) +
(finishing ? " f}" : "") + (mIsExiting ? " mIsExiting=" : "") + "}";
}
StringBuilder sb = new StringBuilder(128);
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 24f58f19294e..595925442053 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -775,7 +775,7 @@ class ActivityStack extends ConfigurationContainer {
// multi-window mode.
final String packageName = topActivity.info.applicationInfo.packageName;
mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
- topTask.taskId, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN, packageName);
+ topTask.mTaskId, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN, packageName);
}
mService.deferWindowLayout();
@@ -1114,7 +1114,7 @@ class ActivityStack extends ConfigurationContainer {
final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
TaskRecord task = mTaskHistory.get(taskNdx);
- if (task.taskId == taskId) {
+ if (task.mTaskId == taskId) {
continue;
}
ArrayList<ActivityRecord> activities = task.mActivities;
@@ -1150,7 +1150,7 @@ class ActivityStack extends ConfigurationContainer {
TaskRecord taskForIdLocked(int id) {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
- if (task.taskId == id) {
+ if (task.mTaskId == id) {
return task;
}
}
@@ -1345,7 +1345,7 @@ class ActivityStack extends ConfigurationContainer {
if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
continue;
}
- if (task.userId != userId) {
+ if (task.mUserId != userId) {
// Looking for a different task.
if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user");
continue;
@@ -2863,7 +2863,7 @@ class ActivityStack extends ConfigurationContainer {
next.notifyAppResumed(next.stopped);
EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.mUserId,
- System.identityHashCode(next), next.getTaskRecord().taskId,
+ System.identityHashCode(next), next.getTaskRecord().mTaskId,
next.shortComponentName);
next.sleeping = false;
@@ -2973,7 +2973,7 @@ class ActivityStack extends ConfigurationContainer {
// The task can't be shown, put non-current user tasks below current user tasks.
while (maxPosition > 0) {
final TaskRecord tmpTask = mTaskHistory.get(maxPosition - 1);
- if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.userId)
+ if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.mUserId)
|| tmpTask.topRunningActivityLocked() == null) {
break;
}
@@ -3026,7 +3026,7 @@ class ActivityStack extends ConfigurationContainer {
void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
boolean newTask, boolean keepCurTransition, ActivityOptions options) {
TaskRecord rTask = r.getTaskRecord();
- final int taskId = rTask.taskId;
+ final int taskId = rTask.mTaskId;
final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
// mLaunchTaskBehind tasks get placed at the back of the task stack.
if (!r.mLaunchTaskBehind && allowMoveToFront
@@ -4098,7 +4098,7 @@ class ActivityStack extends ConfigurationContainer {
Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
r.mUserId, System.identityHashCode(r),
- r.getTaskRecord().taskId, r.shortComponentName,
+ r.getTaskRecord().mTaskId, r.shortComponentName,
"proc died without state saved");
}
} else {
@@ -4223,7 +4223,7 @@ class ActivityStack extends ConfigurationContainer {
}
mRootActivityContainer.resumeFocusedStacksTopActivities();
- EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
+ EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.mUserId, tr.mTaskId);
mService.getTaskChangeNotificationController().notifyTaskMovedToFront(tr.getTaskInfo());
} finally {
getDisplay().continueUpdateImeTarget();
@@ -4520,7 +4520,7 @@ class ActivityStack extends ConfigurationContainer {
continue;
}
if (task.effectiveUid != callingUid) {
- if (task.userId != userId && !crossUser && !profileIds.contains(task.userId)) {
+ if (task.mUserId != userId && !crossUser && !profileIds.contains(task.mUserId)) {
// Skip if the caller does not have cross user permission or cannot access
// the task's profile
continue;
@@ -4545,7 +4545,7 @@ class ActivityStack extends ConfigurationContainer {
// For the focused stack top task, update the last stack active time so that it can
// be used to determine the order of the tasks (it may not be set for newly created
// tasks)
- task.lastActiveTime = SystemClock.elapsedRealtime();
+ task.touchActiveTime();
topTask = false;
}
tasksOut.add(task);
@@ -4654,7 +4654,7 @@ class ActivityStack extends ConfigurationContainer {
if (needSep) {
pw.println("");
}
- pw.println(prefix + "Task id #" + task.taskId);
+ pw.println(prefix + "Task id #" + task.mTaskId);
pw.println(prefix + "mBounds=" + task.getRequestedOverrideBounds());
pw.println(prefix + "mMinWidth=" + task.mMinWidth);
pw.println(prefix + "mMinHeight=" + task.mMinHeight);
@@ -4732,7 +4732,7 @@ class ActivityStack extends ConfigurationContainer {
final boolean removed = mTaskHistory.remove(task);
if (removed) {
- EventLog.writeEvent(EventLogTags.AM_REMOVE_TASK, task.taskId, getStackId());
+ EventLog.writeEvent(EventLogTags.AM_REMOVE_TASK, task.mTaskId, getStackId());
}
removeActivitiesFromLRUList(task);
@@ -4884,7 +4884,7 @@ class ActivityStack extends ConfigurationContainer {
mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, prevStack);
} else if (task.voiceSession != null) {
try {
- task.voiceSession.taskStarted(task.intent, task.taskId);
+ task.voiceSession.taskStarted(task.intent, task.mTaskId);
} catch (RemoteException e) {
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 3dff51d47f21..f1284d81bfbf 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -821,7 +821,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
+ " with results=" + results + " newIntents=" + newIntents
+ " andResume=" + andResume);
EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, r.mUserId,
- System.identityHashCode(r), task.taskId, r.shortComponentName);
+ System.identityHashCode(r), task.mTaskId, r.shortComponentName);
if (r.isActivityTypeHome()) {
// Home process is the root process of the task.
updateHomeProcess(task.mActivities.get(0).app);
@@ -1765,7 +1765,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
moveTasksToFullscreenStackLocked(stack, !ON_TOP);
} else {
for (int i = tasks.size() - 1; i >= 0; i--) {
- removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */,
+ removeTaskByIdLocked(tasks.get(i).mTaskId, true /* killProcess */,
REMOVE_FROM_RECENTS, "remove-stack");
}
}
@@ -1817,7 +1817,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
// Find any running services associated with this app and stop if needed.
final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::cleanUpServices,
- mService.mAmInternal, tr.userId, component, new Intent(tr.getBaseIntent()));
+ mService.mAmInternal, tr.mUserId, component, new Intent(tr.getBaseIntent()));
mService.mH.sendMessage(msg);
if (!killProcess) {
@@ -1834,7 +1834,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
SparseArray<WindowProcessController> uids = pmap.valueAt(i);
for (int j = 0; j < uids.size(); j++) {
WindowProcessController proc = uids.valueAt(j);
- if (proc.mUserId != tr.userId) {
+ if (proc.mUserId != tr.mUserId) {
// Don't kill process for a different user.
continue;
}
@@ -1916,7 +1916,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
if (wasTrimmed) {
// Task was trimmed from the recent tasks list -- remove the active task record as well
// since the user won't really be able to go back to it
- removeTaskByIdLocked(task.taskId, killProcess, false /* removeFromRecents */,
+ removeTaskByIdLocked(task.mTaskId, killProcess, false /* removeFromRecents */,
"recent-task-trimmed");
}
task.removedFromRecents();
@@ -2477,7 +2477,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
return;
}
mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
- task.taskId, reason, topActivity.info.applicationInfo.packageName);
+ task.mTaskId, reason, topActivity.info.applicationInfo.packageName);
}
void activityRelaunchedLocked(IBinder token) {
@@ -2699,7 +2699,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
* @param task The task to put into resizing mode
*/
void setResizingDuringAnimation(TaskRecord task) {
- mResizingTasksDuringAnimation.add(task.taskId);
+ mResizingTasksDuringAnimation.add(task.mTaskId);
task.setTaskDockedResizing(true);
}
@@ -2761,7 +2761,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
// If the user must confirm credentials (e.g. when first launching a work app and the
// Work Challenge is present) let startActivityInPackage handle the intercepting.
- if (!mService.mAmInternal.shouldConfirmCredentials(task.userId)
+ if (!mService.mAmInternal.shouldConfirmCredentials(task.mUserId)
&& task.getRootActivity() != null) {
final ActivityRecord targetActivity = task.getTopActivity();
@@ -2770,7 +2770,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
mActivityMetricsLogger.notifyActivityLaunching(task.intent);
try {
mService.moveTaskToFrontLocked(null /* appThread */, null /* callingPackage */,
- task.taskId, 0, options, true /* fromRecents */);
+ task.mTaskId, 0, options, true /* fromRecents */);
// Apply options to prevent pendingOptions be taken by client to make sure
// the override pending app transition will be applied immediately.
targetActivity.applyOptionsLocked();
@@ -2787,7 +2787,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
callingPackage = task.mCallingPackage;
intent = task.intent;
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
- userId = task.userId;
+ userId = task.mUserId;
return mService.getActivityStartController().startActivityInPackage(
task.mCallingUid, callingPid, callingUid, callingPackage, intent, null, null,
null, 0, 0, options, userId, task, "startActivityFromRecents",
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index cc69b5a7205f..effd154a6aa0 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -274,7 +274,7 @@ class ActivityStartInterceptor {
// ConfirmCredentials intent and unassign it, as otherwise the task will move to
// front even if ConfirmCredentials is cancelled.
if (mInTask != null) {
- mIntent.putExtra(EXTRA_TASK_ID, mInTask.taskId);
+ mIntent.putExtra(EXTRA_TASK_ID, mInTask.mTaskId);
mInTask = null;
}
if (mActivityOptions == null) {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 38e5e3e6beb5..939789307333 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1557,7 +1557,7 @@ class ActivityStarter {
);
if (newTask) {
EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.mUserId,
- mStartActivity.getTaskRecord().taskId);
+ mStartActivity.getTaskRecord().mTaskId);
}
mStartActivity.logStartActivity(
EventLogTags.AM_CREATE_ACTIVITY, mStartActivity.getTaskRecord());
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 299ab8a538ce..750fc6832627 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1618,7 +1618,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// because we don't support returning them across task boundaries. Also, to
// keep backwards compatibility we remove the task from recents when finishing
// task with root activity.
- res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false /* killProcess */,
+ res = mStackSupervisor.removeTaskByIdLocked(tr.mTaskId, false /* killProcess */,
finishWithRootActivity, "finish-activity");
if (!res) {
Slog.i(TAG, "Removing task failed to finish activity");
@@ -2233,7 +2233,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final TaskRecord tr = mRootActivityContainer.anyTaskForId(id,
MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
if (tr != null) {
- return tr.lastTaskDescription;
+ return tr.mTaskDescription;
}
}
return null;
@@ -3032,7 +3032,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
if (structure != null) {
// Pre-fill the task/activity component for all assist data receivers
- structure.setTaskId(pae.activity.getTaskRecord().taskId);
+ structure.setTaskId(pae.activity.getTaskRecord().mTaskId);
structure.setActivityComponent(pae.activity.mActivityComponent);
structure.setHomeActivity(pae.isHome);
}
@@ -3059,7 +3059,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// Caller wants result sent back to them.
sendBundle = new Bundle();
sendBundle.putInt(ActivityTaskManagerInternal.ASSIST_TASK_ID,
- pae.activity.getTaskRecord().taskId);
+ pae.activity.getTaskRecord().mTaskId);
sendBundle.putBinder(ActivityTaskManagerInternal.ASSIST_ACTIVITY_ID,
pae.activity.assistToken);
sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
@@ -3155,11 +3155,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
return INVALID_TASK_ID;
}
- task.lastTaskDescription.copyFrom(description);
+ task.mTaskDescription.copyFrom(description);
// TODO: Send the thumbnail to WM to store it.
- return task.taskId;
+ return task.mTaskId;
}
} finally {
Binder.restoreCallingIdentity(callingIdent);
@@ -4967,8 +4967,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
if (lastTask != task) {
lastTask = task;
pw.print("TASK "); pw.print(lastTask.affinity);
- pw.print(" id="); pw.print(lastTask.taskId);
- pw.print(" userId="); pw.println(lastTask.userId);
+ pw.print(" id="); pw.print(lastTask.mTaskId);
+ pw.print(" userId="); pw.println(lastTask.mUserId);
if (dumpAll) {
lastTask.dump(pw, " ");
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 721de613166e..b1ef60185d8d 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1735,13 +1735,13 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
}
/** @return {@code true} if the compatibility bounds is taking effect. */
- boolean inSizeCompatMode() {
+ boolean hasSizeCompatBounds() {
return mSizeCompatBounds != null;
}
@Override
float getSizeCompatScale() {
- return inSizeCompatMode() ? mSizeCompatScale : super.getSizeCompatScale();
+ return hasSizeCompatBounds() ? mSizeCompatScale : super.getSizeCompatScale();
}
@Override
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 3b90b7e0fcd4..f592ac6957cb 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -132,7 +132,6 @@ import static com.android.server.wm.WindowManagerService.dipToPixel;
import static com.android.server.wm.WindowState.EXCLUSION_LEFT;
import static com.android.server.wm.WindowState.EXCLUSION_RIGHT;
import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
-import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
import static com.android.server.wm.utils.RegionUtils.forEachRectReverse;
import static com.android.server.wm.utils.RegionUtils.rectListToRegion;
@@ -221,7 +220,7 @@ import java.util.function.Predicate;
* particular Display.
*/
class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer>
- implements WindowManagerPolicy.DisplayContentInfo {
+ implements WindowManagerPolicy.DisplayContentInfo, ConfigurationContainerListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
/** The default scaling mode that scales content automatically. */
@@ -240,7 +239,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
private final int mDisplayId;
// TODO: Remove once unification is complete.
- ActivityDisplay mAcitvityDisplay;
+ ActivityDisplay mActivityDisplay;
/** The containers below are the only child containers the display can have. */
// Contains all window containers that are related to apps (Activities)
@@ -852,7 +851,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
DisplayContent(Display display, WindowManagerService service,
ActivityDisplay activityDisplay) {
super(service);
- mAcitvityDisplay = activityDisplay;
+ mActivityDisplay = activityDisplay;
if (service.mRoot.getDisplayContent(display.getDisplayId()) != null) {
throw new IllegalArgumentException("Display with ID=" + display.getDisplayId()
+ " already exists=" + service.mRoot.getDisplayContent(display.getDisplayId())
@@ -1136,10 +1135,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
* values from being replaced by the initializing {@link #ActivityDisplay}.
*/
void initializeDisplayOverrideConfiguration() {
- if (mAcitvityDisplay != null) {
- mAcitvityDisplay.getRequestedOverrideConfiguration()
- .updateFrom(getRequestedOverrideConfiguration());
+ if (mActivityDisplay == null) {
+ return;
}
+ mActivityDisplay.onRequestedOverrideConfigurationChanged(
+ getResolvedOverrideConfiguration());
+ mActivityDisplay.registerConfigurationChangeListener(this);
}
void reconfigureDisplayLocked() {
@@ -1165,10 +1166,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
void sendNewConfiguration() {
- if (!isReady() || mAcitvityDisplay == null) {
+ if (!isReady() || mActivityDisplay == null) {
return;
}
- final boolean configUpdated = mAcitvityDisplay.updateDisplayOverrideConfigurationLocked();
+ final boolean configUpdated = mActivityDisplay.updateDisplayOverrideConfigurationLocked();
if (configUpdated) {
return;
}
@@ -1199,7 +1200,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (handled && requestingContainer instanceof ActivityRecord) {
final ActivityRecord activityRecord = (ActivityRecord) requestingContainer;
- final boolean kept = mAcitvityDisplay.updateDisplayOverrideConfigurationLocked(
+ final boolean kept = mActivityDisplay.updateDisplayOverrideConfigurationLocked(
config, activityRecord, false /* deferResume */, null /* result */);
activityRecord.frozenBeforeDestroy = true;
if (!kept) {
@@ -1208,7 +1209,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
} else {
// We have a new configuration to push so we need to update ATMS for now.
// TODO: Clean up display configuration push between ATMS and WMS after unification.
- mAcitvityDisplay.updateDisplayOverrideConfigurationLocked(
+ mActivityDisplay.updateDisplayOverrideConfigurationLocked(
config, null /* starting */, false /* deferResume */, null);
}
return handled;
@@ -2373,6 +2374,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
void removeImmediately() {
mRemovingDisplay = true;
try {
+ if (mActivityDisplay != null) {
+ mActivityDisplay.unregisterConfigurationChangeListener(this);
+ }
if (mParentWindow != null) {
mParentWindow.removeEmbeddedDisplayContent(this);
}
@@ -3514,19 +3518,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
mWmService.mWindowPlacerLocked.performSurfacePlacement();
}
- void waitForAllWindowsDrawn() {
- final WindowManagerPolicy policy = mWmService.mPolicy;
- forAllWindows(w -> {
- final boolean keyguard = policy.isKeyguardHostWindow(w.mAttrs);
- if (w.isVisibleLw() && (w.mAppToken != null || keyguard)) {
- w.mWinAnimator.mDrawState = DRAW_PENDING;
- // Force add to mResizingWindows.
- w.resetLastContentInsets();
- mWmService.mWaitingForDrawn.add(w);
- }
- }, true /* traverseTopToBottom */);
- }
-
// TODO: Super crazy long method that should be broken down...
void applySurfaceChangesTransaction(boolean recoveringMemory) {
final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index ae3b5f2f70d3..d3e429019767 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -819,9 +819,12 @@ public class DockedStackDividerController {
// We put all tasks into drag resizing mode - wait until all of them have completed the
// drag resizing switch.
- if (!mService.mWaitingForDrawn.isEmpty()) {
- mService.mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
- mService.mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT,
+ final Runnable existingWaitingForDrwanCallback =
+ mService.mWaitingForDrawnCallbacks.get(mService.mRoot);
+ if (existingWaitingForDrwanCallback != null) {
+ mService.mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, mService.mRoot);
+ mService.mH.sendMessageDelayed(mService.mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT,
+ mService.mRoot),
IME_ADJUST_DRAWN_TIMEOUT);
mAnimationStartDelayed = true;
if (imeWin != null) {
@@ -838,10 +841,8 @@ public class DockedStackDividerController {
// still gets executed.
// TODO: Have a real system where we can wait on different windows to be drawn with
// different callbacks.
- if (mService.mWaitingForDrawnCallback != null) {
- mService.mWaitingForDrawnCallback.run();
- }
- mService.mWaitingForDrawnCallback = () -> {
+ existingWaitingForDrwanCallback.run();
+ mService.mWaitingForDrawnCallbacks.put(mService.mRoot, () -> {
synchronized (mService.mGlobalLock) {
mAnimationStartDelayed = false;
if (mDelayedImeWin != null) {
@@ -863,7 +864,7 @@ public class DockedStackDividerController {
notifyAdjustedForImeChanged(
mAdjustedForIme || mAdjustedForDivider, duration);
}
- };
+ });
} else {
notifyAdjustedForImeChanged(
adjustedForIme || adjustedForDivider, IME_ADJUST_ANIM_DURATION);
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
new file mode 100644
index 000000000000..7e085f677be9
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.view.InsetsSource;
+import android.view.WindowInsets;
+
+/**
+ * Controller for IME inset source on the server. It's called provider as it provides the
+ * {@link InsetsSource} to the client that uses it in {@link InsetsSourceConsumer}.
+ */
+class ImeInsetsSourceProvider extends InsetsSourceProvider {
+
+ private WindowState mCurImeTarget;
+ private Runnable mShowImeRunner;
+ private boolean mIsImeLayoutDrawn;
+
+ ImeInsetsSourceProvider(InsetsSource source,
+ InsetsStateController stateController, DisplayContent displayContent) {
+ super(source, stateController, displayContent);
+ }
+
+ /**
+ * Called when a layout pass has occurred.
+ */
+ void onPostLayout() {
+ super.onPostLayout();
+
+ if (mCurImeTarget != null
+ && mCurImeTarget == mDisplayContent.mInputMethodTarget
+ && mWin != null
+ && mWin.isDrawnLw()
+ && !mWin.mGivenInsetsPending) {
+ mIsImeLayoutDrawn = true;
+ }
+ }
+
+ /**
+ * Called when Insets have been dispatched to client.
+ */
+ void onPostInsetsDispatched() {
+ if (mIsImeLayoutDrawn && mShowImeRunner != null) {
+ // Show IME if InputMethodService requested to be shown and it's layout has finished.
+ mShowImeRunner.run();
+ mIsImeLayoutDrawn = false;
+ mShowImeRunner = null;
+ }
+ }
+
+ /**
+ * Called from {@link WindowManagerInternal#showImePostLayout} when {@link InputMethodService}
+ * requests to show IME on {@param imeTarget}.
+ * @param imeTarget imeTarget on which IME is displayed.
+ */
+ void scheduleShowImePostLayout(WindowState imeTarget) {
+ mCurImeTarget = imeTarget;
+ mShowImeRunner = () -> {
+ // Target should still be the same.
+ if (mCurImeTarget == mDisplayContent.mInputMethodTarget) {
+ mDisplayContent.mInputMethodTarget.showInsets(
+ WindowInsets.Type.ime(), true /* fromIme */);
+ }
+ mCurImeTarget = null;
+ };
+ }
+
+}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 842686441465..cc55e0137e20 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -47,9 +47,11 @@ import java.io.PrintWriter;
*/
class InsetsSourceProvider {
+ protected final DisplayContent mDisplayContent;
+ protected final @NonNull InsetsSource mSource;
+ protected WindowState mWin;
+
private final Rect mTmpRect = new Rect();
- private final @NonNull InsetsSource mSource;
- private final DisplayContent mDisplayContent;
private final InsetsStateController mStateController;
private final InsetsSourceControl mFakeControl;
private @Nullable InsetsSourceControl mControl;
@@ -57,7 +59,6 @@ class InsetsSourceProvider {
private @Nullable InsetsControlTarget mFakeControlTarget;
private @Nullable ControlAdapter mAdapter;
- private WindowState mWin;
private TriConsumer<DisplayFrames, WindowState, Rect> mFrameProvider;
/** The visibility override from the current controlling window. */
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 4ebb553318e8..b0410335c5cd 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -108,8 +108,18 @@ class InsetsStateController {
* @return The provider of a specific type.
*/
InsetsSourceProvider getSourceProvider(@InternalInsetType int type) {
- return mProviders.computeIfAbsent(type,
- key -> new InsetsSourceProvider(mState.getSource(key), this, mDisplayContent));
+ if (type == TYPE_IME) {
+ return mProviders.computeIfAbsent(type,
+ key -> new ImeInsetsSourceProvider(
+ mState.getSource(key), this, mDisplayContent));
+ } else {
+ return mProviders.computeIfAbsent(type,
+ key -> new InsetsSourceProvider(mState.getSource(key), this, mDisplayContent));
+ }
+ }
+
+ ImeInsetsSourceProvider getImeSourceProvider() {
+ return (ImeInsetsSourceProvider) getSourceProvider(TYPE_IME);
}
/**
@@ -124,6 +134,7 @@ class InsetsStateController {
mLastState.set(mState, true /* copySources */);
notifyInsetsChanged();
}
+ getImeSourceProvider().onPostInsetsDispatched();
}
void onInsetsModified(WindowState windowState, InsetsState state) {
diff --git a/services/core/java/com/android/server/wm/LaunchParamsPersister.java b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
index d364a3765c22..013607e65367 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsPersister.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
@@ -198,7 +198,7 @@ class LaunchParamsPersister {
void saveTask(TaskRecord task) {
final ComponentName name = task.realActivity;
- final int userId = task.userId;
+ final int userId = task.mUserId;
PersistableLaunchParams params;
ArrayMap<ComponentName, PersistableLaunchParams> map = mMap.get(userId);
if (map == null) {
@@ -247,7 +247,7 @@ class LaunchParamsPersister {
void getLaunchParams(TaskRecord task, ActivityRecord activity, LaunchParams outParams) {
final ComponentName name = task != null ? task.realActivity : activity.mActivityComponent;
- final int userId = task != null ? task.userId : activity.mUserId;
+ final int userId = task != null ? task.mUserId : activity.mUserId;
outParams.reset();
Map<ComponentName, PersistableLaunchParams> map = mMap.get(userId);
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index b30da5e156e2..dc45686a1359 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -317,12 +317,12 @@ public class LockTaskController {
}
// Allow recents activity if enabled by policy
- if (task.isActivityTypeRecents() && isRecentsAllowed(task.userId)) {
+ if (task.isActivityTypeRecents() && isRecentsAllowed(task.mUserId)) {
return false;
}
// Allow emergency calling when the device is protected by a locked keyguard
- if (isKeyguardAllowed(task.userId) && isEmergencyCallTask(task)) {
+ if (isKeyguardAllowed(task.mUserId) && isEmergencyCallTask(task)) {
return false;
}
@@ -474,7 +474,7 @@ public class LockTaskController {
if (mLockTaskModeTasks.isEmpty()) {
if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
" last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
- mHandler.post(() -> performStopLockTask(task.userId));
+ mHandler.post(() -> performStopLockTask(task.mUserId));
}
}
@@ -537,7 +537,7 @@ public class LockTaskController {
StatusBarManagerInternal statusBarManager = LocalServices.getService(
StatusBarManagerInternal.class);
if (statusBarManager != null) {
- statusBarManager.showScreenPinningRequest(task.taskId);
+ statusBarManager.showScreenPinningRequest(task.mTaskId);
}
return;
}
@@ -570,11 +570,11 @@ public class LockTaskController {
final Intent taskIntent = task.intent;
if (mLockTaskModeTasks.isEmpty() && taskIntent != null) {
- mSupervisor.mRecentTasks.onLockTaskModeStateChanged(lockTaskModeState, task.userId);
+ mSupervisor.mRecentTasks.onLockTaskModeStateChanged(lockTaskModeState, task.mUserId);
// Start lock task on the handler thread
mHandler.post(() -> performStartLockTask(
taskIntent.getComponent().getPackageName(),
- task.userId,
+ task.mUserId,
lockTaskModeState));
}
if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskMode: Locking to " + task +
@@ -640,7 +640,7 @@ public class LockTaskController {
|| lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED;
if (mLockTaskModeState != LOCK_TASK_MODE_LOCKED
- || lockedTask.userId != userId
+ || lockedTask.mUserId != userId
|| !wasWhitelisted || isWhitelisted) {
continue;
}
@@ -704,7 +704,7 @@ public class LockTaskController {
}
mLockTaskFeatures.put(userId, flags);
- if (!mLockTaskModeTasks.isEmpty() && userId == mLockTaskModeTasks.get(0).userId) {
+ if (!mLockTaskModeTasks.isEmpty() && userId == mLockTaskModeTasks.get(0).mUserId) {
mHandler.post(() -> {
if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
setStatusBarState(mLockTaskModeState, userId);
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index fb6b5da87f2d..71696778f891 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -120,7 +120,7 @@ class RecentTasks {
// Comparator to sort by taskId
private static final Comparator<TaskRecord> TASK_ID_COMPARATOR =
- (lhs, rhs) -> rhs.taskId - lhs.taskId;
+ (lhs, rhs) -> rhs.mTaskId - lhs.mTaskId;
// Placeholder variables to keep track of activities/apps that are no longer avialble while
// iterating through the recents list
@@ -272,9 +272,14 @@ class RecentTasks {
* app, or a timeout occurs.
*/
void setFreezeTaskListReordering() {
+ // Only fire the callback once per quickswitch session, not on every individual switch
+ if (!mFreezeTaskListReordering) {
+ mTaskNotificationController.notifyTaskListFrozen(true);
+ mFreezeTaskListReordering = true;
+ }
+
// Always update the reordering time when this is called to ensure that the timeout
// is reset
- mFreezeTaskListReordering = true;
mService.mH.removeCallbacks(mResetFreezeTaskListOnTimeoutRunnable);
mService.mH.postDelayed(mResetFreezeTaskListOnTimeoutRunnable, mFreezeTaskListTimeoutMs);
}
@@ -302,6 +307,7 @@ class RecentTasks {
trimInactiveRecentTasks();
mTaskNotificationController.notifyTaskStackChanged();
+ mTaskNotificationController.notifyTaskListFrozen(false);
}
/**
@@ -458,8 +464,8 @@ class RecentTasks {
// Check if any tasks are added before recents is loaded
final SparseBooleanArray preaddedTasks = new SparseBooleanArray();
for (final TaskRecord task : mTasks) {
- if (task.userId == userId && shouldPersistTaskLocked(task)) {
- preaddedTasks.put(task.taskId, true);
+ if (task.mUserId == userId && shouldPersistTaskLocked(task)) {
+ preaddedTasks.put(task.mTaskId, true);
}
}
@@ -527,12 +533,12 @@ class RecentTasks {
if (shouldPersistTaskLocked(task)) {
// Set of persisted taskIds for task.userId should not be null here
// TODO Investigate why it can happen. For now initialize with an empty set
- if (mPersistedTaskIds.get(task.userId) == null) {
- Slog.wtf(TAG, "No task ids found for userId " + task.userId + ". task=" + task
+ if (mPersistedTaskIds.get(task.mUserId) == null) {
+ Slog.wtf(TAG, "No task ids found for userId " + task.mUserId + ". task=" + task
+ " mPersistedTaskIds=" + mPersistedTaskIds);
- mPersistedTaskIds.put(task.userId, new SparseBooleanArray());
+ mPersistedTaskIds.put(task.mUserId, new SparseBooleanArray());
}
- mPersistedTaskIds.get(task.userId).put(task.taskId, true);
+ mPersistedTaskIds.get(task.mUserId).put(task.mTaskId, true);
}
}
}
@@ -608,7 +614,7 @@ class RecentTasks {
for (int i = mTasks.size() - 1; i >= 0; --i) {
TaskRecord tr = mTasks.get(i);
- if (tr.userId == userId) {
+ if (tr.mUserId == userId) {
if(DEBUG_TASKS) Slog.i(TAG_TASKS,
"remove RecentTask " + tr + " when finishing user" + userId);
remove(tr);
@@ -622,11 +628,11 @@ class RecentTasks {
final TaskRecord tr = mTasks.get(i);
if (tr.realActivity != null
&& packageNames.contains(tr.realActivity.getPackageName())
- && tr.userId == userId
+ && tr.mUserId == userId
&& tr.realActivitySuspended != suspended) {
tr.realActivitySuspended = suspended;
if (suspended) {
- mSupervisor.removeTaskByIdLocked(tr.taskId, false,
+ mSupervisor.removeTaskByIdLocked(tr.mTaskId, false,
REMOVE_FROM_RECENTS, "suspended-package");
}
notifyTaskPersisterLocked(tr, false);
@@ -640,7 +646,7 @@ class RecentTasks {
}
for (int i = mTasks.size() - 1; i >= 0; --i) {
final TaskRecord tr = mTasks.get(i);
- if (tr.userId == userId && !mService.getLockTaskController().isTaskWhitelisted(tr)) {
+ if (tr.mUserId == userId && !mService.getLockTaskController().isTaskWhitelisted(tr)) {
remove(tr);
}
}
@@ -651,10 +657,10 @@ class RecentTasks {
final TaskRecord tr = mTasks.get(i);
final String taskPackageName =
tr.getBaseIntent().getComponent().getPackageName();
- if (tr.userId != userId) continue;
+ if (tr.mUserId != userId) continue;
if (!taskPackageName.equals(packageName)) continue;
- mSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS,
+ mSupervisor.removeTaskByIdLocked(tr.mTaskId, true, REMOVE_FROM_RECENTS,
"remove-package-task");
}
}
@@ -663,7 +669,7 @@ class RecentTasks {
Set<Integer> profileIds = getProfileIds(userId);
for (int i = mTasks.size() - 1; i >= 0; --i) {
final TaskRecord tr = mTasks.get(i);
- if (!profileIds.contains(tr.userId)) continue;
+ if (!profileIds.contains(tr.mUserId)) continue;
if (isVisibleRecentTask(tr)) {
mTasks.remove(i);
notifyTaskRemoved(tr, true /* wasTrimmed */, true /* killProcess */);
@@ -675,7 +681,7 @@ class RecentTasks {
int userId) {
for (int i = mTasks.size() - 1; i >= 0; --i) {
final TaskRecord tr = mTasks.get(i);
- if (userId != UserHandle.USER_ALL && tr.userId != userId) {
+ if (userId != UserHandle.USER_ALL && tr.mUserId != userId) {
continue;
}
@@ -683,7 +689,7 @@ class RecentTasks {
final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
&& (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
if (sameComponent) {
- mSupervisor.removeTaskByIdLocked(tr.taskId, false,
+ mSupervisor.removeTaskByIdLocked(tr.mTaskId, false,
REMOVE_FROM_RECENTS, "disabled-package");
}
}
@@ -709,7 +715,7 @@ class RecentTasks {
final IPackageManager pm = AppGlobals.getPackageManager();
for (int i = recentsCount - 1; i >= 0; i--) {
final TaskRecord task = mTasks.get(i);
- if (userId != UserHandle.USER_ALL && task.userId != userId) {
+ if (userId != UserHandle.USER_ALL && task.mUserId != userId) {
// Only look at tasks for the user ID of interest.
continue;
}
@@ -826,7 +832,7 @@ class RecentTasks {
if (intent == null || !callingPackage.equals(intent.getComponent().getPackageName())) {
continue;
}
- AppTaskImpl taskImpl = new AppTaskImpl(mService, tr.taskId, callingUid);
+ AppTaskImpl taskImpl = new AppTaskImpl(mService, tr.mTaskId, callingUid);
list.add(taskImpl.asBinder());
}
return list;
@@ -908,7 +914,7 @@ class RecentTasks {
}
// Only add calling user or related users recent tasks
- if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
+ if (!includedUsers.contains(Integer.valueOf(tr.mUserId))) {
if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
continue;
}
@@ -972,7 +978,7 @@ class RecentTasks {
if ((task.isPersistable || task.inRecents)
&& (stack == null || !stack.isHomeOrRecentsStack())) {
if (TaskPersister.DEBUG) Slog.d(TAG, "adding to persistentTaskIds task=" + task);
- persistentTaskIds.add(task.taskId);
+ persistentTaskIds.add(task.mTaskId);
} else {
if (TaskPersister.DEBUG) Slog.d(TAG, "omitting from persistentTaskIds task="
+ task);
@@ -997,7 +1003,7 @@ class RecentTasks {
if (isVisibleRecentTask(tr)) {
numVisibleTasks++;
if (isInVisibleRange(tr, i, numVisibleTasks, false /* skipExcludedCheck */)) {
- res.put(tr.taskId, true);
+ res.put(tr.mTaskId, true);
}
}
}
@@ -1011,7 +1017,7 @@ class RecentTasks {
final int recentsCount = mTasks.size();
for (int i = 0; i < recentsCount; i++) {
TaskRecord tr = mTasks.get(i);
- if (tr.taskId == id) {
+ if (tr.mTaskId == id) {
return tr;
}
}
@@ -1024,7 +1030,7 @@ class RecentTasks {
void add(TaskRecord task) {
if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "add: task=" + task);
- final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
+ final boolean isAffiliated = task.mAffiliatedTaskId != task.mTaskId
|| task.mNextAffiliateTaskId != INVALID_TASK_ID
|| task.mPrevAffiliateTaskId != INVALID_TASK_ID;
@@ -1138,7 +1144,7 @@ class RecentTasks {
if (needAffiliationFix) {
if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: regrouping affiliations");
- cleanupLocked(task.userId);
+ cleanupLocked(task.mUserId);
}
// Trim the set of tasks to the active set
@@ -1248,13 +1254,13 @@ class RecentTasks {
if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "isActiveRecentTask: task=" + task
+ " globalMax=" + mGlobalMaxNumTasks);
- if (quietProfileUserIds.get(task.userId)) {
+ if (quietProfileUserIds.get(task.mUserId)) {
// Quiet profile user's tasks are never active
if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\tisQuietProfileTask=true");
return false;
}
- if (task.mAffiliatedTaskId != INVALID_TASK_ID && task.mAffiliatedTaskId != task.taskId) {
+ if (task.mAffiliatedTaskId != INVALID_TASK_ID && task.mAffiliatedTaskId != task.mTaskId) {
// Keep the task active if its affiliated task is also active
final TaskRecord affiliatedTask = getTask(task.mAffiliatedTaskId);
if (affiliatedTask != null) {
@@ -1430,7 +1436,7 @@ class RecentTasks {
final TaskRecord tr = mTasks.get(i);
if (task != tr) {
if (!hasCompatibleActivityTypeAndWindowingMode(task, tr)
- || task.userId != tr.userId) {
+ || task.mUserId != tr.mUserId) {
continue;
}
final Intent trIntent = tr.intent;
@@ -1485,7 +1491,7 @@ class RecentTasks {
final int affiliateId = startTask.mAffiliatedTaskId;
// Quick identification of isolated tasks. I.e. those not launched behind.
- if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
+ if (startTask.mTaskId == affiliateId && startTask.mPrevAffiliate == null &&
startTask.mNextAffiliate == null) {
// There is still a slim chance that there are other tasks that point to this task
// and that the chain is so messed up that this task no longer points to them but
@@ -1581,7 +1587,7 @@ class RecentTasks {
} else {
// Verify middle of the chain's next points back to the one before.
if (cur.mNextAffiliate != prev
- || cur.mNextAffiliateTaskId != prev.taskId) {
+ || cur.mNextAffiliateTaskId != prev.mTaskId) {
Slog.wtf(TAG, "Bad chain @" + endIndex
+ ": middle task " + cur + " @" + endIndex
+ " has bad next affiliate "
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 0075c15cbca5..062cdc5b2b60 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -492,7 +492,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
for (int i = targetStack.getChildCount() - 1; i >= 0; i--) {
final TaskRecord task = targetStack.getChildAt(i);
- if (task.userId == mUserId
+ if (task.mUserId == mUserId
&& task.getBaseIntent().getComponent().equals(mTargetIntent.getComponent())) {
return task.getTopActivity();
}
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 8a47c5aa81a3..d78d517fcfc1 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -652,9 +652,9 @@ class RootActivityContainer extends ConfigurationContainer
starting.frozenBeforeDestroy = true;
}
- if (displayContent != null && displayContent.mAcitvityDisplay != null) {
+ if (displayContent != null && displayContent.mActivityDisplay != null) {
// Update the configuration of the activities on the display.
- return displayContent.mAcitvityDisplay.updateDisplayOverrideConfigurationLocked(config,
+ return displayContent.mActivityDisplay.updateDisplayOverrideConfigurationLocked(config,
starting, deferResume, null /* result */);
} else {
return true;
@@ -1103,7 +1103,7 @@ class RootActivityContainer extends ConfigurationContainer
}
}
}
- return finishedTask != null ? finishedTask.taskId : INVALID_TASK_ID;
+ return finishedTask != null ? finishedTask.mTaskId : INVALID_TASK_ID;
}
boolean resumeFocusedStacksTopActivities() {
@@ -1260,14 +1260,14 @@ class RootActivityContainer extends ConfigurationContainer
int[] taskUserIds = new int[numTasks];
for (int i = 0; i < numTasks; ++i) {
final TaskRecord task = tasks.get(i);
- taskIds[i] = task.taskId;
+ taskIds[i] = task.mTaskId;
taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
: task.realActivity != null ? task.realActivity.flattenToString()
: task.getTopActivity() != null ? task.getTopActivity().packageName
: "unknown";
taskBounds[i] = new Rect();
task.getWindowContainerBounds(taskBounds[i]);
- taskUserIds[i] = task.userId;
+ taskUserIds[i] = task.mUserId;
}
info.taskIds = taskIds;
info.taskNames = taskNames;
@@ -2103,7 +2103,7 @@ class RootActivityContainer extends ConfigurationContainer
// picker for personal files, opened by a work app, should still get locked.
if (taskTopActivityIsUser(task, userId)) {
mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
- task.taskId, userId);
+ task.mTaskId, userId);
}
}
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 78fcb37aacd1..6f10d3d291b1 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -230,7 +230,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
final DisplayContent existing = getDisplayContent(displayId);
if (existing != null) {
- existing.mAcitvityDisplay = activityDisplay;
+ existing.mActivityDisplay = activityDisplay;
existing.initializeDisplayOverrideConfiguration();
return existing;
}
@@ -720,7 +720,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
mUpdateRotation = updateRotationUnchecked();
}
- if (mWmService.mWaitingForDrawnCallback != null
+ if (!mWmService.mWaitingForDrawnCallbacks.isEmpty()
|| (mOrientationChangeComplete && !isLayoutNeeded()
&& !mUpdateRotation)) {
mWmService.checkDrawnWindowsLocked();
@@ -1067,7 +1067,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
void positionChildAt(int position, DisplayContent child, boolean includingParents) {
super.positionChildAt(position, child, includingParents);
if (mRootActivityContainer != null) {
- mRootActivityContainer.onChildPositionChanged(child.mAcitvityDisplay, position);
+ mRootActivityContainer.onChildPositionChanged(child.mActivityDisplay, position);
}
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 2ad91029212f..a181c1837af7 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -20,12 +20,8 @@ import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.res.Configuration.EMPTY;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.SurfaceControl.METADATA_TASK_ID;
import static com.android.server.EventLogTags.WM_TASK_REMOVED;
@@ -67,7 +63,9 @@ class Task extends WindowContainer<AppWindowToken> implements ConfigurationConta
// TODO: Track parent marks like this in WindowContainer.
TaskStack mStack;
+ /* Unique identifier for this task. */
final int mTaskId;
+ /* User for which this task was created. */
final int mUserId;
private boolean mDeferRemoval = false;
@@ -101,6 +99,8 @@ class Task extends WindowContainer<AppWindowToken> implements ConfigurationConta
private boolean mDragResizing;
private int mDragResizeMode;
+ // This represents the last resolved activity values for this task
+ // NOTE: This value needs to be persisted with each task
private TaskDescription mTaskDescription;
// If set to true, the task will report that it is not in the floating
@@ -135,26 +135,17 @@ class Task extends WindowContainer<AppWindowToken> implements ConfigurationConta
mResizeMode = resizeMode;
mSupportsPictureInPicture = supportsPictureInPicture;
mTaskRecord = taskRecord;
+ mTaskDescription = taskDescription;
+
+ // Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED).
+ setOrientation(SCREEN_ORIENTATION_UNSET);
if (mTaskRecord != null) {
// This can be null when we call createTaskInStack in WindowTestUtils. Remove this after
// unification.
mTaskRecord.registerConfigurationChangeListener(this);
+ } else {
+ setBounds(getResolvedOverrideBounds());
}
- setBounds(getResolvedOverrideBounds());
- mTaskDescription = taskDescription;
-
- // Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED) not unless
- // set through the override configuration.
- int orientation = SCREEN_ORIENTATION_UNSET;
- switch (getResolvedOverrideConfiguration().orientation) {
- case ORIENTATION_PORTRAIT:
- orientation = SCREEN_ORIENTATION_PORTRAIT;
- break;
- case ORIENTATION_LANDSCAPE:
- orientation = SCREEN_ORIENTATION_LANDSCAPE;
- break;
- }
- setOrientation(orientation);
}
@Override
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index 5e8831d47c12..a61c908e0f6f 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -58,6 +58,7 @@ class TaskChangeNotificationController {
private static final int NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG = 23;
private static final int NOTIFY_TASK_LIST_UPDATED_LISTENERS_MSG = 24;
private static final int NOTIFY_SINGLE_TASK_DISPLAY_EMPTY = 25;
+ private static final int NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG = 26;
// Delay in notifying task stack change listeners (in millis)
private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -174,6 +175,10 @@ class TaskChangeNotificationController {
l.onRecentTaskListUpdated();
};
+ private final TaskStackConsumer mNotifyTaskListFrozen = (l, m) -> {
+ l.onRecentTaskListFrozenChanged(m.arg1 != 0);
+ };
+
@FunctionalInterface
public interface TaskStackConsumer {
void accept(ITaskStackListener t, Message m) throws RemoteException;
@@ -265,6 +270,9 @@ class TaskChangeNotificationController {
case NOTIFY_TASK_LIST_UPDATED_LISTENERS_MSG:
forAllRemoteListeners(mNotifyTaskListUpdated, msg);
break;
+ case NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG:
+ forAllRemoteListeners(mNotifyTaskListFrozen, msg);
+ break;
}
}
}
@@ -342,7 +350,7 @@ class TaskChangeNotificationController {
void notifyActivityPinned(ActivityRecord r) {
mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG,
- r.getTaskRecord().taskId, r.getStackId(), r.packageName);
+ r.getTaskRecord().mTaskId, r.getStackId(), r.packageName);
msg.sendingUid = r.mUserId;
forAllLocalListeners(mNotifyActivityPinned, msg);
msg.sendToTarget();
@@ -549,4 +557,12 @@ class TaskChangeNotificationController {
forAllLocalListeners(mNotifyTaskListUpdated, msg);
msg.sendToTarget();
}
+
+ /** @see ITaskStackListener#onRecentTaskListFrozenChanged(boolean) */
+ void notifyTaskListFrozen(boolean frozen) {
+ final Message msg = mHandler.obtainMessage(NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG,
+ frozen ? 1 : 0, 0 /* unused */);
+ forAllLocalListeners(mNotifyTaskListFrozen, msg);
+ msg.sendToTarget();
+ }
}
diff --git a/services/core/java/com/android/server/wm/TaskPersister.java b/services/core/java/com/android/server/wm/TaskPersister.java
index 06bdcc04e9c8..f9a75d3d4943 100644
--- a/services/core/java/com/android/server/wm/TaskPersister.java
+++ b/services/core/java/com/android/server/wm/TaskPersister.java
@@ -122,7 +122,7 @@ public class TaskPersister implements PersisterQueue.Listener {
mPersisterQueue.removeItems(
item -> {
File file = new File(item.mFilePath);
- return file.getName().startsWith(Integer.toString(task.taskId));
+ return file.getName().startsWith(Integer.toString(task.mTaskId));
},
ImageWriteQueueItem.class);
}
@@ -262,7 +262,7 @@ public class TaskPersister implements PersisterQueue.Listener {
}
for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = tasks.get(taskNdx);
- if (task.taskId == taskId) {
+ if (task.mTaskId == taskId) {
return task;
}
}
@@ -329,14 +329,14 @@ public class TaskPersister implements PersisterQueue.Listener {
// read the same thing again.
// mWriteQueue.add(new TaskWriteQueueItem(task));
- final int taskId = task.taskId;
+ final int taskId = task.mTaskId;
if (mService.mRootActivityContainer.anyTaskForId(taskId,
MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) != null) {
// Should not happen.
Slog.wtf(TAG, "Existing task with taskId " + taskId + "found");
- } else if (userId != task.userId) {
+ } else if (userId != task.mUserId) {
// Should not happen.
- Slog.wtf(TAG, "Task with userId " + task.userId + " found in "
+ Slog.wtf(TAG, "Task with userId " + task.mUserId + " found in "
+ userTasksDir.getAbsolutePath());
} else {
// Looks fine.
@@ -560,14 +560,14 @@ public class TaskPersister implements PersisterQueue.Listener {
FileOutputStream file = null;
AtomicFile atomicFile = null;
try {
- File userTasksDir = getUserTasksDir(task.userId);
+ File userTasksDir = getUserTasksDir(task.mUserId);
if (!userTasksDir.isDirectory() && !userTasksDir.mkdirs()) {
- Slog.e(TAG, "Failure creating tasks directory for user " + task.userId
+ Slog.e(TAG, "Failure creating tasks directory for user " + task.mUserId
+ ": " + userTasksDir + " Dropping persistence for task " + task);
return;
}
atomicFile = new AtomicFile(new File(userTasksDir,
- String.valueOf(task.taskId) + TASK_FILENAME_SUFFIX));
+ String.valueOf(task.mTaskId) + TASK_FILENAME_SUFFIX));
file = atomicFile.startWrite();
file.write(stringWriter.toString().getBytes());
file.write('\n');
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 8b2ef7f07560..75333c728e0b 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -208,7 +208,7 @@ class TaskRecord extends ConfigurationContainer {
*/
private static TaskRecordFactory sTaskRecordFactory;
- final int taskId; // Unique identifier for this task.
+ final int mTaskId; // Unique identifier for this task.
String affinity; // The affinity name for this task, or null; may change identity.
String rootAffinity; // Initial base affinity, or null; does not change from initial root.
final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
@@ -234,7 +234,7 @@ class TaskRecord extends ConfigurationContainer {
boolean hasBeenVisible; // Set if any activities in the task have been visible to the user.
String stringName; // caching of toString() result.
- int userId; // user for which this task was created
+ int mUserId; // user for which this task was created
boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
// was changed.
@@ -262,7 +262,7 @@ class TaskRecord extends ConfigurationContainer {
// This represents the last resolved activity values for this task
// NOTE: This value needs to be persisted with each task
- TaskDescription lastTaskDescription = new TaskDescription();
+ TaskDescription mTaskDescription;
/** List of all activities in the task arranged in history order */
final ArrayList<ActivityRecord> mActivities;
@@ -282,7 +282,7 @@ class TaskRecord extends ConfigurationContainer {
/** Only used for persistable tasks, otherwise 0. The last time this task was moved. Used for
* determining the order when restoring. Sign indicates whether last task movement was to front
* (positive) or back (negative). Absolute value indicates time. */
- long mLastTimeMoved = System.currentTimeMillis();
+ long mLastTimeMoved;
/** If original intent did not allow relinquishing task identity, save that information */
private boolean mNeverRelinquishIdentity = true;
@@ -304,7 +304,7 @@ class TaskRecord extends ConfigurationContainer {
int mCallingUid;
String mCallingPackage;
- final ActivityTaskManagerService mService;
+ final ActivityTaskManagerService mAtmService;
private final Rect mTmpStableBounds = new Rect();
private final Rect mTmpNonDecorBounds = new Rect();
@@ -342,60 +342,25 @@ class TaskRecord extends ConfigurationContainer {
* Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
* ActivityInfo, Intent, TaskDescription)} instead.
*/
- TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
- IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
- mService = service;
- userId = UserHandle.getUserId(info.applicationInfo.uid);
- taskId = _taskId;
- lastActiveTime = SystemClock.elapsedRealtime();
- mAffiliatedTaskId = _taskId;
- voiceSession = _voiceSession;
- voiceInteractor = _voiceInteractor;
- isAvailable = true;
- mActivities = new ArrayList<>();
- mCallingUid = info.applicationInfo.uid;
- mCallingPackage = info.packageName;
- setIntent(_intent, info);
- setMinDimensions(info);
- touchActiveTime();
- mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
- }
-
- /**
- * Don't use constructor directly.
- * Use {@link #create(ActivityTaskManagerService, int, ActivityInfo,
- * Intent, IVoiceInteractionSession, IVoiceInteractor)} instead.
- */
- TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
- TaskDescription _taskDescription) {
- mService = service;
- userId = UserHandle.getUserId(info.applicationInfo.uid);
- taskId = _taskId;
- lastActiveTime = SystemClock.elapsedRealtime();
- mAffiliatedTaskId = _taskId;
- voiceSession = null;
- voiceInteractor = null;
- isAvailable = true;
- mActivities = new ArrayList<>();
- mCallingUid = info.applicationInfo.uid;
- mCallingPackage = info.packageName;
- setIntent(_intent, info);
- setMinDimensions(info);
-
- isPersistable = true;
- // Clamp to [1, max].
- maxRecents = Math.min(Math.max(info.maxRecents, 1),
- ActivityTaskManager.getMaxAppRecentsLimitStatic());
-
- lastTaskDescription = _taskDescription;
- touchActiveTime();
- mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
- }
-
- /**
- * Don't use constructor directly. This is only used by XML parser.
- */
- TaskRecord(ActivityTaskManagerService service, int _taskId, Intent _intent,
+ TaskRecord(ActivityTaskManagerService atmService, int _taskId, ActivityInfo info,
+ Intent _intent, IVoiceInteractionSession _voiceSession,
+ IVoiceInteractor _voiceInteractor, TaskDescription _taskDescription) {
+ this(atmService, _taskId, _intent, null /*_affinityIntent*/, null /*_affinity*/,
+ null /*_rootAffinity*/, null /*_realActivity*/, null /*_origActivity*/,
+ false /*_rootWasReset*/, false /*_autoRemoveRecents*/, false /*_askedCompatMode*/,
+ UserHandle.getUserId(info.applicationInfo.uid), 0 /*_effectiveUid*/,
+ null /*_lastDescription*/, new ArrayList<>(), System.currentTimeMillis(),
+ true /*neverRelinquishIdentity*/,
+ _taskDescription != null ? _taskDescription : new TaskDescription(),
+ _taskId, INVALID_TASK_ID, INVALID_TASK_ID, 0 /*taskAffiliationColor*/,
+ info.applicationInfo.uid, info.packageName, info.resizeMode,
+ info.supportsPictureInPicture(), false /*_realActivitySuspended*/,
+ false /*userSetupComplete*/, INVALID_MIN_SIZE, INVALID_MIN_SIZE, info,
+ _voiceSession, _voiceInteractor);
+ }
+
+ /** Don't use constructor directly. This is only used by XML parser. */
+ TaskRecord(ActivityTaskManagerService atmService, int _taskId, Intent _intent,
Intent _affinityIntent, String _affinity, String _rootAffinity,
ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
@@ -404,15 +369,15 @@ class TaskRecord extends ConfigurationContainer {
TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
- boolean userSetupComplete, int minWidth, int minHeight) {
- mService = service;
- taskId = _taskId;
- intent = _intent;
+ boolean userSetupComplete, int minWidth, int minHeight, ActivityInfo info,
+ IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
+ mAtmService = atmService;
+ mTaskId = _taskId;
affinityIntent = _affinityIntent;
affinity = _affinity;
rootAffinity = _rootAffinity;
- voiceSession = null;
- voiceInteractor = null;
+ voiceSession = _voiceSession;
+ voiceInteractor = _voiceInteractor;
realActivity = _realActivity;
realActivitySuspended = _realActivitySuspended;
origActivity = _origActivity;
@@ -420,15 +385,15 @@ class TaskRecord extends ConfigurationContainer {
isAvailable = true;
autoRemoveRecents = _autoRemoveRecents;
askedCompatMode = _askedCompatMode;
- userId = _userId;
+ mUserId = _userId;
mUserSetupComplete = userSetupComplete;
effectiveUid = _effectiveUid;
- lastActiveTime = SystemClock.elapsedRealtime();
+ touchActiveTime();
lastDescription = _lastDescription;
mActivities = activities;
mLastTimeMoved = lastTimeMoved;
mNeverRelinquishIdentity = neverRelinquishIdentity;
- lastTaskDescription = _lastTaskDescription;
+ mTaskDescription = _lastTaskDescription;
mAffiliatedTaskId = taskAffiliation;
mAffiliatedTaskColor = taskAffiliationColor;
mPrevAffiliateTaskId = prevTaskId;
@@ -437,9 +402,15 @@ class TaskRecord extends ConfigurationContainer {
mCallingPackage = callingPackage;
mResizeMode = resizeMode;
mSupportsPictureInPicture = supportsPictureInPicture;
- mMinWidth = minWidth;
- mMinHeight = minHeight;
- mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
+ if (info != null) {
+ setIntent(_intent, info);
+ setMinDimensions(info);
+ } else {
+ intent = _intent;
+ mMinWidth = minWidth;
+ mMinHeight = minHeight;
+ }
+ mAtmService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
}
Task getTask() {
@@ -458,9 +429,9 @@ class TaskRecord extends ConfigurationContainer {
if (stack == null) {
throw new IllegalArgumentException("TaskRecord: invalid stack=" + mStack);
}
- EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
- mTask = new Task(taskId, stack, userId, mService.mWindowManager, mResizeMode,
- mSupportsPictureInPicture, lastTaskDescription, this);
+ EventLog.writeEvent(WM_TASK_CREATED, mTaskId, stack.mStackId);
+ mTask = new Task(mTaskId, stack, mUserId, mAtmService.mWindowManager, mResizeMode,
+ mSupportsPictureInPicture, mTaskDescription, this);
final int position = onTop ? POSITION_TOP : POSITION_BOTTOM;
if (!mDisplayedBounds.isEmpty()) {
@@ -487,14 +458,14 @@ class TaskRecord extends ConfigurationContainer {
final boolean isVoiceSession = voiceSession != null;
if (isVoiceSession) {
try {
- voiceSession.taskFinished(intent, taskId);
+ voiceSession.taskFinished(intent, mTaskId);
} catch (RemoteException e) {
}
}
if (autoRemoveFromRecents() || isVoiceSession) {
// Task creator asked to remove this when done, or this task was a voice
// interaction, so it should not remain on the recent tasks list.
- mService.mStackSupervisor.mRecentTasks.remove(this);
+ mAtmService.mStackSupervisor.mRecentTasks.remove(this);
}
removeWindowContainer();
@@ -502,9 +473,9 @@ class TaskRecord extends ConfigurationContainer {
@VisibleForTesting
void removeWindowContainer() {
- mService.getLockTaskController().clearLockedTask(this);
+ mAtmService.getLockTaskController().clearLockedTask(this);
if (mTask == null) {
- if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: could not find taskId=" + taskId);
+ if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: could not find taskId=" + mTaskId);
return;
}
mTask.removeIfPossible();
@@ -514,11 +485,11 @@ class TaskRecord extends ConfigurationContainer {
// default configuration the next time it launches.
setBounds(null);
}
- mService.getTaskChangeNotificationController().notifyTaskRemoved(taskId);
+ mAtmService.getTaskChangeNotificationController().notifyTaskRemoved(mTaskId);
}
- public void onSnapshotChanged(TaskSnapshot snapshot) {
- mService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(taskId, snapshot);
+ void onSnapshotChanged(TaskSnapshot snapshot) {
+ mAtmService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(mTaskId, snapshot);
}
void setResizeMode(int resizeMode) {
@@ -527,13 +498,13 @@ class TaskRecord extends ConfigurationContainer {
}
mResizeMode = resizeMode;
mTask.setResizeable(resizeMode);
- mService.mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
- mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
+ mAtmService.mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+ mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
}
void setTaskDockedResizing(boolean resizing) {
if (mTask == null) {
- Slog.w(TAG_WM, "setTaskDockedResizing: taskId " + taskId + " not found.");
+ Slog.w(TAG_WM, "setTaskDockedResizing: taskId " + mTaskId + " not found.");
return;
}
mTask.setTaskDockedResizing(resizing);
@@ -541,11 +512,11 @@ class TaskRecord extends ConfigurationContainer {
// TODO: Consolidate this with the resize() method below.
public void requestResize(Rect bounds, int resizeMode) {
- mService.resizeTask(taskId, bounds, resizeMode);
+ mAtmService.resizeTask(mTaskId, bounds, resizeMode);
}
boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
- mService.deferWindowLayout();
+ mAtmService.deferWindowLayout();
try {
if (!isResizeable()) {
@@ -568,7 +539,7 @@ class TaskRecord extends ConfigurationContainer {
setBounds(bounds);
if (!inFreeformWindowingMode()) {
// re-restore the task so it can have the proper stack association.
- mService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
+ mAtmService.mStackSupervisor.restoreRecentTaskLocked(this, null, !ON_TOP);
}
return true;
}
@@ -582,7 +553,7 @@ class TaskRecord extends ConfigurationContainer {
// This method assumes that the task is already placed in the right stack.
// we do not mess with that decision and we only do the resize!
- Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + taskId);
+ Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + mTaskId);
boolean updatedConfig = false;
mTmpConfig.setTo(getResolvedOverrideConfiguration());
@@ -606,9 +577,9 @@ class TaskRecord extends ConfigurationContainer {
// this won't cause tons of irrelevant windows being preserved because only
// activities in this task may experience a bounds change. Configs for other
// activities stay the same.
- mService.mRootActivityContainer.ensureActivitiesVisible(r, 0, preserveWindow);
+ mAtmService.mRootActivityContainer.ensureActivitiesVisible(r, 0, preserveWindow);
if (!kept) {
- mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
+ mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
}
}
}
@@ -619,7 +590,7 @@ class TaskRecord extends ConfigurationContainer {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
return kept;
} finally {
- mService.continueWindowLayout();
+ mAtmService.continueWindowLayout();
}
}
@@ -687,9 +658,9 @@ class TaskRecord extends ConfigurationContainer {
boolean reparent(ActivityStack preferredStack, int position,
@ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume,
boolean schedulePictureInPictureModeChange, String reason) {
- final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
- final RootActivityContainer root = mService.mRootActivityContainer;
- final WindowManagerService windowManager = mService.mWindowManager;
+ final ActivityStackSupervisor supervisor = mAtmService.mStackSupervisor;
+ final RootActivityContainer root = mAtmService.mRootActivityContainer;
+ final WindowManagerService windowManager = mAtmService.mWindowManager;
final ActivityStack sourceStack = getStack();
final ActivityStack toStack = supervisor.getReparentTargetStack(this, preferredStack,
position == MAX_VALUE);
@@ -725,7 +696,7 @@ class TaskRecord extends ConfigurationContainer {
windowManager.setWillReplaceWindow(topActivity.appToken, animate);
}
- mService.deferWindowLayout();
+ mAtmService.deferWindowLayout();
boolean kept = true;
try {
final ActivityRecord r = topRunningActivityLocked();
@@ -764,7 +735,7 @@ class TaskRecord extends ConfigurationContainer {
// Notify the voice session if required
if (voiceSession != null) {
try {
- voiceSession.taskStarted(intent, taskId);
+ voiceSession.taskStarted(intent, mTaskId);
} catch (RemoteException e) {
}
}
@@ -776,7 +747,7 @@ class TaskRecord extends ConfigurationContainer {
wasPaused, reason);
}
if (!animate) {
- mService.mStackSupervisor.mNoAnimActivities.add(topActivity);
+ mAtmService.mStackSupervisor.mNoAnimActivities.add(topActivity);
}
// We might trigger a configuration change. Save the current task bounds for freezing.
@@ -795,7 +766,7 @@ class TaskRecord extends ConfigurationContainer {
} else if (toStackWindowingMode == WINDOWING_MODE_FREEFORM) {
Rect bounds = getLaunchBounds();
if (bounds == null) {
- mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
+ mAtmService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
bounds = configBounds;
}
kept = resize(bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, deferResume);
@@ -803,13 +774,13 @@ class TaskRecord extends ConfigurationContainer {
if (toStackSplitScreenPrimary && moveStackMode == REPARENT_KEEP_STACK_AT_FRONT) {
// Move recents to front so it is not behind home stack when going into docked
// mode
- mService.mStackSupervisor.moveRecentsStackToFront(reason);
+ mAtmService.mStackSupervisor.moveRecentsStackToFront(reason);
}
kept = resize(toStack.getRequestedOverrideBounds(), RESIZE_MODE_SYSTEM,
!mightReplaceWindow, deferResume);
}
} finally {
- mService.continueWindowLayout();
+ mAtmService.continueWindowLayout();
}
if (mightReplaceWindow) {
@@ -846,7 +817,7 @@ class TaskRecord extends ConfigurationContainer {
void cancelWindowTransition() {
if (mTask == null) {
- Slog.w(TAG_WM, "cancelWindowTransition: taskId " + taskId + " not found.");
+ Slog.w(TAG_WM, "cancelWindowTransition: taskId " + mTaskId + " not found.");
return;
}
mTask.cancelTaskWindowTransition();
@@ -859,7 +830,7 @@ class TaskRecord extends ConfigurationContainer {
// TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
// synchronized between AM and WM.
- return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution,
+ return mAtmService.mWindowManager.getTaskSnapshot(mTaskId, mUserId, reducedResolution,
restoreFromDisk);
}
@@ -938,9 +909,9 @@ class TaskRecord extends ConfigurationContainer {
// task as having a true root activity.
rootWasReset = true;
}
- userId = UserHandle.getUserId(info.applicationInfo.uid);
- mUserSetupComplete = Settings.Secure.getIntForUser(mService.mContext.getContentResolver(),
- USER_SETUP_COMPLETE, 0, userId) != 0;
+ mUserId = UserHandle.getUserId(info.applicationInfo.uid);
+ mUserSetupComplete = Settings.Secure.getIntForUser(
+ mAtmService.mContext.getContentResolver(), USER_SETUP_COMPLETE, 0, mUserId) != 0;
if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
// If the activity itself has requested auto-remove, then just always do it.
autoRemoveRecents = true;
@@ -993,12 +964,12 @@ class TaskRecord extends ConfigurationContainer {
void setPrevAffiliate(TaskRecord prevAffiliate) {
mPrevAffiliate = prevAffiliate;
- mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
+ mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.mTaskId;
}
void setNextAffiliate(TaskRecord nextAffiliate) {
mNextAffiliate = nextAffiliate;
- mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.taskId;
+ mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.mTaskId;
}
<T extends ActivityStack> T getStack() {
@@ -1061,7 +1032,7 @@ class TaskRecord extends ConfigurationContainer {
@Override
protected void onParentChanged() {
super.onParentChanged();
- mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
+ mAtmService.mRootActivityContainer.updateUIDsPresentOnDisplay();
}
// Close up recents linked list.
@@ -1080,13 +1051,13 @@ class TaskRecord extends ConfigurationContainer {
closeRecentsChain();
if (inRecents) {
inRecents = false;
- mService.notifyTaskPersisterLocked(this, false);
+ mAtmService.notifyTaskPersisterLocked(this, false);
}
clearRootProcess();
- mService.mWindowManager.mTaskSnapshotController.notifyTaskRemovedFromRecents(
- taskId, userId);
+ mAtmService.mWindowManager.mTaskSnapshotController.notifyTaskRemovedFromRecents(
+ mTaskId, mUserId);
}
void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
@@ -1235,7 +1206,7 @@ class TaskRecord extends ConfigurationContainer {
boolean okToShowLocked() {
// NOTE: If {@link TaskRecord#topRunningActivity} return is not null then it is
// okay to show the activity when locked.
- return mService.mStackSupervisor.isCurrentProfileLocked(userId)
+ return mAtmService.mStackSupervisor.isCurrentProfileLocked(mUserId)
|| topRunningActivityLocked() != null;
}
@@ -1324,7 +1295,7 @@ class TaskRecord extends ConfigurationContainer {
updateEffectiveIntent();
if (r.isPersistable()) {
- mService.notifyTaskPersisterLocked(this, false);
+ mAtmService.notifyTaskPersisterLocked(this, false);
}
if (r.getParent() != null) {
@@ -1335,7 +1306,7 @@ class TaskRecord extends ConfigurationContainer {
// Make sure the list of display UID whitelists is updated
// now that this record is in a new task.
- mService.mRootActivityContainer.updateUIDsPresentOnDisplay();
+ mAtmService.mRootActivityContainer.updateUIDsPresentOnDisplay();
}
/**
@@ -1360,14 +1331,14 @@ class TaskRecord extends ConfigurationContainer {
numFullscreen--;
}
if (r.isPersistable()) {
- mService.notifyTaskPersisterLocked(this, false);
+ mAtmService.notifyTaskPersisterLocked(this, false);
}
if (inPinnedWindowingMode()) {
// We normally notify listeners of task stack changes on pause, however pinned stack
// activities are normally in the paused state so no notification will be sent there
// before the activity is removed. We send it here so instead.
- mService.getTaskChangeNotificationController().notifyTaskStackChanged();
+ mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
}
if (mActivities.isEmpty()) {
@@ -1530,10 +1501,10 @@ class TaskRecord extends ConfigurationContainer {
}
final String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
- final LockTaskController lockTaskController = mService.getLockTaskController();
+ final LockTaskController lockTaskController = mAtmService.getLockTaskController();
switch (r.lockTaskLaunchMode) {
case LOCK_TASK_LAUNCH_MODE_DEFAULT:
- mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
+ mLockTaskAuth = lockTaskController.isPackageWhitelisted(mUserId, pkg)
? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
break;
@@ -1546,7 +1517,7 @@ class TaskRecord extends ConfigurationContainer {
break;
case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
- mLockTaskAuth = lockTaskController.isPackageWhitelisted(userId, pkg)
+ mLockTaskAuth = lockTaskController.isPackageWhitelisted(mUserId, pkg)
? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
break;
}
@@ -1555,7 +1526,7 @@ class TaskRecord extends ConfigurationContainer {
}
private boolean isResizeable(boolean checkSupportsPip) {
- return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
+ return (mAtmService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
|| (checkSupportsPip && mSupportsPictureInPicture));
}
@@ -1568,8 +1539,8 @@ class TaskRecord extends ConfigurationContainer {
// A task can not be docked even if it is considered resizeable because it only supports
// picture-in-picture mode but has a non-resizeable resizeMode
return super.supportsSplitScreenWindowingMode()
- && mService.mSupportsSplitScreenMultiWindow
- && (mService.mForceResizableActivities
+ && mAtmService.mSupportsSplitScreenMultiWindow
+ && (mAtmService.mForceResizableActivities
|| (isResizeable(false /* checkSupportsPip */)
&& !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
}
@@ -1582,7 +1553,7 @@ class TaskRecord extends ConfigurationContainer {
* secondary display.
*/
boolean canBeLaunchedOnDisplay(int displayId) {
- return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
+ return mAtmService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
-1 /* don't check PID */, -1 /* don't check UID */, null /* activityInfo */);
}
@@ -1700,15 +1671,15 @@ class TaskRecord extends ConfigurationContainer {
}
topActivity = false;
}
- lastTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
+ mTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
colorPrimary, colorBackground, statusBarColor, navigationBarColor,
statusBarContrastWhenTransparent, navigationBarContrastWhenTransparent);
if (mTask != null) {
- mTask.setTaskDescription(lastTaskDescription);
+ mTask.setTaskDescription(mTaskDescription);
}
// Update the task affiliation color if we are the parent of the group
- if (taskId == mAffiliatedTaskId) {
- mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
+ if (mTaskId == mAffiliatedTaskId) {
+ mAffiliatedTaskColor = mTaskDescription.getPrimaryColor();
}
}
}
@@ -1767,9 +1738,9 @@ class TaskRecord extends ConfigurationContainer {
// to do this for the pinned stack as the bounds are controlled by the system.
if (!inPinnedWindowingMode() && mStack != null) {
final int defaultMinSizeDp =
- mService.mRootActivityContainer.mDefaultMinSizeOfResizeableTaskDp;
+ mAtmService.mRootActivityContainer.mDefaultMinSizeOfResizeableTaskDp;
final ActivityDisplay display =
- mService.mRootActivityContainer.getActivityDisplay(mStack.mDisplayId);
+ mAtmService.mRootActivityContainer.getActivityDisplay(mStack.mDisplayId);
final float density =
(float) display.getConfiguration().densityDpi / DisplayMetrics.DENSITY_DEFAULT;
final int defaultMinSize = (int) (defaultMinSizeDp * density);
@@ -1849,7 +1820,7 @@ class TaskRecord extends ConfigurationContainer {
final boolean wasInMultiWindowMode = inMultiWindowMode();
super.onConfigurationChanged(newParentConfig);
if (wasInMultiWindowMode != inMultiWindowMode()) {
- mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
+ mAtmService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
}
// If the configuration supports persistent bounds (eg. Freeform), keep track of the
@@ -1890,7 +1861,7 @@ class TaskRecord extends ConfigurationContainer {
}
// Saves the new state so that we can launch the activity at the same location.
- mService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
+ mAtmService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
}
/**
@@ -2293,7 +2264,7 @@ class TaskRecord extends ConfigurationContainer {
if (mLastNonFullscreenBounds != null) {
setBounds(mLastNonFullscreenBounds);
} else {
- mService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
+ mAtmService.mStackSupervisor.getLaunchParamsController().layoutTask(this, null);
}
} else {
setBounds(inStack.getRequestedOverrideBounds());
@@ -2354,9 +2325,9 @@ class TaskRecord extends ConfigurationContainer {
*/
void fillTaskInfo(TaskInfo info) {
getNumRunningActivities(mReuseActivitiesReport);
- info.userId = userId;
+ info.userId = mUserId;
info.stackId = getStackId();
- info.taskId = taskId;
+ info.taskId = mTaskId;
info.displayId = mStack == null ? Display.INVALID_DISPLAY : mStack.mDisplayId;
info.isRunning = getTopActivity() != null;
info.baseIntent = new Intent(getBaseIntent());
@@ -2370,7 +2341,7 @@ class TaskRecord extends ConfigurationContainer {
info.realActivity = realActivity;
info.numActivities = mReuseActivitiesReport.numActivities;
info.lastActiveTime = lastActiveTime;
- info.taskDescription = new ActivityManager.TaskDescription(lastTaskDescription);
+ info.taskDescription = new ActivityManager.TaskDescription(mTaskDescription);
info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
info.resizeMode = mResizeMode;
info.configuration.setTo(getConfiguration());
@@ -2386,7 +2357,7 @@ class TaskRecord extends ConfigurationContainer {
}
void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("userId="); pw.print(userId);
+ pw.print(prefix); pw.print("userId="); pw.print(mUserId);
pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
pw.print(" mUserSetupComplete="); pw.print(mUserSetupComplete);
@@ -2440,7 +2411,7 @@ class TaskRecord extends ConfigurationContainer {
pw.print(" mReuseTask="); pw.print(mReuseTask);
pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
}
- if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
+ if (mAffiliatedTaskId != mTaskId || mPrevAffiliateTaskId != INVALID_TASK_ID
|| mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID
|| mNextAffiliate != null) {
pw.print(prefix); pw.print("affiliation="); pw.print(mAffiliatedTaskId);
@@ -2487,7 +2458,7 @@ class TaskRecord extends ConfigurationContainer {
if (stringName != null) {
sb.append(stringName);
sb.append(" U=");
- sb.append(userId);
+ sb.append(mUserId);
sb.append(" StackId=");
sb.append(getStackId());
sb.append(" sz=");
@@ -2498,7 +2469,7 @@ class TaskRecord extends ConfigurationContainer {
sb.append("TaskRecord{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
sb.append(" #");
- sb.append(taskId);
+ sb.append(mTaskId);
if (affinity != null) {
sb.append(" A=");
sb.append(affinity);
@@ -2523,7 +2494,7 @@ class TaskRecord extends ConfigurationContainer {
final long token = proto.start(fieldId);
super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
- proto.write(ID, taskId);
+ proto.write(ID, mTaskId);
for (int i = mActivities.size() - 1; i >= 0; i--) {
ActivityRecord activity = mActivities.get(i);
activity.writeToProto(proto, ACTIVITIES);
@@ -2573,7 +2544,7 @@ class TaskRecord extends ConfigurationContainer {
void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
if (DEBUG_RECENTS) Slog.i(TAG_RECENTS, "Saving task=" + this);
- out.attribute(null, ATTR_TASKID, String.valueOf(taskId));
+ out.attribute(null, ATTR_TASKID, String.valueOf(mTaskId));
if (realActivity != null) {
out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
}
@@ -2596,7 +2567,7 @@ class TaskRecord extends ConfigurationContainer {
out.attribute(null, ATTR_ROOTHASRESET, String.valueOf(rootWasReset));
out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
- out.attribute(null, ATTR_USERID, String.valueOf(userId));
+ out.attribute(null, ATTR_USERID, String.valueOf(mUserId));
out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
@@ -2604,8 +2575,8 @@ class TaskRecord extends ConfigurationContainer {
if (lastDescription != null) {
out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
}
- if (lastTaskDescription != null) {
- lastTaskDescription.saveToXml(out);
+ if (mTaskDescription != null) {
+ mTaskDescription.saveToXml(out);
}
out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
@@ -2692,13 +2663,14 @@ class TaskRecord extends ConfigurationContainer {
TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Intent intent, IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor) {
- return new TaskRecord(
- service, taskId, info, intent, voiceSession, voiceInteractor);
+ return new TaskRecord(service, taskId, info, intent, voiceSession, voiceInteractor,
+ null /*taskDescription*/);
}
TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Intent intent, TaskDescription taskDescription) {
- return new TaskRecord(service, taskId, info, intent, taskDescription);
+ return new TaskRecord(service, taskId, info, intent, null /*voiceSession*/,
+ null /*voiceInteractor*/, taskDescription);
}
/**
@@ -2720,7 +2692,8 @@ class TaskRecord extends ConfigurationContainer {
lastTimeMoved, neverRelinquishIdentity, lastTaskDescription, taskAffiliation,
prevTaskId, nextTaskId, taskAffiliationColor, callingUid, callingPackage,
resizeMode, supportsPictureInPicture, realActivitySuspended, userSetupComplete,
- minWidth, minHeight);
+ minWidth, minHeight, null /*ActivityInfo*/, null /*_voiceSession*/,
+ null /*_voiceInteractor*/);
}
TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 19fcb1b96e7b..a4ab66aef550 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -33,6 +33,7 @@ import static com.android.server.wm.WindowContainerProto.VISIBLE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
import android.annotation.CallSuper;
import android.annotation.IntDef;
@@ -54,9 +55,11 @@ import android.view.SurfaceSession;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ToBooleanFunction;
+import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.SurfaceAnimator.Animatable;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.function.Consumer;
@@ -124,6 +127,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
private final Transaction mPendingTransaction;
/**
+ * Windows that clients are waiting to have drawn.
+ */
+ final ArrayList<WindowState> mWaitingForDrawn = new ArrayList<>();
+
+ /**
* Applied as part of the animation pass in "prepareSurfaces".
*/
protected final SurfaceAnimator mSurfaceAnimator;
@@ -1434,6 +1442,19 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
}
+ void waitForAllWindowsDrawn() {
+ final WindowManagerPolicy policy = mWmService.mPolicy;
+ forAllWindows(w -> {
+ final boolean keyguard = policy.isKeyguardHostWindow(w.mAttrs);
+ if (w.isVisibleLw() && (w.mAppToken != null || keyguard)) {
+ w.mWinAnimator.mDrawState = DRAW_PENDING;
+ // Force add to mResizingWindows.
+ w.resetLastContentInsets();
+ mWaitingForDrawn.add(w);
+ }
+ }, true /* traverseTopToBottom */);
+ }
+
Dimmer getDimmer() {
if (mParent == null) {
return null;
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index abbd1abff614..f4b76729b7ea 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -313,10 +313,15 @@ public abstract class WindowManagerInternal {
public abstract void showGlobalActions();
/**
- * Invalidate all visible windows. Then report back on the callback once all windows have
- * redrawn.
+ * Invalidate all visible windows on a given display, and report back on the callback when all
+ * windows have redrawn.
+ *
+ * @param callback reporting callback to be called when all windows have redrawn.
+ * @param timeout calls the callback anyway after the timeout.
+ * @param displayId waits for the windows on the given display, INVALID_DISPLAY to wait for all
+ * windows on all displays.
*/
- public abstract void waitForAllWindowsDrawn(Runnable callback, long timeout);
+ public abstract void waitForAllWindowsDrawn(Runnable callback, long timeout, int displayId);
/**
* Overrides the display size.
@@ -502,6 +507,13 @@ public abstract class WindowManagerInternal {
public abstract boolean shouldShowIme(int displayId);
/**
+ * Show IME on imeTargetWindow once IME has finished layout.
+ *
+ * @param imeTargetWindowToken token of the (IME target) window on which IME should be shown.
+ */
+ public abstract void showImePostLayout(IBinder imeTargetWindowToken);
+
+ /**
* Tell window manager about a package that should not be running with high refresh rate
* setting until removeNonHighRefreshRatePackage is called for the same package.
*
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1f45cfb2f53d..0f4d0a8662f4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -290,6 +290,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@@ -568,13 +569,10 @@ public class WindowManagerService extends IWindowManager.Stub
final ArrayList<WindowState> mForceRemoves = new ArrayList<>();
/**
- * Windows that clients are waiting to have drawn.
+ * The callbacks to make when the windows all have been drawn for a given
+ * {@link WindowContainer}.
*/
- ArrayList<WindowState> mWaitingForDrawn = new ArrayList<>();
- /**
- * And the callback to make when they've all been drawn.
- */
- Runnable mWaitingForDrawnCallback;
+ final HashMap<WindowContainer, Runnable> mWaitingForDrawnCallbacks = new HashMap<>();
/** List of window currently causing non-system overlay windows to be hidden. */
private ArrayList<WindowState> mHidingNonSystemOverlayWindows = new ArrayList<>();
@@ -4736,12 +4734,12 @@ public class WindowManagerService extends IWindowManager.Stub
case WAITING_FOR_DRAWN_TIMEOUT: {
Runnable callback = null;
+ final WindowContainer container = (WindowContainer) msg.obj;
synchronized (mGlobalLock) {
ProtoLog.w(WM_ERROR, "Timeout waiting for drawn: undrawn=%s",
- mWaitingForDrawn);
- mWaitingForDrawn.clear();
- callback = mWaitingForDrawnCallback;
- mWaitingForDrawnCallback = null;
+ container.mWaitingForDrawn);
+ container.mWaitingForDrawn.clear();
+ callback = mWaitingForDrawnCallbacks.remove(container);
}
if (callback != null) {
callback.run();
@@ -4773,9 +4771,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
case ALL_WINDOWS_DRAWN: {
Runnable callback;
+ final WindowContainer container = (WindowContainer) msg.obj;
synchronized (mGlobalLock) {
- callback = mWaitingForDrawnCallback;
- mWaitingForDrawnCallback = null;
+ callback = mWaitingForDrawnCallbacks.remove(container);
}
if (callback != null) {
callback.run();
@@ -5265,30 +5263,32 @@ public class WindowManagerService extends IWindowManager.Stub
}
void checkDrawnWindowsLocked() {
- if (mWaitingForDrawn.isEmpty() || mWaitingForDrawnCallback == null) {
+ if (mWaitingForDrawnCallbacks.isEmpty()) {
return;
}
- for (int j = mWaitingForDrawn.size() - 1; j >= 0; j--) {
- WindowState win = mWaitingForDrawn.get(j);
- ProtoLog.i(WM_DEBUG_SCREEN_ON,
+ mWaitingForDrawnCallbacks.forEach((container, callback) -> {
+ for (int j = container.mWaitingForDrawn.size() - 1; j >= 0; j--) {
+ final WindowState win = (WindowState) container.mWaitingForDrawn.get(j);
+ ProtoLog.i(WM_DEBUG_SCREEN_ON,
"Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d",
win, win.mRemoved, win.isVisibleLw(), win.mHasSurface,
win.mWinAnimator.mDrawState);
- if (win.mRemoved || !win.mHasSurface || !win.isVisibleByPolicy()) {
- // Window has been removed or hidden; no draw will now happen, so stop waiting.
- ProtoLog.w(WM_DEBUG_SCREEN_ON, "Aborted waiting for drawn: %s", win);
- mWaitingForDrawn.remove(win);
- } else if (win.hasDrawnLw()) {
- // Window is now drawn (and shown).
- ProtoLog.d(WM_DEBUG_SCREEN_ON, "Window drawn win=%s", win);
- mWaitingForDrawn.remove(win);
+ if (win.mRemoved || !win.mHasSurface || !win.isVisibleByPolicy()) {
+ // Window has been removed or hidden; no draw will now happen, so stop waiting.
+ ProtoLog.w(WM_DEBUG_SCREEN_ON, "Aborted waiting for drawn: %s", win);
+ container.mWaitingForDrawn.remove(win);
+ } else if (win.hasDrawnLw()) {
+ // Window is now drawn (and shown).
+ ProtoLog.d(WM_DEBUG_SCREEN_ON, "Window drawn win=%s", win);
+ container.mWaitingForDrawn.remove(win);
+ }
}
- }
- if (mWaitingForDrawn.isEmpty()) {
- ProtoLog.d(WM_DEBUG_SCREEN_ON, "All windows drawn!");
- mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
- mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN);
- }
+ if (container.mWaitingForDrawn.isEmpty()) {
+ ProtoLog.d(WM_DEBUG_SCREEN_ON, "All windows drawn!");
+ mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, container);
+ mH.sendMessage(mH.obtainMessage(H.ALL_WINDOWS_DRAWN, container));
+ }
+ });
}
void setHoldScreenLocked(final Session newHoldScreen) {
@@ -5934,13 +5934,18 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
- if (mWaitingForDrawn.size() > 0) {
+ if (!mWaitingForDrawnCallbacks.isEmpty()) {
pw.println();
pw.println(" Clients waiting for these windows to be drawn:");
- for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
- WindowState win = mWaitingForDrawn.get(i);
- pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(win);
- }
+ mWaitingForDrawnCallbacks.forEach((wc, callback) -> {
+ pw.print(" WindowContainer ");
+ pw.println(wc.getName());
+ for (int i = wc.mWaitingForDrawn.size() - 1; i >= 0; i--) {
+ final WindowState win = (WindowState) wc.mWaitingForDrawn.get(i);
+ pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(win);
+ }
+ });
+
}
pw.println();
pw.print(" mGlobalConfiguration="); pw.println(mRoot.getConfiguration());
@@ -7096,17 +7101,25 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public void waitForAllWindowsDrawn(Runnable callback, long timeout) {
+ public void waitForAllWindowsDrawn(Runnable callback, long timeout, int displayId) {
+ final WindowContainer container = displayId == INVALID_DISPLAY
+ ? mRoot : mRoot.getDisplayContent(displayId);
+ if (container == null) {
+ // The waiting container doesn't exist, no need to wait to run the callback. Run and
+ // return;
+ callback.run();
+ return;
+ }
boolean allWindowsDrawn = false;
synchronized (mGlobalLock) {
- mWaitingForDrawnCallback = callback;
- getDefaultDisplayContentLocked().waitForAllWindowsDrawn();
+ container.waitForAllWindowsDrawn();
mWindowPlacerLocked.requestTraversal();
- mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
- if (mWaitingForDrawn.isEmpty()) {
+ mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, container);
+ if (container.mWaitingForDrawn.isEmpty()) {
allWindowsDrawn = true;
} else {
- mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout);
+ mWaitingForDrawnCallbacks.put(container, callback);
+ mH.sendNewMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, container, timeout);
checkDrawnWindowsLocked();
}
}
@@ -7303,6 +7316,29 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void showImePostLayout(IBinder imeTargetWindowToken) {
+ synchronized (mGlobalLock) {
+ final WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
+ if (imeTarget == null) {
+ return;
+ }
+ final DisplayContent displayContent = imeTarget.getDisplayContent();
+ if (displayContent == null) {
+ Slog.w(TAG_WM, "Attempted to show IME on an IME target that does not exist: "
+ + imeTarget.getName());
+ return;
+ }
+ if (displayContent.isUntrustedVirtualDisplay()) {
+ throw new SecurityException("Attempted to show IME on an untrusted "
+ + "virtual display: " + displayContent.getDisplayId());
+ }
+
+ displayContent.getInsetsStateController().getImeSourceProvider()
+ .scheduleShowImePostLayout(imeTarget);
+ }
+ }
+
+ @Override
public boolean isUidAllowedOnDisplay(int displayId, int uid) {
if (displayId == Display.DEFAULT_DISPLAY) {
return true;
@@ -7636,7 +7672,7 @@ public class WindowManagerService extends IWindowManager.Stub
// to do so because it seems possible to resume activities as part of a larger
// transaction and it's too early to resume based on current order when performing
// updateTopResumedActivityIfNeeded().
- displayContent.mAcitvityDisplay.ensureActivitiesVisible(null /* starting */,
+ displayContent.mActivityDisplay.ensureActivitiesVisible(null /* starting */,
0 /* configChanges */, !PRESERVE_WINDOWS, true /* notifyClients */);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index d7116d8bbd87..1c0d1561de90 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -702,7 +702,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
}
ActivityRecord hist = mActivities.get(0);
intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName);
- intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTaskRecord().taskId);
+ intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTaskRecord().mTaskId);
}
boolean shouldKillProcessForRemovedTask(TaskRecord tr) {
@@ -713,7 +713,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
return false;
}
final TaskRecord otherTask = activity.getTaskRecord();
- if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
+ if (tr.mTaskId != otherTask.mTaskId && otherTask.inRecents) {
// Don't kill process(es) that has an activity in a different task that is
// also in recents.
return false;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 1270658dbedd..56e08b2843b5 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -836,7 +836,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
*/
boolean inSizeCompatMode() {
return (mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0
- || (mAppToken != null && mAppToken.inSizeCompatMode()
+ || (mAppToken != null && mAppToken.hasSizeCompatBounds()
// Exclude starting window because it is not displayed by the application.
&& mAttrs.type != TYPE_APPLICATION_STARTING);
}
@@ -2320,7 +2320,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
// The offset of compatibility bounds is applied to surface of {@link #AppWindowToken}
// and frame, so it is unnecessary to translate twice in surface based coordinates.
- final int surfaceOffsetX = mAppToken.inSizeCompatMode()
+ final int surfaceOffsetX = mAppToken.hasSizeCompatBounds()
? mAppToken.getBounds().left : 0;
mTmpRect.offset(surfaceOffsetX - mWindowFrames.mFrame.left, -mWindowFrames.mFrame.top);
region.set(mTmpRect);
@@ -3497,7 +3497,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
void setWaitingForDrawnIfResizingChanged() {
if (isDragResizeChanged()) {
- mWmService.mWaitingForDrawn.add(this);
+ mWmService.mRoot.mWaitingForDrawn.add(this);
}
super.setWaitingForDrawnIfResizingChanged();
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index b118cdfeb84d..47291cb286ba 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11320,6 +11320,28 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
+ @Override
+ public boolean isActiveSupervisionApp(int uid) {
+ synchronized (getLockObject()) {
+ final ActiveAdmin admin = getActiveAdminWithPolicyForUidLocked(
+ null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, uid);
+ if (admin == null) {
+ return false;
+ }
+
+ final String supervisionString = mContext.getResources().getString(
+ com.android.internal.R.string
+ .config_defaultSupervisionProfileOwnerComponent);
+ if (supervisionString == null) {
+ return false;
+ }
+
+ final ComponentName supervisorComponent = ComponentName.unflattenFromString(
+ supervisionString);
+ return admin.info.getComponent().equals(supervisorComponent);
+ }
+ }
+
private void notifyCrossProfileProvidersChanged(int userId, List<String> packages) {
final List<OnCrossProfileWidgetProvidersChangeListener> listeners;
synchronized (getLockObject()) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index 108b017fc76c..2aa625a657ef 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -108,7 +108,7 @@ public class DeviceIdleControllerTest {
@Mock
private AlarmManager mAlarmManager;
@Mock
- private ConnectivityService mConnectivityService;
+ private ConnectivityManager mConnectivityManager;
@Mock
private ContentResolver mContentResolver;
@Mock
@@ -127,7 +127,7 @@ public class DeviceIdleControllerTest {
private SensorManager mSensorManager;
class InjectorForTest extends DeviceIdleController.Injector {
- ConnectivityService connectivityService;
+ ConnectivityManager connectivityManager;
LocationManager locationManager;
ConstraintController constraintController;
// Freeze time for testing.
@@ -155,8 +155,8 @@ public class DeviceIdleControllerTest {
}
@Override
- ConnectivityService getConnectivityService() {
- return connectivityService;
+ ConnectivityManager getConnectivityManager() {
+ return connectivityManager;
}
@Override
@@ -347,19 +347,19 @@ public class DeviceIdleControllerTest {
public void testUpdateConnectivityState() {
// No connectivity service
final boolean isConnected = mDeviceIdleController.isNetworkConnected();
- mInjector.connectivityService = null;
+ mInjector.connectivityManager = null;
mDeviceIdleController.updateConnectivityState(null);
assertEquals(isConnected, mDeviceIdleController.isNetworkConnected());
// No active network info
- mInjector.connectivityService = mConnectivityService;
- doReturn(null).when(mConnectivityService).getActiveNetworkInfo();
+ mInjector.connectivityManager = mConnectivityManager;
+ doReturn(null).when(mConnectivityManager).getActiveNetworkInfo();
mDeviceIdleController.updateConnectivityState(null);
assertFalse(mDeviceIdleController.isNetworkConnected());
// Active network info says connected.
final NetworkInfo ani = mock(NetworkInfo.class);
- doReturn(ani).when(mConnectivityService).getActiveNetworkInfo();
+ doReturn(ani).when(mConnectivityManager).getActiveNetworkInfo();
doReturn(true).when(ani).isConnected();
mDeviceIdleController.updateConnectivityState(null);
assertTrue(mDeviceIdleController.isNetworkConnected());
@@ -1827,10 +1827,10 @@ public class DeviceIdleControllerTest {
}
private void setNetworkConnected(boolean connected) {
- mInjector.connectivityService = mConnectivityService;
+ mInjector.connectivityManager = mConnectivityManager;
final NetworkInfo ani = mock(NetworkInfo.class);
doReturn(connected).when(ani).isConnected();
- doReturn(ani).when(mConnectivityService).getActiveNetworkInfo();
+ doReturn(ani).when(mConnectivityManager).getActiveNetworkInfo();
mDeviceIdleController.updateConnectivityState(null);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
index 4538cacbf9c4..5c2b8ce4b432 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
@@ -20,6 +20,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.assertArrayEquals;
+
import android.content.Context;
import android.content.res.Resources;
import android.os.Binder;
@@ -184,8 +186,56 @@ public class DisplayWhiteBalanceTintControllerTest {
.isFalse();
}
+ /**
+ * Matrix should match the precalculated one for given cct and display primaries.
+ */
+ @Test
+ public void displayWhiteBalance_validateTransformMatrix() {
+ DisplayPrimaries displayPrimaries = new DisplayPrimaries();
+ displayPrimaries.red = new CieXyz();
+ displayPrimaries.red.X = 0.412315f;
+ displayPrimaries.red.Y = 0.212600f;
+ displayPrimaries.red.Z = 0.019327f;
+ displayPrimaries.green = new CieXyz();
+ displayPrimaries.green.X = 0.357600f;
+ displayPrimaries.green.Y = 0.715200f;
+ displayPrimaries.green.Z = 0.119200f;
+ displayPrimaries.blue = new CieXyz();
+ displayPrimaries.blue.X = 0.180500f;
+ displayPrimaries.blue.Y = 0.072200f;
+ displayPrimaries.blue.Z = 0.950633f;
+ displayPrimaries.white = new CieXyz();
+ displayPrimaries.white.X = 0.950456f;
+ displayPrimaries.white.Y = 1.000000f;
+ displayPrimaries.white.Z = 1.089058f;
+ doReturn(displayPrimaries)
+ .when(() -> SurfaceControl.getDisplayNativePrimaries(mDisplayToken));
+
+ setUpTintController();
+ assertWithMessage("Setup with valid SurfaceControl failed")
+ .that(mDisplayWhiteBalanceTintController.mSetUp)
+ .isTrue();
+
+ final int cct = 6500;
+ mDisplayWhiteBalanceTintController.setMatrix(cct);
+ assertWithMessage("Failed to set temperature")
+ .that(mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
+ .isEqualTo(cct);
+
+ float[] matrixDwb = mDisplayWhiteBalanceTintController.getMatrix();
+ final float[] expectedMatrixDwb = {
+ 0.962880f, -0.001780f, -0.000158f, 0.0f,
+ 0.035765f, 0.929988f, 0.000858f, 0.0f,
+ 0.001354f, -0.000470f, 0.948327f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ };
+ assertArrayEquals("Unexpected DWB matrix", matrixDwb, expectedMatrixDwb,
+ 1e-6f /* tolerance */);
+ }
+
private void setUpTintController() {
mDisplayWhiteBalanceTintController = new DisplayWhiteBalanceTintController();
mDisplayWhiteBalanceTintController.setUp(mMockedContext, true);
+ mDisplayWhiteBalanceTintController.setActivated(true);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index a25e40f8cc13..9a1fd9cf0e12 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -2650,6 +2650,21 @@ public class DevicePolicyManagerTest extends DpmTestBase {
verifyStayOnWhilePluggedCleared(false);
}
+ public void testIsActiveSupervisionApp() throws Exception {
+ when(mServiceContext.resources
+ .getString(R.string.config_defaultSupervisionProfileOwnerComponent))
+ .thenReturn(admin1.flattenToString());
+
+ final int PROFILE_USER = 15;
+ final int PROFILE_ADMIN = UserHandle.getUid(PROFILE_USER, 19436);
+ addManagedProfile(admin1, PROFILE_ADMIN, admin1);
+ mContext.binder.callingUid = PROFILE_ADMIN;
+
+ final DevicePolicyManagerInternal dpmi =
+ LocalServices.getService(DevicePolicyManagerInternal.class);
+ assertTrue(dpmi.isActiveSupervisionApp(PROFILE_ADMIN));
+ }
+
// Test if lock timeout on managed profile is handled correctly depending on whether profile
// uses separate challenge.
public void testSetMaximumTimeToLockProfile() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java
index 0d5a7d6c1952..acf2d0e700d4 100644
--- a/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java
@@ -78,6 +78,8 @@ public final class AmbientLuxTest {
@Mock private TypedArray mBiases;
@Mock private TypedArray mHighLightBrightnesses;
@Mock private TypedArray mHighLightBiases;
+ @Mock private TypedArray mAmbientColorTemperatures;
+ @Mock private TypedArray mDisplayColorTemperatures;
@Before
public void setUp() throws Exception {
@@ -105,10 +107,10 @@ public final class AmbientLuxTest {
HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE);
when(mResourcesSpy.obtainTypedArray(
R.array.config_displayWhiteBalanceAmbientColorTemperatures))
- .thenReturn(createTypedArray());
+ .thenReturn(mAmbientColorTemperatures);
when(mResourcesSpy.obtainTypedArray(
R.array.config_displayWhiteBalanceDisplayColorTemperatures))
- .thenReturn(createTypedArray());
+ .thenReturn(mDisplayColorTemperatures);
when(mResourcesSpy.obtainTypedArray(
R.array.config_displayWhiteBalanceLowLightAmbientBrightnesses))
@@ -388,6 +390,16 @@ public final class AmbientLuxTest {
assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
}
+ @Test
+ public void testWhiteBalance_updateWithEmptyFilter() throws Exception {
+ setAmbientColorTemperatures(5300.0f, 6000.0f, 7000.0f, 8000.0f);
+ setDisplayColorTemperatures(6300.0f, 6400.0f, 6850.0f, 7450.0f);
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ controller.updateAmbientColorTemperature();
+ assertEquals(-1.0f, controller.mPendingAmbientColorTemperature, 0);
+ }
+
void mockThrottler() {
when(mResourcesSpy.getInteger(
R.integer.config_displayWhiteBalanceDecreaseDebounce)).thenReturn(0);
@@ -455,6 +467,14 @@ public final class AmbientLuxTest {
setFloatArrayResource(mHighLightBiases, vals);
}
+ private void setAmbientColorTemperatures(float... vals) {
+ setFloatArrayResource(mAmbientColorTemperatures, vals);
+ }
+
+ private void setDisplayColorTemperatures(float... vals) {
+ setFloatArrayResource(mDisplayColorTemperatures, vals);
+ }
+
private void setFloatArrayResource(TypedArray array, float[] vals) {
when(array.length()).thenReturn(vals.length);
for (int i = 0; i < vals.length; i++) {
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java
new file mode 100644
index 000000000000..1cb2fb3517d3
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.integrity.model;
+
+import static com.android.server.testutils.TestUtils.assertExpectException;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class AtomicFormulaTest {
+
+ @Test
+ public void testValidAtomicFormula_stringValue() {
+ AtomicFormula atomicFormula = new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME,
+ AtomicFormula.Operator.EQ, "com.test.app");
+
+ assertEquals(AtomicFormula.Key.PACKAGE_NAME, atomicFormula.getKey());
+ assertEquals(AtomicFormula.Operator.EQ, atomicFormula.getOperator());
+ assertEquals("com.test.app", atomicFormula.getStringValue());
+ }
+
+ @Test
+ public void testValidAtomicFormula_intValue() {
+ AtomicFormula atomicFormula = new AtomicFormula(AtomicFormula.Key.VERSION_CODE,
+ AtomicFormula.Operator.LE, 1);
+
+ assertEquals(AtomicFormula.Key.VERSION_CODE, atomicFormula.getKey());
+ assertEquals(AtomicFormula.Operator.LE, atomicFormula.getOperator());
+ assertEquals(1, atomicFormula.getIntValue().intValue());
+ }
+
+ @Test
+ public void testValidAtomicFormula_boolValue() {
+ AtomicFormula atomicFormula = new AtomicFormula(AtomicFormula.Key.PRE_INSTALLED,
+ AtomicFormula.Operator.EQ, true);
+
+ assertEquals(AtomicFormula.Key.PRE_INSTALLED, atomicFormula.getKey());
+ assertEquals(AtomicFormula.Operator.EQ, atomicFormula.getOperator());
+ assertEquals(true, atomicFormula.getBoolValue());
+ }
+
+ @Test
+ public void testInvalidAtomicFormula_stringValue() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Key %s cannot have string value", AtomicFormula.Key.VERSION_CODE),
+ () -> new AtomicFormula(AtomicFormula.Key.VERSION_CODE, AtomicFormula.Operator.EQ,
+ "test-value"));
+ }
+
+ @Test
+ public void testInvalidAtomicFormula_intValue() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Key %s cannot have integer value", AtomicFormula.Key.PACKAGE_NAME),
+ () -> new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.EQ,
+ 1));
+ }
+
+ @Test
+ public void testInvalidAtomicFormula_boolValue() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Key %s cannot have boolean value", AtomicFormula.Key.PACKAGE_NAME),
+ () -> new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.EQ,
+ true));
+ }
+
+ @Test
+ public void testValidateOperator_invalidKeyOperatorPair() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Invalid operator %s used for key %s",
+ AtomicFormula.Operator.LE, AtomicFormula.Key.PACKAGE_NAME),
+ () -> new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.LE,
+ "test-value"));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java
new file mode 100644
index 000000000000..1a3dde0cb838
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.integrity.model;
+
+import static com.android.server.testutils.TestUtils.assertExpectException;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class OpenFormulaTest {
+
+ private static final AtomicFormula ATOMIC_FORMULA_1 = new AtomicFormula(
+ AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.EQ, "test1");
+ private static final AtomicFormula ATOMIC_FORMULA_2 = new AtomicFormula(
+ AtomicFormula.Key.VERSION_CODE, AtomicFormula.Operator.EQ, 1);
+
+ @Test
+ public void testValidOpenFormula() {
+ OpenFormula openFormula = new OpenFormula(OpenFormula.Connector.AND, ATOMIC_FORMULA_1,
+ ATOMIC_FORMULA_2);
+
+ assertEquals(OpenFormula.Connector.AND, openFormula.getConnector());
+ assertEquals(ATOMIC_FORMULA_1, openFormula.getMainFormula());
+ assertEquals(ATOMIC_FORMULA_2, openFormula.getAuxiliaryFormula());
+ }
+
+ @Test
+ public void testValidateAuxiliaryFormula_binaryConnectors() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Invalid formulas used for connector %s", OpenFormula.Connector.AND),
+ () -> new OpenFormula(OpenFormula.Connector.AND, ATOMIC_FORMULA_1,
+ null));
+ }
+
+ @Test
+ public void testValidateAuxiliaryFormula_unaryConnectors() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Invalid formulas used for connector %s", OpenFormula.Connector.NOT),
+ () -> new OpenFormula(OpenFormula.Connector.NOT, ATOMIC_FORMULA_1,
+ ATOMIC_FORMULA_2));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java
index 4321c21f68b2..cf001be2cf82 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java
@@ -29,8 +29,9 @@ import org.junit.runners.JUnit4;
public class RuleTest {
private static final Rule.Effect DENY_EFFECT = Rule.Effect.DENY;
- private static final Rule.Formula SIMPLE_FORMULA =
- new Rule.AtomicFormula(Rule.Key.PACKAGE_NAME, Rule.Operator.EQ, "com.test.app");
+ private static final Formula SIMPLE_FORMULA =
+ new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.EQ,
+ "com.test.app");
@Test
public void testEmptyRule() {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index f652c5afd203..721641a7a8c8 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -15,6 +15,8 @@
*/
package com.android.server.notification;
+import static com.android.server.notification.GroupHelper.AUTOGROUP_KEY;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
@@ -155,6 +157,196 @@ public class GroupHelperTest extends UiServiceTestCase {
}
@Test
+ public void testAutoGroupCount_addingNoGroupSBN() {
+ final String pkg = "package";
+ ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) {
+ notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+ sbn.setOverrideGroupKey(AUTOGROUP_KEY);
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ mGroupHelper.onNotificationPosted(sbn, true);
+ }
+
+ verify(mCallback, times(AUTOGROUP_AT_COUNT + 1))
+ .updateAutogroupSummary(anyString(), eq(true));
+
+ int userId = UserHandle.SYSTEM.getIdentifier();
+ assertEquals(mGroupHelper.getOngoingGroupCount(
+ userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT + 1);
+ }
+
+ @Test
+ public void testAutoGroupCount_UpdateNotification() {
+ final String pkg = "package";
+ ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) {
+ notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+ sbn.setOverrideGroupKey(AUTOGROUP_KEY);
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ mGroupHelper.onNotificationPosted(sbn, true);
+ }
+
+ notifications.get(0).getNotification().flags &= ~Notification.FLAG_ONGOING_EVENT;
+
+ mGroupHelper.onNotificationUpdated(notifications.get(0), true);
+
+ verify(mCallback, times(AUTOGROUP_AT_COUNT + 2))
+ .updateAutogroupSummary(anyString(), eq(true));
+
+ int userId = UserHandle.SYSTEM.getIdentifier();
+ assertEquals(mGroupHelper.getOngoingGroupCount(
+ userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT);
+ }
+
+ @Test
+ public void testAutoGroupCount_UpdateNotificationAfterChanges() {
+ final String pkg = "package";
+ ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) {
+ notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+ sbn.setOverrideGroupKey(AUTOGROUP_KEY);
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ mGroupHelper.onNotificationPosted(sbn, true);
+ }
+
+ notifications.get(0).getNotification().flags &= ~Notification.FLAG_ONGOING_EVENT;
+
+ mGroupHelper.onNotificationUpdated(notifications.get(0), true);
+
+ notifications.get(0).getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+
+ mGroupHelper.onNotificationUpdated(notifications.get(0), true);
+
+ verify(mCallback, times(AUTOGROUP_AT_COUNT + 3))
+ .updateAutogroupSummary(anyString(), eq(true));
+
+ int userId = UserHandle.SYSTEM.getIdentifier();
+ assertEquals(mGroupHelper.getOngoingGroupCount(
+ userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT + 1);
+ }
+
+ @Test
+ public void testAutoGroupCount_RemoveNotification() {
+ final String pkg = "package";
+ ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) {
+ notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+ sbn.setOverrideGroupKey(AUTOGROUP_KEY);
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ mGroupHelper.onNotificationPosted(sbn, true);
+ }
+
+ mGroupHelper.onNotificationRemoved(notifications.get(0));
+
+ verify(mCallback, times(AUTOGROUP_AT_COUNT + 2))
+ .updateAutogroupSummary(anyString(), eq(true));
+
+ int userId = UserHandle.SYSTEM.getIdentifier();
+ assertEquals(mGroupHelper.getOngoingGroupCount(
+ userId, pkg, AUTOGROUP_KEY), AUTOGROUP_AT_COUNT);
+ }
+
+
+ @Test
+ public void testAutoGroupCount_UpdateToNoneOngoingNotification() {
+ final String pkg = "package";
+ ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) {
+ notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ sbn.setOverrideGroupKey(AUTOGROUP_KEY);
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ mGroupHelper.onNotificationPosted(sbn, true);
+ }
+
+ notifications.get(0).getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+ mGroupHelper.onNotificationUpdated(notifications.get(0), true);
+
+ verify(mCallback, times(1))
+ .updateAutogroupSummary(anyString(), eq(true));
+
+ int userId = UserHandle.SYSTEM.getIdentifier();
+ assertEquals(mGroupHelper.getOngoingGroupCount(
+ userId, pkg, AUTOGROUP_KEY), 1);
+ }
+
+ @Test
+ public void testAutoGroupCount_AddOneOngoingNotification() {
+ final String pkg = "package";
+ ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) {
+ notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ }
+ StatusBarNotification sbn = notifications.get(0);
+ sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+ sbn.setOverrideGroupKey(AUTOGROUP_KEY);
+
+
+ for (StatusBarNotification current: notifications) {
+ mGroupHelper.onNotificationPosted(current, true);
+ }
+
+ verify(mCallback, times(1))
+ .updateAutogroupSummary(anyString(), eq(true));
+
+ int userId = UserHandle.SYSTEM.getIdentifier();
+ assertEquals(mGroupHelper.getOngoingGroupCount(
+ userId, pkg, AUTOGROUP_KEY), 1);
+ }
+
+ @Test
+ public void testAutoGroupCount_UpdateNoneOngoing() {
+ final String pkg = "package";
+ ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+ for (int i = 0; i < AUTOGROUP_AT_COUNT + 1; i++) {
+ notifications.add(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ sbn.setOverrideGroupKey(AUTOGROUP_KEY);
+ }
+
+ for (StatusBarNotification sbn: notifications) {
+ mGroupHelper.onNotificationPosted(sbn, true);
+ }
+
+ verify(mCallback, times(0))
+ .updateAutogroupSummary(anyString(), eq(true));
+
+ int userId = UserHandle.SYSTEM.getIdentifier();
+ assertEquals(mGroupHelper.getOngoingGroupCount(userId, pkg, AUTOGROUP_KEY), 0);
+ }
+
+
+ @Test
public void testDropToZeroRemoveGroup() throws Exception {
final String pkg = "package";
List<StatusBarNotification> posted = new ArrayList<>();
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 e80c6291b42a..4ea2fc0d398e 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -44,6 +44,7 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION_CODES.O_MR1;
import static android.os.Build.VERSION_CODES.P;
+import static android.os.UserHandle.USER_SYSTEM;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
@@ -129,6 +130,7 @@ import android.testing.TestableContext;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.testing.TestablePermissions;
+import android.testing.TestableResources;
import android.text.Html;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -1180,6 +1182,36 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testAutobundledSummary_notificationAdded() {
+ NotificationRecord summary =
+ generateNotificationRecord(mTestNotificationChannel, 0, "pkg", true);
+ summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
+ mService.addNotification(summary);
+ mService.mSummaryByGroupKey.put("pkg", summary);
+ mService.mAutobundledSummaries.put(0, new ArrayMap<>());
+ mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey());
+ mService.updateAutobundledSummaryFlags(0, "pkg", true);
+
+ assertTrue(summary.sbn.isOngoing());
+ }
+
+ @Test
+ public void testAutobundledSummary_notificationRemoved() {
+ NotificationRecord summary =
+ generateNotificationRecord(mTestNotificationChannel, 0, "pkg", true);
+ summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
+ summary.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+ mService.addNotification(summary);
+ mService.mAutobundledSummaries.put(0, new ArrayMap<>());
+ mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey());
+ mService.mSummaryByGroupKey.put("pkg", summary);
+
+ mService.updateAutobundledSummaryFlags(0, "pkg", false);
+
+ assertFalse(summary.sbn.isOngoing());
+ }
+
+ @Test
public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
@@ -3278,7 +3310,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testRestore() throws Exception {
int systemChecks = mService.countSystemChecks;
- mBinderService.applyRestore(null, UserHandle.USER_SYSTEM);
+ mBinderService.applyRestore(null, USER_SYSTEM);
assertEquals(1, mService.countSystemChecks - systemChecks);
}
@@ -3347,7 +3379,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
reset(mUgmInternal);
when(mUgmInternal.newUriPermissionOwner(any())).thenReturn(new Binder());
mService.updateUriPermissions(recordA, null, mContext.getPackageName(),
- UserHandle.USER_SYSTEM);
+ USER_SYSTEM);
verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
@@ -3363,21 +3395,21 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Update means we drop access to first
reset(mUgmInternal);
mService.updateUriPermissions(recordB, recordA, mContext.getPackageName(),
- UserHandle.USER_SYSTEM);
+ USER_SYSTEM);
verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(any(),
eq(message1.getDataUri()), anyInt(), anyInt());
// Update back means we grant access to first again
reset(mUgm);
mService.updateUriPermissions(recordA, recordB, mContext.getPackageName(),
- UserHandle.USER_SYSTEM);
+ USER_SYSTEM);
verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
// And update to empty means we drop everything
reset(mUgmInternal);
mService.updateUriPermissions(null, recordB, mContext.getPackageName(),
- UserHandle.USER_SYSTEM);
+ USER_SYSTEM);
verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(any(), eq(null),
anyInt(), anyInt());
}
@@ -4077,7 +4109,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testIsCallerInstantApp_userAllNotification() throws Exception {
ApplicationInfo info = new ApplicationInfo();
info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
- when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(UserHandle.USER_SYSTEM)))
+ when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(USER_SYSTEM)))
.thenReturn(info);
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{"any"});
@@ -5666,4 +5698,33 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
assertEquals(1, notifsAfter.length);
}
+
+ @Test
+ public void testLoadDefaultApprovedServices_emptyResources() {
+ TestableResources tr = mContext.getOrCreateTestableResources();
+ tr.addOverride(com.android.internal.R.string.config_defaultListenerAccessPackages, "");
+ tr.addOverride(com.android.internal.R.string.config_defaultDndAccessPackages, "");
+ tr.addOverride(com.android.internal.R.string.config_defaultAssistantAccessComponent, "");
+ setDefaultAssistantInDeviceConfig("");
+
+ mService.loadDefaultApprovedServices(USER_SYSTEM);
+
+ verify(mListeners, never()).addDefaultComponentOrPackage(anyString());
+ verify(mConditionProviders, never()).addDefaultComponentOrPackage(anyString());
+ verify(mAssistants, never()).addDefaultComponentOrPackage(anyString());
+ }
+
+ @Test
+ public void testLoadDefaultApprovedServices_dnd() {
+ TestableResources tr = mContext.getOrCreateTestableResources();
+ tr.addOverride(com.android.internal.R.string.config_defaultDndAccessPackages, "test");
+ when(mListeners.queryPackageForServices(anyString(), anyInt(), anyInt()))
+ .thenReturn(new ArraySet<>());
+
+ mService.loadDefaultApprovedServices(USER_SYSTEM);
+
+ verify(mConditionProviders, times(1)).addDefaultComponentOrPackage("test");
+ }
+
+ // TODO: add tests for the rest of the non-empty cases
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
index 69cc9b256b83..fff32215493b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -317,24 +317,24 @@ public class ActivityDisplayTests extends ActivityTestsBase {
doAnswer(invocation -> {
display.positionChildAtTop(stack3, false);
return true;
- }).when(mSupervisor).removeTaskByIdLocked(eq(task4.taskId), anyBoolean(), anyBoolean(),
+ }).when(mSupervisor).removeTaskByIdLocked(eq(task4.mTaskId), anyBoolean(), anyBoolean(),
any());
// Removing stacks from the display while removing stacks.
doAnswer(invocation -> {
display.removeChild(stack2);
return true;
- }).when(mSupervisor).removeTaskByIdLocked(eq(task2.taskId), anyBoolean(), anyBoolean(),
+ }).when(mSupervisor).removeTaskByIdLocked(eq(task2.mTaskId), anyBoolean(), anyBoolean(),
any());
runnable.run();
- verify(mSupervisor).removeTaskByIdLocked(eq(task4.taskId), anyBoolean(), anyBoolean(),
+ verify(mSupervisor).removeTaskByIdLocked(eq(task4.mTaskId), anyBoolean(), anyBoolean(),
any());
- verify(mSupervisor).removeTaskByIdLocked(eq(task3.taskId), anyBoolean(), anyBoolean(),
+ verify(mSupervisor).removeTaskByIdLocked(eq(task3.mTaskId), anyBoolean(), anyBoolean(),
any());
- verify(mSupervisor).removeTaskByIdLocked(eq(task2.taskId), anyBoolean(), anyBoolean(),
+ verify(mSupervisor).removeTaskByIdLocked(eq(task2.mTaskId), anyBoolean(), anyBoolean(),
any());
- verify(mSupervisor).removeTaskByIdLocked(eq(task1.taskId), anyBoolean(), anyBoolean(),
+ verify(mSupervisor).removeTaskByIdLocked(eq(task1.mTaskId), anyBoolean(), anyBoolean(),
any());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
index 9e1df913b22c..1eeca91e29d0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -127,7 +127,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
mSupervisor.handleNonResizableTaskIfNeeded(task, newDisplay.getWindowingMode(),
newDisplay.mDisplayId, stack);
// The top activity is unresizable, so it should notify the activity is forced resizing.
- verify(taskChangeNotifier).notifyActivityForcedResizable(eq(task.taskId),
+ verify(taskChangeNotifier).notifyActivityForcedResizable(eq(task.mTaskId),
eq(FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY),
eq(unresizableActivity.packageName));
reset(taskChangeNotifier);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 668ad78e5900..77fbdcf8ff52 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -42,7 +42,6 @@ import android.content.res.Configuration;
import android.os.Build;
import android.os.UserHandle;
import android.service.voice.IVoiceInteractionSession;
-import android.testing.DexmakerShareClassLoaderRule;
import android.util.Pair;
import android.view.DisplayInfo;
@@ -385,9 +384,10 @@ class ActivityTestsBase extends SystemServiceTestsBase {
intent.setFlags(mFlags);
final TaskRecord task = new TaskRecord(mSupervisor.mService, mTaskId, aInfo,
- intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/);
+ intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/,
+ null /*taskDescription*/);
spyOn(task);
- task.userId = mUserId;
+ task.mUserId = mUserId;
if (mStack != null) {
mStack.moveToFront("test");
@@ -396,8 +396,6 @@ class ActivityTestsBase extends SystemServiceTestsBase {
spyOn(task.mTask);
}
- task.touchActiveTime();
-
return task;
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index fcda49472e8d..26617355cfbf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -221,7 +221,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
containerBounds.set(0, 0, 600, 800);
mToken.onConfigurationChanged(newParentConfig);
- assertTrue(mToken.inSizeCompatMode());
+ assertTrue(mToken.hasSizeCompatBounds());
assertEquals(containerAppBounds, mToken.getBounds());
assertEquals((float) containerAppBounds.width() / fixedBounds.width(),
mToken.getSizeCompatScale(), 0.0001f /* delta */);
@@ -231,7 +231,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
containerBounds.set(containerAppBounds);
mToken.onConfigurationChanged(newParentConfig);
- assertTrue(mToken.inSizeCompatMode());
+ assertTrue(mToken.hasSizeCompatBounds());
// Don't scale up, so the bounds keep the same as the fixed width.
assertEquals(fixedBounds.width(), mToken.getBounds().width());
// Assert the position is horizontal center.
@@ -243,7 +243,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
containerBounds.set(0, 0, 1200, 2000);
mToken.onConfigurationChanged(newParentConfig);
// Assert don't use fixed bounds because the region is enough.
- assertFalse(mToken.inSizeCompatMode());
+ assertFalse(mToken.hasSizeCompatBounds());
}
@Test
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 c48dc25662bd..2ba3cbdadad4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -706,13 +706,13 @@ public class DisplayContentTests extends WindowTestsBase {
final ActivityStack stack =
new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
- .setDisplay(dc.mAcitvityDisplay).build();
+ .setDisplay(dc.mActivityDisplay).build();
final ActivityRecord activity = stack.topTask().getTopActivity();
activity.setRequestedOrientation(newOrientation);
final ArgumentCaptor<Configuration> captor = ArgumentCaptor.forClass(Configuration.class);
- verify(dc.mAcitvityDisplay).updateDisplayOverrideConfigurationLocked(captor.capture(),
+ verify(dc.mActivityDisplay).updateDisplayOverrideConfigurationLocked(captor.capture(),
same(activity), anyBoolean(), same(null));
final Configuration newDisplayConfig = captor.getValue();
final int expectedOrientation = newOrientation == SCREEN_ORIENTATION_PORTRAIT
@@ -732,12 +732,12 @@ public class DisplayContentTests extends WindowTestsBase {
final ActivityStack stack =
new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
- .setDisplay(dc.mAcitvityDisplay).build();
+ .setDisplay(dc.mActivityDisplay).build();
final ActivityRecord activity = stack.topTask().getTopActivity();
activity.setRequestedOrientation(newOrientation);
- verify(dc.mAcitvityDisplay, never()).updateDisplayOverrideConfigurationLocked(any(),
+ verify(dc.mActivityDisplay, never()).updateDisplayOverrideConfigurationLocked(any(),
eq(activity), anyBoolean(), same(null));
assertEquals(dc.getDisplayRotation().getUserRotation(), dc.getRotation());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
index be2ee2909a22..46435ebd8e15 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
@@ -422,7 +422,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
@Override
void saveTask(TaskRecord task) {
- final int userId = task.userId;
+ final int userId = task.mUserId;
final ComponentName realActivity = task.realActivity;
mTmpParams.mPreferredDisplayId = task.getStack().mDisplayId;
mTmpParams.mWindowingMode = task.getWindowingMode();
@@ -436,7 +436,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase {
@Override
void getLaunchParams(TaskRecord task, ActivityRecord activity, LaunchParams params) {
- final int userId = task != null ? task.userId : activity.mUserId;
+ final int userId = task != null ? task.mUserId : activity.mUserId;
final ComponentName name = task != null
? task.realActivity : activity.mActivityComponent;
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
index 49d778f023e5..7115af9f1ee9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -115,16 +115,16 @@ public class LaunchParamsPersisterTests extends ActivityTestsBase {
ACTIVITY_TYPE_STANDARD, /* onTop */ true);
mTestTask = new TaskBuilder(mSupervisor).setComponent(TEST_COMPONENT).setStack(stack)
.build();
- mTestTask.userId = TEST_USER_ID;
+ mTestTask.mUserId = TEST_USER_ID;
mTestTask.mLastNonFullscreenBounds = TEST_BOUNDS;
mTestTask.hasBeenVisible = true;
mTaskWithDifferentComponent = new TaskBuilder(mSupervisor)
.setComponent(ALTERNATIVE_COMPONENT).build();
- mTaskWithDifferentComponent.userId = TEST_USER_ID;
+ mTaskWithDifferentComponent.mUserId = TEST_USER_ID;
mTaskWithDifferentUser = new TaskBuilder(mSupervisor).setComponent(TEST_COMPONENT).build();
- mTaskWithDifferentUser.userId = ALTERNATIVE_USER_ID;
+ mTaskWithDifferentUser.mUserId = ALTERNATIVE_USER_ID;
mTarget = new LaunchParamsPersister(mPersisterQueue, mSupervisor, mUserFolderGetter);
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 47c76fc28d15..05e173c957d3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
@@ -707,7 +707,7 @@ public class LockTaskControllerTest {
TaskRecord tr = mock(TaskRecord.class);
tr.mLockTaskAuth = lockTaskAuth;
tr.intent = intent;
- tr.userId = TEST_USER_ID;
+ tr.mUserId = TEST_USER_ID;
return tr;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 445a5cc50d51..cc598ffa63bd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -882,7 +882,7 @@ public class RecentTasksTest extends ActivityTestsBase {
@Test
public void testNotRestoreRecentTaskApis() {
final TaskRecord task = createTaskBuilder(".Task").build();
- final int taskId = task.taskId;
+ final int taskId = task.mTaskId;
mRecentTasks.add(task);
// Only keep the task in RecentTasks.
task.removeWindowContainer();
@@ -968,7 +968,7 @@ public class RecentTasksTest extends ActivityTestsBase {
TEST_USER_0_ID, 0).getList();
assertTrue(expectedTasks.length == infos.size());
for (int i = 0; i < infos.size(); i++) {
- assertTrue(expectedTasks[i].taskId == infos.get(i).taskId);
+ assertTrue(expectedTasks[i].mTaskId == infos.get(i).taskId);
}
}
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 6b28135f2b1c..f353846202e6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -138,7 +138,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
@Test
public void testIncludedApps_expectTargetAndVisible() {
mWm.setRecentsAnimationController(mController);
- final ActivityStack homeStack = mDisplayContent.mAcitvityDisplay.getOrCreateStack(
+ final ActivityStack homeStack = mDisplayContent.mActivityDisplay.getOrCreateStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
final AppWindowToken homeAppWindow =
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
@@ -163,7 +163,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
@Test
public void testWallpaperIncluded_expectTarget() throws Exception {
mWm.setRecentsAnimationController(mController);
- final ActivityStack homeStack = mDisplayContent.mAcitvityDisplay.getOrCreateStack(
+ final ActivityStack homeStack = mDisplayContent.mActivityDisplay.getOrCreateStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
final AppWindowToken homeAppWindow =
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
@@ -192,7 +192,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
@Test
public void testWallpaperAnimatorCanceled_expectAnimationKeepsRunning() throws Exception {
mWm.setRecentsAnimationController(mController);
- final ActivityStack homeStack = mDisplayContent.mAcitvityDisplay.getOrCreateStack(
+ final ActivityStack homeStack = mDisplayContent.mActivityDisplay.getOrCreateStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
final AppWindowToken homeAppWindow =
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
@@ -223,7 +223,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
@Test
public void testFinish_expectTargetAndWallpaperAdaptersRemoved() {
mWm.setRecentsAnimationController(mController);
- final ActivityStack homeStack = mDisplayContent.mAcitvityDisplay.getOrCreateStack(
+ final ActivityStack homeStack = mDisplayContent.mActivityDisplay.getOrCreateStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
final AppWindowToken homeAppWindow =
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index c6ffc4641261..ebedde7d4460 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -345,7 +345,7 @@ public class RecentsAnimationTest extends ActivityTestsBase {
.setCreateTask(true)
.setComponent(new ComponentName(mContext.getPackageName(), "Home2"))
.build();
- otherUserHomeActivity.getTaskRecord().userId = TEST_USER_ID;
+ otherUserHomeActivity.getTaskRecord().mUserId = TEST_USER_ID;
ActivityStack fullscreenStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
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 86e307b4f0a5..0f8fb0417d01 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -119,7 +119,7 @@ public class TaskRecordTests extends ActivityTestsBase {
final byte[] serializedBytes = serializeToBytes(expected);
final TaskRecord actual = restoreFromBytes(serializedBytes);
- assertEquals(expected.taskId, actual.taskId);
+ assertEquals(expected.mTaskId, actual.mTaskId);
assertEquals(expected.mLastNonFullscreenBounds, actual.mLastNonFullscreenBounds);
}
@@ -132,7 +132,7 @@ public class TaskRecordTests extends ActivityTestsBase {
@Test
public void testCopyBaseIntentForTaskInfo() {
final TaskRecord task = createTaskRecord(1);
- task.lastTaskDescription = new ActivityManager.TaskDescription();
+ task.mTaskDescription = new ActivityManager.TaskDescription();
final TaskInfo info = task.getTaskInfo();
// The intent of info should be a copy so assert that they are different instances.
@@ -648,9 +648,9 @@ public class TaskRecordTests extends ActivityTestsBase {
final TaskRecord task1 = getTestTask();
final ActivityRecord activity1 = task1.getChildAt(0);
- assertEquals(task0.taskId,
+ assertEquals(task0.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity0.appToken, false /* onlyRoot */));
- assertEquals(task1.taskId,
+ assertEquals(task1.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity1.appToken, false /* onlyRoot */));
}
@@ -669,9 +669,9 @@ public class TaskRecordTests extends ActivityTestsBase {
// Add one more on top
final ActivityRecord activity2 = new ActivityBuilder(mService).setTask(task).build();
- assertEquals(task.taskId,
+ assertEquals(task.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity0.appToken, true /* onlyRoot */));
- assertEquals(task.taskId,
+ assertEquals(task.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity1.appToken, true /* onlyRoot */));
assertEquals("No task must be reported for activity that is above root", INVALID_TASK_ID,
ActivityRecord.getTaskForActivityLocked(activity2.appToken, true /* onlyRoot */));
@@ -692,9 +692,9 @@ public class TaskRecordTests extends ActivityTestsBase {
// Add one more on top
final ActivityRecord activity2 = new ActivityBuilder(mService).setTask(task).build();
- assertEquals(task.taskId,
+ assertEquals(task.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity0.appToken, true /* onlyRoot */));
- assertEquals(task.taskId,
+ assertEquals(task.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity1.appToken, true /* onlyRoot */));
assertEquals("No task must be reported for activity that is above root", INVALID_TASK_ID,
ActivityRecord.getTaskForActivityLocked(activity2.appToken, true /* onlyRoot */));
@@ -718,11 +718,11 @@ public class TaskRecordTests extends ActivityTestsBase {
// Add one more activity on top
final ActivityRecord activity2 = new ActivityBuilder(mService).setTask(task).build();
- assertEquals(task.taskId,
+ assertEquals(task.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity0.appToken, false /* onlyRoot */));
- assertEquals(task.taskId,
+ assertEquals(task.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity1.appToken, false /* onlyRoot */));
- assertEquals(task.taskId,
+ assertEquals(task.mTaskId,
ActivityRecord.getTaskForActivityLocked(activity2.appToken, false /* onlyRoot */));
}
@@ -832,8 +832,8 @@ public class TaskRecordTests extends ActivityTestsBase {
private TaskRecord createTaskRecord(int taskId) {
return new TaskRecord(mService, taskId, new Intent(), null, null, null,
ActivityBuilder.getDefaultComponent(), null, false, false, false, 0, 10050, null,
- new ArrayList<>(), 0, false, null, 0, 0, 0, 0, 0, null, 0, false, false, false, 0, 0
- );
+ new ArrayList<>(), 0, false, null, 0, 0, 0, 0, 0, null, 0, false, false, false, 0,
+ 0, null /*ActivityInfo*/, null /*_voiceSession*/, null /*_voiceInteractor*/);
}
private static class TestTaskRecordFactory extends TaskRecordFactory {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 34eb3f16bf2a..ecee709054ee 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -1733,10 +1733,13 @@ public class UsageStatsService extends SystemService implements
public void registerAppUsageLimitObserver(int observerId, String[] packages,
long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent,
String callingPackage) {
+ final int callingUid = Binder.getCallingUid();
+ final DevicePolicyManagerInternal dpmInternal = getDpmInternal();
if (!hasPermissions(callingPackage,
- Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE)) {
- throw new SecurityException("Caller doesn't have both SUSPEND_APPS and "
- + "OBSERVE_APP_USAGE permissions");
+ Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE)
+ && (dpmInternal != null && !dpmInternal.isActiveSupervisionApp(callingUid))) {
+ throw new SecurityException("Caller must be the active supervision app or "
+ + "it must have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions");
}
if (packages == null || packages.length == 0) {
@@ -1745,7 +1748,6 @@ public class UsageStatsService extends SystemService implements
if (callbackIntent == null && timeUsedMs < timeLimitMs) {
throw new NullPointerException("callbackIntent can't be null");
}
- final int callingUid = Binder.getCallingUid();
final int userId = UserHandle.getUserId(callingUid);
final long token = Binder.clearCallingIdentity();
try {
@@ -1758,13 +1760,15 @@ public class UsageStatsService extends SystemService implements
@Override
public void unregisterAppUsageLimitObserver(int observerId, String callingPackage) {
+ final int callingUid = Binder.getCallingUid();
+ final DevicePolicyManagerInternal dpmInternal = getDpmInternal();
if (!hasPermissions(callingPackage,
- Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE)) {
- throw new SecurityException("Caller doesn't have both SUSPEND_APPS and "
- + "OBSERVE_APP_USAGE permissions");
+ Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE)
+ && (dpmInternal != null && !dpmInternal.isActiveSupervisionApp(callingUid))) {
+ throw new SecurityException("Caller must be the active supervision app or "
+ + "it must have both SUSPEND_APPS and OBSERVE_APP_USAGE permissions");
}
- final int callingUid = Binder.getCallingUid();
final int userId = UserHandle.getUserId(callingUid);
final long token = Binder.clearCallingIdentity();
try {
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
index 9735502a4f69..973924379f5a 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
@@ -159,7 +159,8 @@ public final class UsbDeviceDescriptor extends UsbDescriptor {
return new UsbDevice.Builder(parser.getDeviceAddr(), mVendorID,
mProductID, mDevClass, mDevSubClass, mProtocol, mfgName, prodName, versionString,
- configs, serialStr, parser.hasAudioPlayback(), parser.hasAudioCapture());
+ configs, serialStr, parser.hasAudioPlayback(), parser.hasAudioCapture(),
+ parser.hasMIDIInterface());
}
@Override
diff --git a/telephony/common/com/android/internal/telephony/HbpcdLookup.java b/telephony/common/com/android/internal/telephony/HbpcdLookup.java
new file mode 100644
index 000000000000..d9a3e725b6fb
--- /dev/null
+++ b/telephony/common/com/android/internal/telephony/HbpcdLookup.java
@@ -0,0 +1,124 @@
+/*
+**
+** Copyright 2014, 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.telephony;
+
+import android.net.Uri;
+import android.provider.BaseColumns;
+
+/**
+ * @hide
+ */
+public class HbpcdLookup {
+ public static final String AUTHORITY = "hbpcd_lookup";
+
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY);
+
+ public static final String PATH_MCC_IDD = "idd";
+ public static final String PATH_MCC_LOOKUP_TABLE = "lookup";
+ public static final String PATH_MCC_SID_CONFLICT = "conflict";
+ public static final String PATH_MCC_SID_RANGE = "range";
+ public static final String PATH_NANP_AREA_CODE = "nanp";
+ public static final String PATH_ARBITRARY_MCC_SID_MATCH = "arbitrary";
+ public static final String PATH_USERADD_COUNTRY = "useradd";
+
+ public static final String ID = "_id";
+ public static final int IDINDEX = 0;
+
+ /**
+ * @hide
+ */
+ public static class MccIdd implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_MCC_IDD);
+ public static final String DEFAULT_SORT_ORDER = "MCC ASC";
+
+ public static final String MCC = "MCC";
+ public static final String IDD = "IDD";
+
+ }
+
+ /**
+ * @hide
+ */
+ public static class MccLookup implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_MCC_LOOKUP_TABLE);
+ public static final String DEFAULT_SORT_ORDER = "MCC ASC";
+
+ public static final String MCC = "MCC";
+ public static final String COUNTRY_CODE = "Country_Code";
+ public static final String COUNTRY_NAME = "Country_Name";
+ public static final String NDD = "NDD";
+ public static final String NANPS = "NANPS";
+ public static final String GMT_OFFSET_LOW = "GMT_Offset_Low";
+ public static final String GMT_OFFSET_HIGH = "GMT_Offset_High";
+ public static final String GMT_DST_LOW = "GMT_DST_Low";
+ public static final String GMT_DST_HIGH = "GMT_DST_High";
+
+ }
+
+ /**
+ * @hide
+ */
+ public static class MccSidConflicts implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_MCC_SID_CONFLICT);
+ public static final String DEFAULT_SORT_ORDER = "MCC ASC";
+
+ public static final String MCC = "MCC";
+ public static final String SID_CONFLICT = "SID_Conflict";
+
+ }
+
+ /**
+ * @hide
+ */
+ public static class MccSidRange implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_MCC_SID_RANGE);
+ public static final String DEFAULT_SORT_ORDER = "MCC ASC";
+
+ public static final String MCC = "MCC";
+ public static final String RANGE_LOW = "SID_Range_Low";
+ public static final String RANGE_HIGH = "SID_Range_High";
+ }
+
+ /**
+ * @hide
+ */
+ public static class ArbitraryMccSidMatch implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_ARBITRARY_MCC_SID_MATCH);
+ public static final String DEFAULT_SORT_ORDER = "MCC ASC";
+
+ public static final String MCC = "MCC";
+ public static final String SID = "SID";
+
+ }
+
+ /**
+ * @hide
+ */
+ public static class NanpAreaCode implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_NANP_AREA_CODE);
+ public static final String DEFAULT_SORT_ORDER = "Area_Code ASC";
+
+ public static final String AREA_CODE = "Area_Code";
+ }
+}
diff --git a/telephony/common/com/android/internal/telephony/HbpcdUtils.java b/telephony/common/com/android/internal/telephony/HbpcdUtils.java
new file mode 100644
index 000000000000..2f3194214be6
--- /dev/null
+++ b/telephony/common/com/android/internal/telephony/HbpcdUtils.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2014 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.telephony;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.telephony.Rlog;
+
+import com.android.internal.telephony.HbpcdLookup.ArbitraryMccSidMatch;
+import com.android.internal.telephony.HbpcdLookup.MccIdd;
+import com.android.internal.telephony.HbpcdLookup.MccLookup;
+import com.android.internal.telephony.HbpcdLookup.MccSidConflicts;
+import com.android.internal.telephony.HbpcdLookup.MccSidRange;
+
+public final class HbpcdUtils {
+ private static final String LOG_TAG = "HbpcdUtils";
+ private static final boolean DBG = false;
+ private ContentResolver resolver = null;
+
+ public HbpcdUtils(Context context) {
+ resolver = context.getContentResolver();
+ }
+
+ /**
+ * Resolves the unknown MCC with SID and Timezone information.
+ */
+ public int getMcc(int sid, int tz, int DSTflag, boolean isNitzTimeZone) {
+ int tmpMcc = 0;
+
+ // check if SID exists in arbitrary_mcc_sid_match table.
+ // these SIDs are assigned to more than 1 operators, but they are known to
+ // be used by a specific operator, other operators having the same SID are
+ // not using it currently, if that SID is in this table, we don't need to
+ // check other tables.
+ String projection2[] = {ArbitraryMccSidMatch.MCC};
+ Cursor c2 = resolver.query(ArbitraryMccSidMatch.CONTENT_URI, projection2,
+ ArbitraryMccSidMatch.SID + "=" + sid, null, null);
+
+ if (c2 != null) {
+ int c2Counter = c2.getCount();
+ if (DBG) {
+ Rlog.d(LOG_TAG, "Query unresolved arbitrary table, entries are " + c2Counter);
+ }
+ if (c2Counter == 1) {
+ if (DBG) {
+ Rlog.d(LOG_TAG, "Query Unresolved arbitrary returned the cursor " + c2);
+ }
+ c2.moveToFirst();
+ tmpMcc = c2.getInt(0);
+ if (DBG) {
+ Rlog.d(LOG_TAG, "MCC found in arbitrary_mcc_sid_match: " + tmpMcc);
+ }
+ c2.close();
+ return tmpMcc;
+ }
+ c2.close();
+ }
+
+ // Then check if SID exists in mcc_sid_conflict table.
+ // and use the timezone in mcc_lookup table to check which MCC matches.
+ String projection3[] = {MccSidConflicts.MCC};
+ Cursor c3 = resolver.query(MccSidConflicts.CONTENT_URI, projection3,
+ MccSidConflicts.SID_CONFLICT + "=" + sid + " and (((" +
+ MccLookup.GMT_OFFSET_LOW + "<=" + tz + ") and (" + tz + "<=" +
+ MccLookup.GMT_OFFSET_HIGH + ") and (" + "0=" + DSTflag + ")) or ((" +
+ MccLookup.GMT_DST_LOW + "<=" + tz + ") and (" + tz + "<=" +
+ MccLookup.GMT_DST_HIGH + ") and (" + "1=" + DSTflag + ")))",
+ null, null);
+ if (c3 != null) {
+ int c3Counter = c3.getCount();
+ if (c3Counter > 0) {
+ if (c3Counter > 1) {
+ Rlog.w(LOG_TAG, "something wrong, get more results for 1 conflict SID: " + c3);
+ }
+ if (DBG) Rlog.d(LOG_TAG, "Query conflict sid returned the cursor " + c3);
+ c3.moveToFirst();
+ tmpMcc = c3.getInt(0);
+ if (DBG) {
+ Rlog.d(LOG_TAG, "MCC found in mcc_lookup_table. Return tmpMcc = " + tmpMcc);
+ }
+ if (!isNitzTimeZone) {
+ // time zone is not accurate, it may get wrong mcc, ignore it.
+ if (DBG) {
+ Rlog.d(LOG_TAG, "time zone is not accurate, mcc may be " + tmpMcc);
+ }
+ tmpMcc = 0;
+ }
+ c3.close();
+ return tmpMcc;
+ } else {
+ c3.close();
+ }
+ }
+
+ // if there is no conflict, then check if SID is in mcc_sid_range.
+ String projection5[] = {MccSidRange.MCC};
+ Cursor c5 = resolver.query(MccSidRange.CONTENT_URI, projection5,
+ MccSidRange.RANGE_LOW + "<=" + sid + " and " +
+ MccSidRange.RANGE_HIGH + ">=" + sid,
+ null, null);
+ if (c5 != null) {
+ if (c5.getCount() > 0) {
+ if (DBG) Rlog.d(LOG_TAG, "Query Range returned the cursor " + c5);
+ c5.moveToFirst();
+ tmpMcc = c5.getInt(0);
+ if (DBG) Rlog.d(LOG_TAG, "SID found in mcc_sid_range. Return tmpMcc = " + tmpMcc);
+ c5.close();
+ return tmpMcc;
+ }
+ c5.close();
+ }
+ if (DBG) Rlog.d(LOG_TAG, "SID NOT found in mcc_sid_range.");
+
+ if (DBG) Rlog.d(LOG_TAG, "Exit getMccByOtherFactors. Return tmpMcc = " + tmpMcc);
+ // If unknown MCC still could not be resolved,
+ return tmpMcc;
+ }
+
+ /**
+ * Gets country information with given MCC.
+ */
+ public String getIddByMcc(int mcc) {
+ if (DBG) Rlog.d(LOG_TAG, "Enter getHbpcdInfoByMCC.");
+ String idd = "";
+
+ Cursor c = null;
+
+ String projection[] = {MccIdd.IDD};
+ Cursor cur = resolver.query(MccIdd.CONTENT_URI, projection,
+ MccIdd.MCC + "=" + mcc, null, null);
+ if (cur != null) {
+ if (cur.getCount() > 0) {
+ if (DBG) Rlog.d(LOG_TAG, "Query Idd returned the cursor " + cur);
+ // TODO: for those country having more than 1 IDDs, need more information
+ // to decide which IDD would be used. currently just use the first 1.
+ cur.moveToFirst();
+ idd = cur.getString(0);
+ if (DBG) Rlog.d(LOG_TAG, "IDD = " + idd);
+
+ }
+ cur.close();
+ }
+ if (c != null) c.close();
+
+ if (DBG) Rlog.d(LOG_TAG, "Exit getHbpcdInfoByMCC.");
+ return idd;
+ }
+}
diff --git a/telephony/common/com/android/internal/telephony/SmsNumberUtils.java b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
new file mode 100644
index 000000000000..0d33af639113
--- /dev/null
+++ b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
@@ -0,0 +1,627 @@
+/*
+ * Copyright (C) 2014 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.telephony;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.os.Binder;
+import android.os.Build;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.Rlog;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.android.internal.telephony.HbpcdLookup.MccIdd;
+import com.android.internal.telephony.HbpcdLookup.MccLookup;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+
+/**
+ * This class implements handle the MO SMS target address before sending.
+ * This is special for VZW requirement. Follow the specifications of assisted dialing
+ * of MO SMS while traveling on VZW CDMA, international CDMA or GSM markets.
+ * {@hide}
+ */
+public class SmsNumberUtils {
+ private static final String TAG = "SmsNumberUtils";
+ private static final boolean DBG = Build.IS_DEBUGGABLE;
+
+ private static final String PLUS_SIGN = "+";
+
+ private static final int NANP_SHORT_LENGTH = 7;
+ private static final int NANP_MEDIUM_LENGTH = 10;
+ private static final int NANP_LONG_LENGTH = 11;
+
+ private static final int NANP_CC = 1;
+ private static final String NANP_NDD = "1";
+ private static final String NANP_IDD = "011";
+
+ private static final int MIN_COUNTRY_AREA_LOCAL_LENGTH = 10;
+
+ private static final int GSM_UMTS_NETWORK = 0;
+ private static final int CDMA_HOME_NETWORK = 1;
+ private static final int CDMA_ROAMING_NETWORK = 2;
+
+ private static final int NP_NONE = 0;
+ private static final int NP_NANP_BEGIN = 1;
+
+ /* <Phone Number>, <NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_LOCAL = NP_NANP_BEGIN;
+
+ /* <Area_code>-<Phone Number>, <NXX>-<NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_AREA_LOCAL = NP_NANP_BEGIN + 1;
+
+ /* <1>-<Area_code>-<Phone Number>, 1-<NXX>-<NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_NDD_AREA_LOCAL = NP_NANP_BEGIN + 2;
+
+ /* <+><U.S.Country_code><Area_code><Phone Number>, +1-<NXX>-<NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_NBPCD_CC_AREA_LOCAL = NP_NANP_BEGIN + 3;
+
+ /* <Local_IDD><Country_code><Area_code><Phone Number>, 001-1-<NXX>-<NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_LOCALIDD_CC_AREA_LOCAL = NP_NANP_BEGIN + 4;
+
+ /* <+><Home_IDD><Country_code><Area_code><Phone Number>, +011-1-<NXX>-<NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL = NP_NANP_BEGIN + 5;
+
+ private static final int NP_INTERNATIONAL_BEGIN = 100;
+ /* <+>-<Home_IDD>-<Country_code>-<Area_code>-<Phone Number>, +011-86-25-86281234 */
+ private static final int NP_NBPCD_HOMEIDD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN;
+
+ /* <Home_IDD>-<Country_code>-<Area_code>-<Phone Number>, 011-86-25-86281234 */
+ private static final int NP_HOMEIDD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 1;
+
+ /* <NBPCD>-<Country_code>-<Area_code>-<Phone Number>, +1-86-25-86281234 */
+ private static final int NP_NBPCD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 2;
+
+ /* <Local_IDD>-<Country_code>-<Area_code>-<Phone Number>, 00-86-25-86281234 */
+ private static final int NP_LOCALIDD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 3;
+
+ /* <Country_code>-<Area_code>-<Phone Number>, 86-25-86281234*/
+ private static final int NP_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 4;
+
+ private static int[] ALL_COUNTRY_CODES = null;
+ private static int MAX_COUNTRY_CODES_LENGTH;
+ private static HashMap<String, ArrayList<String>> IDDS_MAPS =
+ new HashMap<String, ArrayList<String>>();
+
+ private static class NumberEntry {
+ public String number;
+ public String IDD;
+ public int countryCode;
+ public NumberEntry(String number) {
+ this.number = number;
+ }
+ }
+
+ /**
+ * Breaks the given number down and formats it according to the rules
+ * for different number plans and different network.
+ *
+ * @param number destination number which need to be format
+ * @param activeMcc current network's mcc
+ * @param networkType current network type
+ *
+ * @return the number after formatting.
+ */
+ private static String formatNumber(Context context, String number,
+ String activeMcc,
+ int networkType) {
+ if (number == null ) {
+ throw new IllegalArgumentException("number is null");
+ }
+
+ if (activeMcc == null || activeMcc.trim().length() == 0) {
+ throw new IllegalArgumentException("activeMcc is null or empty!");
+ }
+
+ String networkPortionNumber = PhoneNumberUtils.extractNetworkPortion(number);
+ if (networkPortionNumber == null || networkPortionNumber.length() == 0) {
+ throw new IllegalArgumentException("Number is invalid!");
+ }
+
+ NumberEntry numberEntry = new NumberEntry(networkPortionNumber);
+ ArrayList<String> allIDDs = getAllIDDs(context, activeMcc);
+
+ // First check whether the number is a NANP number.
+ int nanpState = checkNANP(numberEntry, allIDDs);
+ if (DBG) Rlog.d(TAG, "NANP type: " + getNumberPlanType(nanpState));
+
+ if ((nanpState == NP_NANP_LOCAL)
+ || (nanpState == NP_NANP_AREA_LOCAL)
+ || (nanpState == NP_NANP_NDD_AREA_LOCAL)) {
+ return networkPortionNumber;
+ } else if (nanpState == NP_NANP_NBPCD_CC_AREA_LOCAL) {
+ if (networkType == CDMA_HOME_NETWORK
+ || networkType == CDMA_ROAMING_NETWORK) {
+ // Remove "+"
+ return networkPortionNumber.substring(1);
+ } else {
+ return networkPortionNumber;
+ }
+ } else if (nanpState == NP_NANP_LOCALIDD_CC_AREA_LOCAL) {
+ if (networkType == CDMA_HOME_NETWORK) {
+ return networkPortionNumber;
+ } else if (networkType == GSM_UMTS_NETWORK) {
+ // Remove the local IDD and replace with "+"
+ int iddLength = numberEntry.IDD != null ? numberEntry.IDD.length() : 0;
+ return PLUS_SIGN + networkPortionNumber.substring(iddLength);
+ } else if (networkType == CDMA_ROAMING_NETWORK) {
+ // Remove the local IDD
+ int iddLength = numberEntry.IDD != null ? numberEntry.IDD.length() : 0;
+ return networkPortionNumber.substring(iddLength);
+ }
+ }
+
+ int internationalState = checkInternationalNumberPlan(context, numberEntry, allIDDs,
+ NANP_IDD);
+ if (DBG) Rlog.d(TAG, "International type: " + getNumberPlanType(internationalState));
+ String returnNumber = null;
+
+ switch (internationalState) {
+ case NP_NBPCD_HOMEIDD_CC_AREA_LOCAL:
+ if (networkType == GSM_UMTS_NETWORK) {
+ // Remove "+"
+ returnNumber = networkPortionNumber.substring(1);
+ }
+ break;
+
+ case NP_NBPCD_CC_AREA_LOCAL:
+ // Replace "+" with "011"
+ returnNumber = NANP_IDD + networkPortionNumber.substring(1);
+ break;
+
+ case NP_LOCALIDD_CC_AREA_LOCAL:
+ if (networkType == GSM_UMTS_NETWORK || networkType == CDMA_ROAMING_NETWORK) {
+ int iddLength = numberEntry.IDD != null ? numberEntry.IDD.length() : 0;
+ // Replace <Local IDD> to <Home IDD>("011")
+ returnNumber = NANP_IDD + networkPortionNumber.substring(iddLength);
+ }
+ break;
+
+ case NP_CC_AREA_LOCAL:
+ int countryCode = numberEntry.countryCode;
+
+ if (!inExceptionListForNpCcAreaLocal(numberEntry)
+ && networkPortionNumber.length() >= 11 && countryCode != NANP_CC) {
+ // Add "011"
+ returnNumber = NANP_IDD + networkPortionNumber;
+ }
+ break;
+
+ case NP_HOMEIDD_CC_AREA_LOCAL:
+ returnNumber = networkPortionNumber;
+ break;
+
+ default:
+ // Replace "+" with 011 in CDMA network if the number's country
+ // code is not in the HbpcdLookup database.
+ if (networkPortionNumber.startsWith(PLUS_SIGN)
+ && (networkType == CDMA_HOME_NETWORK || networkType == CDMA_ROAMING_NETWORK)) {
+ if (networkPortionNumber.startsWith(PLUS_SIGN + NANP_IDD)) {
+ // Only remove "+"
+ returnNumber = networkPortionNumber.substring(1);
+ } else {
+ // Replace "+" with "011"
+ returnNumber = NANP_IDD + networkPortionNumber.substring(1);
+ }
+ }
+ }
+
+ if (returnNumber == null) {
+ returnNumber = networkPortionNumber;
+ }
+ return returnNumber;
+ }
+
+ /**
+ * Query International direct dialing from HbpcdLookup.db
+ * for specified country code
+ *
+ * @param mcc current network's country code
+ *
+ * @return the IDD array list.
+ */
+ private static ArrayList<String> getAllIDDs(Context context, String mcc) {
+ ArrayList<String> allIDDs = IDDS_MAPS.get(mcc);
+ if (allIDDs != null) {
+ return allIDDs;
+ } else {
+ allIDDs = new ArrayList<String>();
+ }
+
+ String projection[] = {MccIdd.IDD, MccIdd.MCC};
+ String where = null;
+
+ // if mcc is null : return all rows
+ // if mcc is empty-string : return those rows whose mcc is emptry-string
+ String[] selectionArgs = null;
+ if (mcc != null) {
+ where = MccIdd.MCC + "=?";
+ selectionArgs = new String[] {mcc};
+ }
+
+ Cursor cursor = null;
+ try {
+ cursor = context.getContentResolver().query(MccIdd.CONTENT_URI, projection,
+ where, selectionArgs, null);
+ if (cursor.getCount() > 0) {
+ while (cursor.moveToNext()) {
+ String idd = cursor.getString(0);
+ if (!allIDDs.contains(idd)) {
+ allIDDs.add(idd);
+ }
+ }
+ }
+ } catch (SQLException e) {
+ Rlog.e(TAG, "Can't access HbpcdLookup database", e);
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+
+ IDDS_MAPS.put(mcc, allIDDs);
+
+ if (DBG) Rlog.d(TAG, "MCC = " + mcc + ", all IDDs = " + allIDDs);
+ return allIDDs;
+ }
+
+
+ /**
+ * Verify if the the destination number is a NANP number
+ *
+ * @param numberEntry including number and IDD array
+ * @param allIDDs the IDD array list of the current network's country code
+ *
+ * @return the number plan type related NANP
+ */
+ private static int checkNANP(NumberEntry numberEntry, ArrayList<String> allIDDs) {
+ boolean isNANP = false;
+ String number = numberEntry.number;
+
+ if (number.length() == NANP_SHORT_LENGTH) {
+ // 7 digits - Seven digit phone numbers
+ char firstChar = number.charAt(0);
+ if (firstChar >= '2' && firstChar <= '9') {
+ isNANP = true;
+ for (int i=1; i< NANP_SHORT_LENGTH; i++ ) {
+ char c= number.charAt(i);
+ if (!PhoneNumberUtils.isISODigit(c)) {
+ isNANP = false;
+ break;
+ }
+ }
+ }
+ if (isNANP) {
+ return NP_NANP_LOCAL;
+ }
+ } else if (number.length() == NANP_MEDIUM_LENGTH) {
+ // 10 digits - Three digit area code followed by seven digit phone numbers/
+ if (isNANP(number)) {
+ return NP_NANP_AREA_LOCAL;
+ }
+ } else if (number.length() == NANP_LONG_LENGTH) {
+ // 11 digits - One digit U.S. NDD(National Direct Dial) prefix '1',
+ // followed by three digit area code and seven digit phone numbers
+ if (isNANP(number)) {
+ return NP_NANP_NDD_AREA_LOCAL;
+ }
+ } else if (number.startsWith(PLUS_SIGN)) {
+ number = number.substring(1);
+ if (number.length() == NANP_LONG_LENGTH) {
+ // '+' and 11 digits -'+', followed by NANP CC prefix '1' followed by
+ // three digit area code and seven digit phone numbers
+ if (isNANP(number)) {
+ return NP_NANP_NBPCD_CC_AREA_LOCAL;
+ }
+ } else if (number.startsWith(NANP_IDD) && number.length() == NANP_LONG_LENGTH + 3) {
+ // '+' and 14 digits -'+', followed by NANP IDD "011" followed by NANP CC
+ // prefix '1' followed by three digit area code and seven digit phone numbers
+ number = number.substring(3);
+ if (isNANP(number)) {
+ return NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL;
+ }
+ }
+ } else {
+ // Check whether it's NP_NANP_LOCALIDD_CC_AREA_LOCAL
+ for (String idd : allIDDs) {
+ if (number.startsWith(idd)) {
+ String number2 = number.substring(idd.length());
+ if(number2 !=null && number2.startsWith(String.valueOf(NANP_CC))){
+ if (isNANP(number2)) {
+ numberEntry.IDD = idd;
+ return NP_NANP_LOCALIDD_CC_AREA_LOCAL;
+ }
+ }
+ }
+ }
+ }
+
+ return NP_NONE;
+ }
+
+ private static boolean isNANP(String number) {
+ if (number.length() == NANP_MEDIUM_LENGTH
+ || (number.length() == NANP_LONG_LENGTH && number.startsWith(NANP_NDD))) {
+ if (number.length() == NANP_LONG_LENGTH) {
+ number = number.substring(1);
+ }
+ return (PhoneNumberUtils.isNanp(number));
+ }
+ return false;
+ }
+
+ /**
+ * Verify if the the destination number is an internal number
+ *
+ * @param numberEntry including number and IDD array
+ * @param allIDDs the IDD array list of the current network's country code
+ *
+ * @return the number plan type related international number
+ */
+ private static int checkInternationalNumberPlan(Context context, NumberEntry numberEntry,
+ ArrayList<String> allIDDs,String homeIDD) {
+ String number = numberEntry.number;
+ int countryCode = -1;
+
+ if (number.startsWith(PLUS_SIGN)) {
+ // +xxxxxxxxxx
+ String numberNoNBPCD = number.substring(1);
+ if (numberNoNBPCD.startsWith(homeIDD)) {
+ // +011xxxxxxxx
+ String numberCountryAreaLocal = numberNoNBPCD.substring(homeIDD.length());
+ if ((countryCode = getCountryCode(context, numberCountryAreaLocal)) > 0) {
+ numberEntry.countryCode = countryCode;
+ return NP_NBPCD_HOMEIDD_CC_AREA_LOCAL;
+ }
+ } else if ((countryCode = getCountryCode(context, numberNoNBPCD)) > 0) {
+ numberEntry.countryCode = countryCode;
+ return NP_NBPCD_CC_AREA_LOCAL;
+ }
+
+ } else if (number.startsWith(homeIDD)) {
+ // 011xxxxxxxxx
+ String numberCountryAreaLocal = number.substring(homeIDD.length());
+ if ((countryCode = getCountryCode(context, numberCountryAreaLocal)) > 0) {
+ numberEntry.countryCode = countryCode;
+ return NP_HOMEIDD_CC_AREA_LOCAL;
+ }
+ } else {
+ for (String exitCode : allIDDs) {
+ if (number.startsWith(exitCode)) {
+ String numberNoIDD = number.substring(exitCode.length());
+ if ((countryCode = getCountryCode(context, numberNoIDD)) > 0) {
+ numberEntry.countryCode = countryCode;
+ numberEntry.IDD = exitCode;
+ return NP_LOCALIDD_CC_AREA_LOCAL;
+ }
+ }
+ }
+
+ if (!number.startsWith("0") && (countryCode = getCountryCode(context, number)) > 0) {
+ numberEntry.countryCode = countryCode;
+ return NP_CC_AREA_LOCAL;
+ }
+ }
+ return NP_NONE;
+ }
+
+ /**
+ * Returns the country code from the given number.
+ */
+ private static int getCountryCode(Context context, String number) {
+ int countryCode = -1;
+ if (number.length() >= MIN_COUNTRY_AREA_LOCAL_LENGTH) {
+ // Check Country code
+ int[] allCCs = getAllCountryCodes(context);
+ if (allCCs == null) {
+ return countryCode;
+ }
+
+ int[] ccArray = new int[MAX_COUNTRY_CODES_LENGTH];
+ for (int i = 0; i < MAX_COUNTRY_CODES_LENGTH; i ++) {
+ ccArray[i] = Integer.parseInt(number.substring(0, i+1));
+ }
+
+ for (int i = 0; i < allCCs.length; i ++) {
+ int tempCC = allCCs[i];
+ for (int j = 0; j < MAX_COUNTRY_CODES_LENGTH; j ++) {
+ if (tempCC == ccArray[j]) {
+ if (DBG) Rlog.d(TAG, "Country code = " + tempCC);
+ return tempCC;
+ }
+ }
+ }
+ }
+
+ return countryCode;
+ }
+
+ /**
+ * Gets all country Codes information with given MCC.
+ */
+ private static int[] getAllCountryCodes(Context context) {
+ if (ALL_COUNTRY_CODES != null) {
+ return ALL_COUNTRY_CODES;
+ }
+
+ Cursor cursor = null;
+ try {
+ String projection[] = {MccLookup.COUNTRY_CODE};
+ cursor = context.getContentResolver().query(MccLookup.CONTENT_URI,
+ projection, null, null, null);
+
+ if (cursor.getCount() > 0) {
+ ALL_COUNTRY_CODES = new int[cursor.getCount()];
+ int i = 0;
+ while (cursor.moveToNext()) {
+ int countryCode = cursor.getInt(0);
+ ALL_COUNTRY_CODES[i++] = countryCode;
+ int length = String.valueOf(countryCode).trim().length();
+ if (length > MAX_COUNTRY_CODES_LENGTH) {
+ MAX_COUNTRY_CODES_LENGTH = length;
+ }
+ }
+ }
+ } catch (SQLException e) {
+ Rlog.e(TAG, "Can't access HbpcdLookup database", e);
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ return ALL_COUNTRY_CODES;
+ }
+
+ private static boolean inExceptionListForNpCcAreaLocal(NumberEntry numberEntry) {
+ int countryCode = numberEntry.countryCode;
+ boolean result = (numberEntry.number.length() == 12
+ && (countryCode == 7 || countryCode == 20
+ || countryCode == 65 || countryCode == 90));
+ return result;
+ }
+
+ private static String getNumberPlanType(int state) {
+ String numberPlanType = "Number Plan type (" + state + "): ";
+
+ if (state == NP_NANP_LOCAL) {
+ numberPlanType = "NP_NANP_LOCAL";
+ } else if (state == NP_NANP_AREA_LOCAL) {
+ numberPlanType = "NP_NANP_AREA_LOCAL";
+ } else if (state == NP_NANP_NDD_AREA_LOCAL) {
+ numberPlanType = "NP_NANP_NDD_AREA_LOCAL";
+ } else if (state == NP_NANP_NBPCD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_NANP_NBPCD_CC_AREA_LOCAL";
+ } else if (state == NP_NANP_LOCALIDD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_NANP_LOCALIDD_CC_AREA_LOCAL";
+ } else if (state == NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL";
+ } else if (state == NP_NBPCD_HOMEIDD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_NBPCD_HOMEIDD_CC_AREA_LOCAL";
+ } else if (state == NP_HOMEIDD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_HOMEIDD_CC_AREA_LOCAL";
+ } else if (state == NP_NBPCD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_NBPCD_CC_AREA_LOCAL";
+ } else if (state == NP_LOCALIDD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_LOCALIDD_CC_AREA_LOCAL";
+ } else if (state == NP_CC_AREA_LOCAL) {
+ numberPlanType = "NP_CC_AREA_LOCAL";
+ } else {
+ numberPlanType = "Unknown type";
+ }
+ return numberPlanType;
+ }
+
+ /**
+ * Filter the destination number if using VZW sim card.
+ */
+ public static String filterDestAddr(Context context, int subId, String destAddr) {
+ if (DBG) Rlog.d(TAG, "enter filterDestAddr. destAddr=\"" + Rlog.pii(TAG, destAddr) + "\"" );
+
+ if (destAddr == null || !PhoneNumberUtils.isGlobalPhoneNumber(destAddr)) {
+ Rlog.w(TAG, "destAddr" + Rlog.pii(TAG, destAddr) +
+ " is not a global phone number! Nothing changed.");
+ return destAddr;
+ }
+
+ final TelephonyManager telephonyManager = ((TelephonyManager) context
+ .getSystemService(Context.TELEPHONY_SERVICE)).createForSubscriptionId(subId);
+ final String networkOperator = telephonyManager.getNetworkOperator();
+ String result = null;
+
+ if (needToConvert(context, subId)) {
+ final int networkType = getNetworkType(telephonyManager);
+ if (networkType != -1 && !TextUtils.isEmpty(networkOperator)) {
+ String networkMcc = networkOperator.substring(0, 3);
+ if (networkMcc != null && networkMcc.trim().length() > 0) {
+ result = formatNumber(context, destAddr, networkMcc, networkType);
+ }
+ }
+ }
+
+ if (DBG) {
+ Rlog.d(TAG, "destAddr is " + ((result != null)?"formatted.":"not formatted."));
+ Rlog.d(TAG, "leave filterDestAddr, new destAddr=\"" + (result != null ? Rlog.pii(TAG,
+ result) : Rlog.pii(TAG, destAddr)) + "\"");
+ }
+ return result != null ? result : destAddr;
+ }
+
+ /**
+ * Returns the current network type
+ */
+ private static int getNetworkType(TelephonyManager telephonyManager) {
+ int networkType = -1;
+ int phoneType = telephonyManager.getPhoneType();
+
+ if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+ networkType = GSM_UMTS_NETWORK;
+ } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+ if (isInternationalRoaming(telephonyManager)) {
+ networkType = CDMA_ROAMING_NETWORK;
+ } else {
+ networkType = CDMA_HOME_NETWORK;
+ }
+ } else {
+ if (DBG) Rlog.w(TAG, "warning! unknown mPhoneType value=" + phoneType);
+ }
+
+ return networkType;
+ }
+
+ private static boolean isInternationalRoaming(TelephonyManager telephonyManager) {
+ String operatorIsoCountry = telephonyManager.getNetworkCountryIso();
+ String simIsoCountry = telephonyManager.getSimCountryIso();
+ boolean internationalRoaming = !TextUtils.isEmpty(operatorIsoCountry)
+ && !TextUtils.isEmpty(simIsoCountry)
+ && !simIsoCountry.equals(operatorIsoCountry);
+ if (internationalRoaming) {
+ if ("us".equals(simIsoCountry)) {
+ internationalRoaming = !"vi".equals(operatorIsoCountry);
+ } else if ("vi".equals(simIsoCountry)) {
+ internationalRoaming = !"us".equals(operatorIsoCountry);
+ }
+ }
+ return internationalRoaming;
+ }
+
+ private static boolean needToConvert(Context context, int subId) {
+ // Calling package may not have READ_PHONE_STATE which is required for getConfig().
+ // Clear the calling identity so that it is called as self.
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager != null) {
+ PersistableBundle bundle = configManager.getConfigForSubId(subId);
+ if (bundle != null) {
+ return bundle.getBoolean(CarrierConfigManager
+ .KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ // by default this value is false
+ return false;
+ }
+}
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 67b252e52db9..bc29b595b0bb 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -3962,13 +3962,21 @@ public final class Telephony {
public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts");
/**
- * The id of the subscription which received this cell broadcast message.
+ * The subscription which received this cell broadcast message.
+ * @deprecated use {@link #SLOT_INDEX} instead.
* <P>Type: INTEGER</P>
* @hide
*/
public static final String SUB_ID = "sub_id";
/**
+ * The slot which received this cell broadcast message.
+ * <P>Type: INTEGER</P>
+ * @hide
+ */
+ public static final String SLOT_INDEX = "slot_index";
+
+ /**
* Message geographical scope. Valid values are:
* <ul>
* <li>{@link android.telephony.SmsCbMessage#GEOGRAPHICAL_SCOPE_CELL_WIDE}. meaning the
@@ -4202,7 +4210,7 @@ public final class Telephony {
public static final String MAXIMUM_WAIT_TIME = "maximum_wait_time";
/**
- * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
+ * Query columns for instantiating com.android.cellbroadcastreceiver.CellBroadcastMessage.
* @hide
*/
@NonNull
@@ -4235,6 +4243,7 @@ public final class Telephony {
*/
public static final String[] QUERY_COLUMNS_FWK = {
_ID,
+ SLOT_INDEX,
GEOGRAPHICAL_SCOPE,
PLMN,
LAC,
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 8587be7579e6..1d00b4f51fdc 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -963,6 +963,9 @@ public class ServiceState implements Parcelable {
case RIL_RADIO_TECHNOLOGY_LTE_CA:
rtString = "LTE_CA";
break;
+ case RIL_RADIO_TECHNOLOGY_NR:
+ rtString = "LTE_NR";
+ break;
default:
rtString = "Unexpected";
Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
@@ -1529,6 +1532,7 @@ public class ServiceState implements Parcelable {
return AccessNetworkType.CDMA2000;
case RIL_RADIO_TECHNOLOGY_LTE:
case RIL_RADIO_TECHNOLOGY_LTE_CA:
+ case RIL_RADIO_TECHNOLOGY_NR:
return AccessNetworkType.EUTRAN;
case RIL_RADIO_TECHNOLOGY_IWLAN:
return AccessNetworkType.IWLAN;
@@ -1577,6 +1581,8 @@ public class ServiceState implements Parcelable {
return ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
case TelephonyManager.NETWORK_TYPE_LTE_CA:
return ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA;
+ case TelephonyManager.NETWORK_TYPE_NR:
+ return ServiceState.RIL_RADIO_TECHNOLOGY_NR;
default:
return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
}
@@ -1667,7 +1673,8 @@ public class ServiceState implements Parcelable {
|| radioTechnology == RIL_RADIO_TECHNOLOGY_GSM
|| radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA
|| radioTechnology == RIL_RADIO_TECHNOLOGY_IWLAN
- || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA;
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_NR;
}
diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java
index c078764cfa24..dc991b9a3ea7 100644
--- a/telephony/java/android/telephony/SmsCbMessage.java
+++ b/telephony/java/android/telephony/SmsCbMessage.java
@@ -207,17 +207,19 @@ public final class SmsCbMessage implements Parcelable {
/** CMAS warning area coordinates. */
private final List<Geometry> mGeometries;
+ private int mSlotIndex = 0;
+
/**
* Create a new SmsCbMessage with the specified data.
*/
public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
@NonNull SmsCbLocation location, int serviceCategory, @Nullable String language,
@Nullable String body, int priority, @Nullable SmsCbEtwsInfo etwsWarningInfo,
- @Nullable SmsCbCmasInfo cmasWarningInfo) {
+ @Nullable SmsCbCmasInfo cmasWarningInfo, int slotIndex) {
this(messageFormat, geographicalScope, serialNumber, location, serviceCategory, language,
body, priority, etwsWarningInfo, cmasWarningInfo, 0 /* maximumWaitingTime */,
- null /* geometries */, System.currentTimeMillis());
+ null /* geometries */, System.currentTimeMillis(), slotIndex);
}
/**
@@ -227,7 +229,8 @@ public final class SmsCbMessage implements Parcelable {
public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
SmsCbLocation location, int serviceCategory, String language, String body,
int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo,
- int maximumWaitTimeSec, List<Geometry> geometries, long receivedTimeMillis) {
+ int maximumWaitTimeSec, List<Geometry> geometries, long receivedTimeMillis,
+ int slotIndex) {
mMessageFormat = messageFormat;
mGeographicalScope = geographicalScope;
mSerialNumber = serialNumber;
@@ -241,6 +244,7 @@ public final class SmsCbMessage implements Parcelable {
mReceivedTimeMillis = receivedTimeMillis;
mGeometries = geometries;
mMaximumWaitTimeSec = maximumWaitTimeSec;
+ mSlotIndex = slotIndex;
}
/**
@@ -278,6 +282,7 @@ public final class SmsCbMessage implements Parcelable {
String geoStr = in.readString();
mGeometries = geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null;
mMaximumWaitTimeSec = in.readInt();
+ mSlotIndex = in.readInt();
}
/**
@@ -312,6 +317,7 @@ public final class SmsCbMessage implements Parcelable {
dest.writeString(
mGeometries != null ? CbGeoUtils.encodeGeometriesToString(mGeometries) : null);
dest.writeInt(mMaximumWaitTimeSec);
+ dest.writeInt(mSlotIndex);
}
@NonNull
@@ -423,6 +429,14 @@ public final class SmsCbMessage implements Parcelable {
}
/**
+ * Get the slotIndex associated with this message.
+ * @return the slotIndex associated with this message
+ */
+ public int getSlotIndex() {
+ return mSlotIndex;
+ }
+
+ /**
* Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}).
* @return an integer representing 3GPP or 3GPP2 message format
*/
@@ -502,6 +516,7 @@ public final class SmsCbMessage implements Parcelable {
+ (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "")
+ (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "")
+ ", maximumWaitingTime = " + mMaximumWaitTimeSec
+ + ", slotIndex = " + mSlotIndex
+ ", geo=" + (mGeometries != null
? CbGeoUtils.encodeGeometriesToString(mGeometries) : "null")
+ '}';
@@ -522,6 +537,7 @@ public final class SmsCbMessage implements Parcelable {
@NonNull
public ContentValues getContentValues() {
ContentValues cv = new ContentValues(16);
+ cv.put(CellBroadcasts.SLOT_INDEX, mSlotIndex);
cv.put(CellBroadcasts.GEOGRAPHICAL_SCOPE, mGeographicalScope);
if (mLocation.getPlmn() != null) {
cv.put(CellBroadcasts.PLMN, mLocation.getPlmn());
@@ -563,6 +579,7 @@ public final class SmsCbMessage implements Parcelable {
}
cv.put(CellBroadcasts.MAXIMUM_WAIT_TIME, mMaximumWaitTimeSec);
+ cv.put(CellBroadcasts.SLOT_INDEX, mSlotIndex);
return cv;
}
@@ -584,6 +601,7 @@ public final class SmsCbMessage implements Parcelable {
String body = cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BODY));
int format = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_FORMAT));
int priority = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_PRIORITY));
+ int slotIndex = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SLOT_INDEX));
String plmn;
int plmnColumn = cursor.getColumnIndex(CellBroadcasts.PLMN);
@@ -681,7 +699,7 @@ public final class SmsCbMessage implements Parcelable {
return new SmsCbMessage(format, geoScope, serialNum, location, category,
language, body, priority, etwsInfo, cmasInfo, maximumWaitTimeSec, geometries,
- receivedTimeMillis);
+ receivedTimeMillis, slotIndex);
}
/**
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index a89328836e2a..1b876575a742 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2110,19 +2110,6 @@ public class SubscriptionManager {
return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getMaxPhoneCount();
}
- /**
- * When getPhoneCount and getMaxPhoneCount return different value, isValidPhoneId being true
- * doesn't mean the phoneId has a corresponding active slot / logical modem. If a DSDS capable
- * device is in single SIM mode, phoneId=1 is valid but not active.
- *
- * TODO: b/139642279 combine with SubscriptionManager#isValidPhoneId when phone objects
- * are dynamically allocated instead of always based on getMaxPhoneCount.
- * @hide
- */
- public static boolean isActivePhoneId(int slotIndex) {
- return slotIndex < TelephonyManager.getDefault().getPhoneCount();
- }
-
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f3215d4d0e8b..66571e39394e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -70,7 +70,6 @@ import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SimActivationState;
import android.telephony.VisualVoicemailService.VisualVoicemailTask;
-import android.telephony.data.ApnSetting;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
import android.telephony.ims.ImsMmTelManager;
@@ -1172,6 +1171,35 @@ public class TelephonyManager {
"android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
/**
+ * Broadcast intent that indicates multi-SIM configuration is changed. For example, it changed
+ * from single SIM capable to dual-SIM capable (DSDS or DSDA) or triple-SIM mode.
+ *
+ * It doesn't indicate how many subscriptions are actually active, or which states SIMs are,
+ * or that all steps during multi-SIM change are done. To know those information you still need
+ * to listen to SIM_STATE changes or active subscription changes.
+ *
+ * See extra of {@link #EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED} for updated value.
+ */
+ public static final String ACTION_MULTI_SIM_CONFIG_CHANGED =
+ "android.telephony.action.MULTI_SIM_CONFIG_CHANGED";
+
+
+ /**
+ * The number of active SIM supported by current multi-SIM config. It's not related to how many
+ * SIM/subscriptions are currently active.
+ *
+ * For single SIM mode, it's 1.
+ * For DSDS or DSDA mode, it's 2.
+ * For triple-SIM mode, it's 3.
+ *
+ * Extra of {@link #ACTION_MULTI_SIM_CONFIG_CHANGED}.
+ *
+ * type: integer
+ */
+ public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED =
+ "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED";
+
+ /**
* @hide
*/
public static final String USSD_RESPONSE = "USSD_RESPONSE";
@@ -1867,11 +1895,23 @@ public class TelephonyManager {
/**
* Returns the Network Access Identifier (NAI). Return null if NAI is not available.
*
- * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+ * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
+ * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+ * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+ * managed profile on the device; for more details see <a
+ * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+ * access is deprecated and will be removed in a future release.
+ *
+ * <ul>
+ * <li>If the calling app's target SDK is API level 28 or lower and the app has the
+ * READ_PHONE_STATE permission then null is returned.</li>
+ * <li>If the calling app's target SDK is API level 28 or lower and the app does not have
+ * the READ_PHONE_STATE permission, or if the calling app is targeting API level 29 or
+ * higher, then a SecurityException is thrown.</li>
+ * </ul>
*/
- @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
- @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getNai() {
return getNaiBySubscriberId(getSubId());
}
@@ -1879,6 +1919,21 @@ public class TelephonyManager {
/**
* Returns the NAI. Return null if NAI is not available.
*
+ * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
+ * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+ * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+ * managed profile on the device; for more details see <a
+ * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
+ * access is deprecated and will be removed in a future release.
+ *
+ * <ul>
+ * <li>If the calling app's target SDK is API level 28 or lower and the app has the
+ * READ_PHONE_STATE permission then null is returned.</li>
+ * <li>If the calling app's target SDK is API level 28 or lower and the app does not have
+ * the READ_PHONE_STATE permission, or if the calling app is targeting API level 29 or
+ * higher, then a SecurityException is thrown.</li>
+ * </ul>
+ *
* @param slotIndex of which Nai is returned
*/
/** {@hide}*/
@@ -2717,6 +2772,8 @@ public class TelephonyManager {
/** Class of broadly defined "4G" networks. {@hide} */
@UnsupportedAppUsage
public static final int NETWORK_CLASS_4_G = 3;
+ /** Class of broadly defined "5G" networks. {@hide} */
+ public static final int NETWORK_CLASS_5_G = 4;
/**
* Return general class of network type, such as "3G" or "4G". In cases
@@ -2749,6 +2806,8 @@ public class TelephonyManager {
case NETWORK_TYPE_IWLAN:
case NETWORK_TYPE_LTE_CA:
return NETWORK_CLASS_4_G;
+ case NETWORK_TYPE_NR:
+ return NETWORK_CLASS_5_G;
default:
return NETWORK_CLASS_UNKNOWN;
}
@@ -11375,10 +11434,13 @@ public class TelephonyManager {
* 3) APN type is whitelisted. E.g. MMS is whitelisted if
* {@link SubscriptionManager#setAlwaysAllowMmsData} is turned on.
*
+ * @param apnType Value indicating the apn type. Apn types are defined in {@link ApnSetting}.
* @return whether data is enabled for a apn type.
*
* @hide
*/
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean isDataEnabledForApn(@ApnType int apnType) {
String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
try {
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index d892e559c899..4654437fb49c 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -878,8 +878,9 @@ public class SmsMessage extends SmsMessageBase {
* Parses a broadcast SMS, possibly containing a CMAS alert.
*
* @param plmn the PLMN for a broadcast SMS
+ * @param subId
*/
- public SmsCbMessage parseBroadcastSms(String plmn) {
+ public SmsCbMessage parseBroadcastSms(String plmn, int subId) {
BearerData bData = BearerData.decode(mEnvelope.bearerData, mEnvelope.serviceCategory);
if (bData == null) {
Rlog.w(LOG_TAG, "BearerData.decode() returned null");
@@ -895,7 +896,7 @@ public class SmsMessage extends SmsMessageBase {
return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP2,
SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, bData.messageId, location,
mEnvelope.serviceCategory, bData.getLanguage(), bData.userData.payloadStr,
- bData.priority, null, bData.cmasWarningInfo);
+ bData.priority, null, bData.cmasWarningInfo, subId);
}
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index c65c45fa015b..c3d490a6d5cf 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -90,9 +90,10 @@ public class GsmSmsCbMessage {
* Create a new SmsCbMessage object from a header object plus one or more received PDUs.
*
* @param pdus PDU bytes
+ * @slotIndex slotIndex for which received sms cb message
*/
public static SmsCbMessage createSmsCbMessage(Context context, SmsCbHeader header,
- SmsCbLocation location, byte[][] pdus)
+ SmsCbLocation location, byte[][] pdus, int slotIndex)
throws IllegalArgumentException {
long receivedTimeMillis = System.currentTimeMillis();
if (header.isEtwsPrimaryNotification()) {
@@ -104,7 +105,7 @@ public class GsmSmsCbMessage {
header.getSerialNumber(), location, header.getServiceCategory(), null,
getEtwsPrimaryMessage(context, header.getEtwsInfo().getWarningType()),
SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, header.getEtwsInfo(),
- header.getCmasInfo(), 0, null /* geometries */, receivedTimeMillis);
+ header.getCmasInfo(), 0, null /* geometries */, receivedTimeMillis, slotIndex);
} else if (header.isUmtsFormat()) {
// UMTS format has only 1 PDU
byte[] pdu = pdus[0];
@@ -138,7 +139,7 @@ public class GsmSmsCbMessage {
header.getGeographicalScope(), header.getSerialNumber(), location,
header.getServiceCategory(), language, body, priority,
header.getEtwsInfo(), header.getCmasInfo(), maximumWaitingTimeSec, geometries,
- receivedTimeMillis);
+ receivedTimeMillis, slotIndex);
} else {
String language = null;
StringBuilder sb = new StringBuilder();
@@ -154,7 +155,7 @@ public class GsmSmsCbMessage {
header.getGeographicalScope(), header.getSerialNumber(), location,
header.getServiceCategory(), language, sb.toString(), priority,
header.getEtwsInfo(), header.getCmasInfo(), 0, null /* geometries */,
- receivedTimeMillis);
+ receivedTimeMillis, slotIndex);
}
}
diff --git a/tests/Codegen/runTest.sh b/tests/Codegen/runTest.sh
index bb3f5b257897..0e90deaadd61 100755
--- a/tests/Codegen/runTest.sh
+++ b/tests/Codegen/runTest.sh
@@ -16,9 +16,10 @@ else
header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java && \
header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java && \
header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java && \
+ header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java && \
cd $ANDROID_BUILD_TOP &&
header_and_eval mmma -j16 frameworks/base/tests/Codegen && \
- header_and_eval adb install -r -t $ANDROID_PRODUCT_OUT/testcases/CodegenTests/arm64/CodegenTests.apk && \
+ header_and_eval adb install -r -t "$(find $ANDROID_TARGET_OUT_TESTCASES -name 'CodegenTests.apk')" && \
# header_and_eval adb shell am set-debug-app -w com.android.codegentest && \
header_and_eval adb shell am instrument -w -e package com.android.codegentest com.android.codegentest/androidx.test.runner.AndroidJUnitRunner
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
index 9e9ddae4ca76..10eba6a899ad 100644
--- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
@@ -32,7 +32,7 @@ public class HierrarchicalDataClassBase implements Parcelable {
- // Code below generated by codegen v1.0.5.
+ // Code below generated by codegen v1.0.7.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -94,8 +94,8 @@ public class HierrarchicalDataClassBase implements Parcelable {
};
@DataClass.Generated(
- time = 1570231100269L,
- codegenVersion = "1.0.5",
+ time = 1570576455287L,
+ codegenVersion = "1.0.7",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java",
inputSignatures = "private int mBaseData\nclass HierrarchicalDataClassBase extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genSetters=true)")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
index 27a6933d25e8..1085a6a1636a 100644
--- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
@@ -46,7 +46,7 @@ public class HierrarchicalDataClassChild extends HierrarchicalDataClassBase {
- // Code below generated by codegen v1.0.5.
+ // Code below generated by codegen v1.0.7.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -116,8 +116,8 @@ public class HierrarchicalDataClassChild extends HierrarchicalDataClassBase {
};
@DataClass.Generated(
- time = 1570231101208L,
- codegenVersion = "1.0.5",
+ time = 1570576456245L,
+ codegenVersion = "1.0.7",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java",
inputSignatures = "private @android.annotation.NonNull java.lang.String mChildData\nclass HierrarchicalDataClassChild extends com.android.codegentest.HierrarchicalDataClassBase implements []\n@com.android.internal.util.DataClass(genParcelable=true, genConstructor=false, genSetters=true)")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
index dafece17b7ac..75ef963c7995 100644
--- a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
@@ -48,7 +48,7 @@ public class ParcelAllTheThingsDataClass implements Parcelable {
- // Code below generated by codegen v1.0.5.
+ // Code below generated by codegen v1.0.7.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -374,8 +374,8 @@ public class ParcelAllTheThingsDataClass implements Parcelable {
}
@DataClass.Generated(
- time = 1570231099316L,
- codegenVersion = "1.0.5",
+ time = 1570576454326L,
+ codegenVersion = "1.0.7",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java",
inputSignatures = " @android.annotation.NonNull java.lang.String[] mStringArray\n @android.annotation.NonNull int[] mIntArray\n @android.annotation.NonNull java.util.List<java.lang.String> mStringList\n @android.annotation.NonNull java.util.Map<java.lang.String,com.android.codegentest.SampleWithCustomBuilder> mMap\n @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.String> mStringMap\n @android.annotation.NonNull android.util.SparseArray<com.android.codegentest.SampleWithCustomBuilder> mSparseArray\n @android.annotation.NonNull android.util.SparseIntArray mSparseIntArray\nclass ParcelAllTheThingsDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
index 1d737361da6f..14010a9cfb1d 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
@@ -342,7 +342,7 @@ public final class SampleDataClass implements Parcelable {
- // Code below generated by codegen v1.0.5.
+ // Code below generated by codegen v1.0.7.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -1868,8 +1868,8 @@ public final class SampleDataClass implements Parcelable {
}
@DataClass.Generated(
- time = 1570231097226L,
- codegenVersion = "1.0.5",
+ time = 1570576452225L,
+ codegenVersion = "1.0.7",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java",
inputSignatures = "public static final java.lang.String STATE_NAME_UNDEFINED\npublic static final java.lang.String STATE_NAME_ON\npublic static final java.lang.String STATE_NAME_OFF\npublic static final int STATE_UNDEFINED\npublic static final int STATE_ON\npublic static final int STATE_OFF\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate int mNum\nprivate int mNum2\nprivate int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient android.net.LinkAddress[] mLinkAddresses6\ntransient int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange(from=0L, to=6L) int mDayOfWeek\nprivate @android.annotation.Size(2L) @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange(from=0.0) float[] mCoords\nprivate static java.lang.String defaultName4()\nprivate int[] lazyInitTmpStorage()\npublic android.net.LinkAddress[] getLinkAddresses4()\nprivate boolean patternEquals(java.util.regex.Pattern)\nprivate int patternHashCode()\nprivate void onConstructed()\npublic void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
index 2efa193e7e2a..b5f6c73a8aef 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
@@ -85,7 +85,7 @@ public class SampleWithCustomBuilder implements Parcelable {
- // Code below generated by codegen v1.0.5.
+ // Code below generated by codegen v1.0.7.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -249,8 +249,8 @@ public class SampleWithCustomBuilder implements Parcelable {
}
@DataClass.Generated(
- time = 1570231098303L,
- codegenVersion = "1.0.5",
+ time = 1570576453295L,
+ codegenVersion = "1.0.7",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java",
inputSignatures = " long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n long creationTimestamp\nprivate static java.util.concurrent.TimeUnit unparcelDelayUnit(android.os.Parcel)\nprivate void parcelDelayUnit(android.os.Parcel,int)\nclass SampleWithCustomBuilder extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)\nabstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
new file mode 100644
index 000000000000..0ce8aba9b28f
--- /dev/null
+++ b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.codegentest;
+
+import android.annotation.NonNull;
+
+import com.android.internal.util.DataClass;
+
+/**
+ * Test for some false positive pitfalls for
+ * {@link android.processor.staledataclass.StaleDataclassProcessor}
+ *
+ * Relies on the detector being run, failing the build should any of things here falsely
+ * register as stale.
+ */
+@DataClass(genConstructor = false, genBuilder = false)
+public class StaleDataclassDetectorFalsePositivesTest {
+
+ /** Interfaces should be ignored */
+ public interface SomeListener {
+ void onEvent();
+ }
+
+ /** Enums should be ignored */
+ private enum SomeEnum { ONE, TWO }
+
+ /** Annotations should be ignored */
+ public @interface SomeAnnotation {}
+
+ /* Static initializers should be ignored */
+ static {}
+
+ /* Initializers should be ignored */
+ {}
+
+ /** Unrelated methods should be noted, without triggering staleness false positives */
+ public @NonNull String someMethod(int param) { return null; }
+
+
+
+ // Code below generated by codegen v1.0.7.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
+
+
+ @DataClass.Generated(
+ time = 1570576457249L,
+ codegenVersion = "1.0.7",
+ sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java",
+ inputSignatures = "public @android.annotation.NonNull java.lang.String someMethod(int)\nclass StaleDataclassDetectorFalsePositivesTest extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false)")
+ @Deprecated
+ private void __metadata() {}
+
+}
diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index b0464d9e656f..ae8285b8a908 100644
--- a/tests/net/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -99,6 +99,7 @@ public class LinkPropertiesTest {
assertFalse(lp.isIpv4Provisioned());
assertFalse(lp.isIpv6Provisioned());
assertFalse(lp.isPrivateDnsActive());
+ assertFalse(lp.isWakeOnLanSupported());
}
private LinkProperties makeTestObject() {
@@ -120,6 +121,7 @@ public class LinkPropertiesTest {
lp.setMtu(MTU);
lp.setTcpBufferSizes(TCP_BUFFER_SIZES);
lp.setNat64Prefix(new IpPrefix("2001:db8:0:64::/96"));
+ lp.setWakeOnLanSupported(true);
return lp;
}
@@ -158,6 +160,9 @@ public class LinkPropertiesTest {
assertTrue(source.isIdenticalTcpBufferSizes(target));
assertTrue(target.isIdenticalTcpBufferSizes(source));
+ assertTrue(source.isIdenticalWakeOnLan(target));
+ assertTrue(target.isIdenticalWakeOnLan(source));
+
// Check result of equals().
assertTrue(source.equals(target));
assertTrue(target.equals(source));
@@ -1057,4 +1062,13 @@ public class LinkPropertiesTest {
lp.clear();
assertFalse(lp.isPrivateDnsActive());
}
+
+ @Test
+ public void testWakeOnLanSupported() {
+ final LinkProperties lp = makeTestObject();
+ assertTrue(lp.isWakeOnLanSupported());
+
+ lp.clear();
+ assertFalse(lp.isWakeOnLanSupported());
+ }
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 41440abadcd0..bffbbfda08ee 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -274,6 +274,7 @@ public class ConnectivityServiceTest {
private static final String CLAT_PREFIX = "v4-";
private static final String MOBILE_IFNAME = "test_rmnet_data0";
private static final String WIFI_IFNAME = "test_wlan0";
+ private static final String WIFI_WOL_IFNAME = "test_wlan_wol";
private static final String[] EMPTY_STRING_ARRAY = new String[0];
private MockContext mServiceContext;
@@ -343,6 +344,12 @@ public class ConnectivityServiceTest {
"mobile_mms,2,0,2,60000,true",
});
+ when(mResources.getStringArray(
+ com.android.internal.R.array.config_wakeonlan_supported_interfaces))
+ .thenReturn(new String[]{
+ WIFI_WOL_IFNAME,
+ });
+
mContentResolver = new MockContentResolver();
mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider);
}
@@ -5947,6 +5954,24 @@ public class ConnectivityServiceTest {
assertContainsExactly(uidCaptor.getValue(), APP2_UID);
}
+ @Test
+ public void testLinkPropertiesWithWakeOnLanForActiveNetwork() throws Exception {
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+
+ LinkProperties wifiLp = new LinkProperties();
+ wifiLp.setInterfaceName(WIFI_WOL_IFNAME);
+ wifiLp.setWakeOnLanSupported(false);
+
+ // Default network switch should update ifaces.
+ mWiFiNetworkAgent.connect(false);
+ mWiFiNetworkAgent.sendLinkProperties(wifiLp);
+ waitForIdle();
+
+ // ConnectivityService should have changed the WakeOnLanSupported to true
+ wifiLp.setWakeOnLanSupported(true);
+ assertEquals(wifiLp, mService.getActiveLinkProperties());
+ }
+
private TestNetworkAgentWrapper establishVpn(LinkProperties lp, int establishingUid,
Set<UidRange> vpnRange) throws Exception {
diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt
index a36f2c838787..47f774f07f16 100644
--- a/tools/codegen/src/com/android/codegen/SharedConstants.kt
+++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt
@@ -1,7 +1,7 @@
package com.android.codegen
const val CODEGEN_NAME = "codegen"
-const val CODEGEN_VERSION = "1.0.5"
+const val CODEGEN_VERSION = "1.0.7"
const val CANONICAL_BUILDER_CLASS = "Builder"
const val BASE_BUILDER_CLASS = "BaseBuilder"
diff --git a/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt b/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt
index d00def625a39..7fe21c7aab3e 100644
--- a/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt
+++ b/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt
@@ -182,6 +182,11 @@ class StaleDataclassProcessor: AbstractProcessor() {
.filterNot {
it.kind == ElementKind.CLASS
|| it.kind == ElementKind.CONSTRUCTOR
+ || it.kind == ElementKind.INTERFACE
+ || it.kind == ElementKind.ENUM
+ || it.kind == ElementKind.ANNOTATION_TYPE
+ || it.kind == ElementKind.INSTANCE_INIT
+ || it.kind == ElementKind.STATIC_INIT
|| isGenerated(it)
}.map {
elemToString(it)