summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--StubLibraries.bp4
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java9
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java10
-rw-r--r--apex/statsd/framework/Android.bp5
-rw-r--r--api/current.txt10
-rwxr-xr-xapi/system-current.txt4
-rw-r--r--cmds/statsd/src/atoms.proto12
-rw-r--r--core/java/android/app/IActivityManager.aidl2
-rw-r--r--core/java/android/app/Notification.java24
-rw-r--r--core/java/android/app/Person.java15
-rw-r--r--core/java/android/app/PropertyInvalidatedCache.java34
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java21
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl2
-rw-r--r--core/java/android/net/NetworkPolicyManager.java4
-rw-r--r--core/java/android/net/NetworkTemplate.java4
-rw-r--r--core/java/android/os/UserManager.java25
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/java/android/service/notification/StatusBarNotification.java29
-rw-r--r--core/java/android/service/quickaccesswallet/TEST_MAPPING7
-rw-r--r--core/java/android/view/Display.java20
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java5
-rw-r--r--core/java/android/view/ViewRootImpl.java2
-rw-r--r--core/java/android/widget/Toast.java5
-rw-r--r--core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java61
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java161
-rw-r--r--core/java/com/android/internal/app/ChooserListAdapter.java13
-rw-r--r--core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java24
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java254
-rw-r--r--core/java/com/android/internal/app/ResolverListAdapter.java51
-rw-r--r--core/java/com/android/internal/app/ResolverListController.java11
-rw-r--r--core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java24
-rw-r--r--core/java/com/android/internal/logging/InstanceId.java47
-rw-r--r--core/java/com/android/internal/logging/InstanceIdSequence.java18
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java3
-rw-r--r--core/res/res/drawable-hdpi/sym_app_on_sd_unavailable_icon.pngbin3342 -> 0 bytes
-rw-r--r--core/res/res/drawable-ldpi/sym_app_on_sd_unavailable_icon.pngbin1077 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/sym_app_on_sd_unavailable_icon.pngbin5433 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/sym_app_on_sd_unavailable_icon.pngbin4125 -> 0 bytes
-rw-r--r--core/res/res/drawable/chooser_action_button_bg.xml33
-rw-r--r--core/res/res/drawable/ic_content_copy_gm2.xml25
-rw-r--r--core/res/res/drawable/ic_menu_copy_material.xml41
-rw-r--r--core/res/res/drawable/sym_app_on_sd_unavailable_icon.xml47
-rw-r--r--core/res/res/layout/chooser_action_button.xml30
-rw-r--r--core/res/res/layout/chooser_action_row.xml26
-rw-r--r--core/res/res/layout/chooser_grid_preview_file.xml16
-rw-r--r--core/res/res/layout/chooser_grid_preview_image.xml10
-rw-r--r--core/res/res/layout/chooser_grid_preview_text.xml44
-rw-r--r--core/res/res/mipmap-hdpi/sym_app_on_sd_unavailable_icon.pngbin3342 -> 0 bytes
-rw-r--r--core/res/res/mipmap-ldpi/sym_app_on_sd_unavailable_icon.pngbin1077 -> 0 bytes
-rw-r--r--core/res/res/mipmap-mdpi/sym_app_on_sd_unavailable_icon.pngbin5433 -> 0 bytes
-rw-r--r--core/res/res/values/config.xml8
-rw-r--r--core/res/res/values/dimens.xml2
-rw-r--r--core/res/res/values/ids.xml3
-rw-r--r--core/res/res/values/symbols.xml8
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java12
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java58
-rw-r--r--data/etc/services.core.protolog.json45
-rw-r--r--libs/hwui/hwui/Bitmap.cpp8
-rw-r--r--media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRoute2InfoTest.java363
-rw-r--r--media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java780
-rw-r--r--media/tests/MediaRouter/src/com/android/mediaroutertest/RouteDiscoveryPreferenceTest.java87
-rw-r--r--media/tests/MediaRouter/src/com/android/mediaroutertest/RoutingSessionInfoTest.java526
-rw-r--r--mms/java/android/telephony/MmsManager.java14
-rw-r--r--mms/java/com/android/internal/telephony/IMms.aidl9
-rw-r--r--packages/SettingsLib/res/values-ar/arrays.xml2
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java2
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/SystemUI/Android.bp9
-rw-r--r--packages/SystemUI/docs/plugin_hooks.md5
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/HomeControlsPlugin.java41
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java52
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java4
-rw-r--r--packages/SystemUI/res/drawable/control_no_favorites_background.xml2
-rw-r--r--packages/SystemUI/res/layout/controls_base_item.xml12
-rw-r--r--packages/SystemUI/res/layout/controls_no_favorites.xml2
-rw-r--r--packages/SystemUI/res/layout/controls_with_favorites.xml17
-rw-r--r--packages/SystemUI/res/layout/global_actions_grid_v2.xml4
-rw-r--r--packages/SystemUI/res/layout/home_controls.xml12
-rw-r--r--packages/SystemUI/res/layout/status_bar.xml26
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml3
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/res/values/strings.xml3
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java197
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java101
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyLruCache.java100
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java9
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java23
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java142
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeLog.java177
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt201
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeUi.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/LogMessage.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/SysuiLog.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/ControlsTile.java203
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVPluginManager.kt102
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java144
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java54
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/Utils.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java28
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shared/recents/model/TaskKeyLruCacheTest.java140
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java21
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java60
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java14
-rw-r--r--packages/WAPPushManager/Android.bp1
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java2
-rw-r--r--services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java11
-rw-r--r--services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java20
-rw-r--r--services/core/java/com/android/server/LocationManagerService.java4
-rw-r--r--services/core/java/com/android/server/MmsServiceBroker.java15
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java43
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerConstants.java13
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java16
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java7
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkNotificationManager.java12
-rw-r--r--services/core/java/com/android/server/location/AbstractLocationProvider.java19
-rw-r--r--services/core/java/com/android/server/location/GnssConfiguration.java5
-rw-r--r--services/core/java/com/android/server/location/GnssLocationProvider.java20
-rw-r--r--services/core/java/com/android/server/location/GnssVisibilityControl.java4
-rw-r--r--services/core/java/com/android/server/location/LocationProviderProxy.java8
-rw-r--r--services/core/java/com/android/server/location/LocationUsageLogger.java9
-rw-r--r--services/core/java/com/android/server/location/MockProvider.java15
-rw-r--r--services/core/java/com/android/server/location/MockableLocationProvider.java23
-rw-r--r--services/core/java/com/android/server/location/PassiveProvider.java27
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java32
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecordLogger.java4
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java2
-rw-r--r--services/core/java/com/android/server/pm/ApexManager.java66
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java80
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java40
-rw-r--r--services/core/java/com/android/server/rollback/AppDataRollbackHelper.java135
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java80
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java11
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java69
-rw-r--r--services/core/java/com/android/server/wm/InsetsControlTarget.java7
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java11
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java36
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java16
-rw-r--r--services/core/java/com/android/server/wm/ProtoLogGroup.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java48
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java23
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java29
-rw-r--r--services/tests/servicestests/Android.bp1
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/location/MockableLocationProviderTest.java213
-rw-r--r--services/tests/servicestests/src/com/android/server/location/test/FakeProvider.java45
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java23
-rw-r--r--services/tests/uiservicestests/src/com/android/internal/logging/InstanceIdSequenceFake.java (renamed from core/java/com/android/internal/logging/testing/InstanceIdSequenceFake.java)21
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java7
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java70
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java4
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java33
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java16
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java43
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java25
-rw-r--r--services/usb/java/com/android/server/usb/UsbHostManager.java17
-rw-r--r--services/usb/java/com/android/server/usb/UsbPortManager.java17
-rw-r--r--services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java22
-rw-r--r--telephony/java/android/telephony/CellIdentity.java4
-rw-r--r--telephony/java/android/telephony/CellIdentityCdma.java13
-rw-r--r--telephony/java/android/telephony/CellIdentityGsm.java24
-rw-r--r--telephony/java/android/telephony/CellIdentityLte.java25
-rw-r--r--telephony/java/android/telephony/CellIdentityNr.java16
-rw-r--r--telephony/java/android/telephony/CellIdentityTdscdma.java24
-rw-r--r--telephony/java/android/telephony/CellIdentityWcdma.java25
-rw-r--r--telephony/java/android/telephony/SmsManager.java4
-rw-r--r--tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java19
-rw-r--r--tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java133
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl2
-rw-r--r--wifi/java/android/net/wifi/WifiInfo.java7
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java23
-rw-r--r--wifi/java/com/android/server/wifi/BaseWifiService.java4
-rw-r--r--wifi/tests/src/android/net/wifi/WifiManagerTest.java10
212 files changed, 3136 insertions, 4288 deletions
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 6927f4449054..0f805655b33d 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -340,7 +340,7 @@ java_library_static {
}
java_library_static {
- name: "framework_module_app_stubs_current",
+ name: "android_module_app_stubs_current",
srcs: [
":module-app-api-stubs-docs",
],
@@ -355,7 +355,7 @@ java_library_static {
}
java_library_static {
- name: "framework_module_lib_stubs_current",
+ name: "android_module_lib_stubs_current",
srcs: [
":module-lib-api-stubs-docs",
],
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index ed5626a1acbc..69f4748548a7 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -77,7 +77,6 @@ import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
-import android.util.StatsLog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
@@ -85,6 +84,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.AppStateTracker;
import com.android.server.DeviceIdleInternal;
@@ -1171,9 +1171,9 @@ public class JobSchedulerService extends com.android.server.SystemService
jobStatus.enqueueWorkLocked(work);
}
- StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED,
+ FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
uId, null, jobStatus.getBatteryName(),
- StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED,
+ FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED,
JobProtoEnums.STOP_REASON_CANCELLED, jobStatus.getStandbyBucket(),
jobStatus.getJobId());
@@ -2567,7 +2567,8 @@ public class JobSchedulerService extends com.android.server.SystemService
BatteryStatsInternal mBatteryStatsInternal = LocalServices.getService
(BatteryStatsInternal.class);
mBatteryStatsInternal.noteJobsDeferred(uid, counter.numDeferred(), sinceLast);
- StatsLog.write_non_chained(StatsLog.DEFERRED_JOB_STATS_REPORTED, uid, null,
+ FrameworkStatsLog.write_non_chained(
+ FrameworkStatsLog.DEFERRED_JOB_STATS_REPORTED, uid, null,
counter.numDeferred(), sinceLast);
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index dbdce70dda03..f706260edec2 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -32,10 +32,10 @@ import android.text.format.DateFormat;
import android.util.ArraySet;
import android.util.Pair;
import android.util.Slog;
-import android.util.StatsLog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
import com.android.server.job.GrantedUriPermissions;
import com.android.server.job.JobSchedulerInternal;
@@ -1059,10 +1059,12 @@ public final class JobStatus {
mReadyDynamicSatisfied =
mDynamicConstraints == (satisfiedConstraints & mDynamicConstraints);
if (STATS_LOG_ENABLED && (STATSD_CONSTRAINTS_TO_LOG & constraint) != 0) {
- StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED,
+ FrameworkStatsLog.write_non_chained(
+ FrameworkStatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED,
sourceUid, null, getBatteryName(), getProtoConstraint(constraint),
- state ? StatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__SATISFIED
- : StatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__UNSATISFIED);
+ state ? FrameworkStatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__SATISFIED
+ : FrameworkStatsLog
+ .SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__UNSATISFIED);
}
return true;
}
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
index f66f0340edab..231c91026bb6 100644
--- a/apex/statsd/framework/Android.bp
+++ b/apex/statsd/framework/Android.bp
@@ -34,9 +34,8 @@ java_library {
],
libs: [
"framework-annotations-lib",
- // TODO(b/146230220): Use framework-system-stubs instead.
- //"android_system_stubs_current",
- //"framework_module_lib_stubs_current",
+ // TODO(b/146230220): Use android_module_lib_stubs_current instead.
+ //"android_module_lib_stubs_current",
"framework-all",
],
hostdex: true, // for hiddenapi check
diff --git a/api/current.txt b/api/current.txt
index 32fb1e7e8bfd..510db01940cd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -47070,8 +47070,8 @@ package android.telephony {
}
public class MmsManager {
- method public void downloadMultimediaMessage(int, @NonNull String, @NonNull android.net.Uri, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent);
- method public void sendMultimediaMessage(int, @NonNull android.net.Uri, @Nullable String, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent);
+ method public void downloadMultimediaMessage(int, @NonNull String, @NonNull android.net.Uri, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent, long);
+ method public void sendMultimediaMessage(int, @NonNull android.net.Uri, @Nullable String, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent, long);
}
@Deprecated public class NeighboringCellInfo implements android.os.Parcelable {
@@ -51776,7 +51776,7 @@ package android.view {
method public int getFlags();
method public android.view.Display.HdrCapabilities getHdrCapabilities();
method @Deprecated public int getHeight();
- method public void getMetrics(android.util.DisplayMetrics);
+ method @Deprecated public void getMetrics(android.util.DisplayMetrics);
method public android.view.Display.Mode getMode();
method public String getName();
method @Deprecated public int getOrientation();
@@ -51785,10 +51785,10 @@ package android.view {
method public long getPresentationDeadlineNanos();
method public void getRealMetrics(android.util.DisplayMetrics);
method public void getRealSize(android.graphics.Point);
- method public void getRectSize(android.graphics.Rect);
+ method @Deprecated public void getRectSize(android.graphics.Rect);
method public float getRefreshRate();
method public int getRotation();
- method public void getSize(android.graphics.Point);
+ method @Deprecated public void getSize(android.graphics.Point);
method public int getState();
method public android.view.Display.Mode[] getSupportedModes();
method @Deprecated public float[] getSupportedRefreshRates();
diff --git a/api/system-current.txt b/api/system-current.txt
index e3c61c89dcb9..0930f68e7b1a 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -7580,7 +7580,7 @@ package android.net.wifi {
method public boolean isEphemeral();
method public boolean isOsuAp();
method public boolean isPasspointAp();
- method @Nullable public static String removeDoubleQuotes(@Nullable String);
+ method @Nullable public static String sanitizeSsid(@Nullable String);
field public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
field public static final int INVALID_RSSI = -127; // 0xffffff81
}
@@ -7622,7 +7622,6 @@ package android.net.wifi {
method public boolean isApMacRandomizationSupported();
method public boolean isConnectedMacRandomizationSupported();
method @Deprecated public boolean isDeviceToDeviceRttSupported();
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean isDualModeSupported();
method public boolean isPortableHotspotSupported();
method public boolean isVerboseLoggingEnabled();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
@@ -8962,7 +8961,6 @@ package android.os {
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isSameProfileGroup(@NonNull android.os.UserHandle, @NonNull android.os.UserHandle);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}) public boolean isUserNameSet();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isUserOfType(@NonNull String);
- method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isUserOfType(@NonNull android.os.UserHandle, @NonNull String);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isUserUnlockingOrUnlocked(@NonNull android.os.UserHandle);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean removeUser(@NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(@NonNull android.graphics.Bitmap) throws android.os.UserManager.UserOperationException;
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index fa307bda9d26..7f00410ac9ab 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -226,12 +226,12 @@ message Atom {
GnssNfwNotificationReported gnss_nfw_notification_reported = 131 [(module) = "framework"];
GnssConfigurationReported gnss_configuration_reported = 132 [(module) = "framework"];
UsbPortOverheatEvent usb_port_overheat_event_reported = 133;
- NfcErrorOccurred nfc_error_occurred = 134;
- NfcStateChanged nfc_state_changed = 135;
- NfcBeamOccurred nfc_beam_occurred = 136;
- NfcCardemulationOccurred nfc_cardemulation_occurred = 137;
- NfcTagOccurred nfc_tag_occurred = 138;
- NfcHceTransactionOccurred nfc_hce_transaction_occurred = 139;
+ NfcErrorOccurred nfc_error_occurred = 134 [(module) = "nfc"];
+ NfcStateChanged nfc_state_changed = 135 [(module) = "nfc"];
+ NfcBeamOccurred nfc_beam_occurred = 136 [(module) = "nfc"];
+ NfcCardemulationOccurred nfc_cardemulation_occurred = 137 [(module) = "nfc"];
+ NfcTagOccurred nfc_tag_occurred = 138 [(module) = "nfc"];
+ NfcHceTransactionOccurred nfc_hce_transaction_occurred = 139 [(module) = "nfc"];
SeStateChanged se_state_changed = 140;
SeOmapiReported se_omapi_reported = 141;
BroadcastDispatchLatencyReported broadcast_dispatch_latency_reported =
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 5f3bad6ad1a8..cb6a476fb617 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -287,7 +287,7 @@ interface IActivityManager {
void killApplicationProcess(in String processName, int uid);
// Special low-level communication with activity manager.
boolean handleApplicationWtf(in IBinder app, in String tag, boolean system,
- in ApplicationErrorReport.ParcelableCrashInfo crashInfo);
+ in ApplicationErrorReport.ParcelableCrashInfo crashInfo, int immediateCallerPid);
@UnsupportedAppUsage
void killBackgroundProcesses(in String packageName, int userId);
boolean isUserAMonkey();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 35d26aba9094..576b56fa33f6 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2487,6 +2487,20 @@ public class Notification implements Parcelable
if (extras.containsKey(EXTRA_BACKGROUND_IMAGE_URI)) {
visitor.accept(Uri.parse(extras.getString(EXTRA_BACKGROUND_IMAGE_URI)));
}
+
+ ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST);
+ if (people != null && !people.isEmpty()) {
+ for (Person p : people) {
+ if (p.getIconUri() != null) {
+ visitor.accept(p.getIconUri());
+ }
+ }
+ }
+
+ final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON);
+ if (person != null && person.getIconUri() != null) {
+ visitor.accept(person.getIconUri());
+ }
}
if (MessagingStyle.class.equals(getNotificationStyle()) && extras != null) {
@@ -2495,6 +2509,11 @@ public class Notification implements Parcelable
for (MessagingStyle.Message message : MessagingStyle.Message
.getMessagesFromBundleArray(messages)) {
visitor.accept(message.getDataUri());
+
+ Person senderPerson = message.getSenderPerson();
+ if (senderPerson != null && senderPerson.getIconUri() != null) {
+ visitor.accept(senderPerson.getIconUri());
+ }
}
}
@@ -2503,6 +2522,11 @@ public class Notification implements Parcelable
for (MessagingStyle.Message message : MessagingStyle.Message
.getMessagesFromBundleArray(historic)) {
visitor.accept(message.getDataUri());
+
+ Person senderPerson = message.getSenderPerson();
+ if (senderPerson != null && senderPerson.getIconUri() != null) {
+ visitor.accept(senderPerson.getIconUri());
+ }
}
}
}
diff --git a/core/java/android/app/Person.java b/core/java/android/app/Person.java
index 14a5589c04c2..63ef2484ca1d 100644
--- a/core/java/android/app/Person.java
+++ b/core/java/android/app/Person.java
@@ -19,6 +19,7 @@ package android.app;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.drawable.Icon;
+import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -122,6 +123,20 @@ public final class Person implements Parcelable {
return "";
}
+ /**
+ * @return the URI associated with the {@link #getIcon()} for this person, iff the icon exists
+ * and is URI based.
+ * @hide
+ */
+ @Nullable
+ public Uri getIconUri() {
+ if (mIcon != null && (mIcon.getType() == Icon.TYPE_URI
+ || mIcon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP)) {
+ return mIcon.getUri();
+ }
+ return null;
+ }
+
@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 736efb6a5e69..cbd2f1a52c0c 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -297,9 +297,10 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
if (currentNonce == NONCE_DISABLED || currentNonce == NONCE_UNSET) {
if (DEBUG) {
Log.d(TAG,
- String.format("cache %s for %s",
+ String.format("cache %s %s for %s",
+ cacheName(),
currentNonce == NONCE_DISABLED ? "disabled" : "unset",
- query));
+ queryToString(query)));
}
return recompute(query);
}
@@ -310,7 +311,8 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
} else {
if (DEBUG) {
Log.d(TAG,
- String.format("clearing cache because nonce changed [%s] -> [%s]",
+ String.format("clearing cache %s because nonce changed [%s] -> [%s]",
+ cacheName(),
mLastSeenNonce, currentNonce));
}
mCache.clear();
@@ -328,13 +330,15 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
final Result refreshedResult = refresh(cachedResult, query);
if (refreshedResult != cachedResult) {
if (DEBUG) {
- Log.d(TAG, "cache refresh for " + query);
+ Log.d(TAG, "cache refresh for " + cacheName() + " " + queryToString(query));
}
final long afterRefreshNonce = getCurrentNonce();
if (currentNonce != afterRefreshNonce) {
currentNonce = afterRefreshNonce;
if (DEBUG) {
- Log.d(TAG, "restarting query because nonce changed in refresh");
+ Log.d(TAG, String.format("restarting %s %s because nonce changed in refresh",
+ cacheName(),
+ queryToString(query)));
}
continue;
}
@@ -352,13 +356,13 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
return maybeCheckConsistency(query, refreshedResult);
}
if (DEBUG) {
- Log.d(TAG, "cache hit for " + query);
+ Log.d(TAG, "cache hit for " + cacheName() + " " + queryToString(query));
}
return maybeCheckConsistency(query, cachedResult);
}
// Cache miss: make the value from scratch.
if (DEBUG) {
- Log.d(TAG, "cache miss for " + query);
+ Log.d(TAG, "cache miss for " + cacheName() + " " + queryToString(query));
}
final Result result = recompute(query);
synchronized (mLock) {
@@ -451,4 +455,20 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
}
return proposedResult;
}
+
+ /**
+ * Return the name of the cache, to be used in debug messages. The
+ * method is public so clients can use it.
+ */
+ public String cacheName() {
+ return mPropertyName;
+ }
+
+ /**
+ * Return the query as a string, to be used in debug messages. The
+ * method is public so clients can use it in external debug messages.
+ */
+ public String queryToString(Query query) {
+ return Objects.toString(query);
+ }
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d1b5a83e7142..f71d78b40242 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -7028,21 +7028,28 @@ public class DevicePolicyManager {
}
/**
- * Called by a device owner to set the default SMS application.
+ * Must be called by a device owner or a profile owner of an organization-owned managed profile
+ * to set the default SMS application.
* <p>
- * The calling device admin must be a device owner. If it is not, a security exception will be
- * thrown.
+ * This method can be called on the {@link DevicePolicyManager} instance, returned by
+ * {@link #getParentProfileInstance(ComponentName)}, where the caller must be the profile owner
+ * of an organization-owned managed profile and the package must be a pre-installed system
+ * package. If called on the parent instance, then the default SMS application is set on the
+ * personal profile.
*
- * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param packageName The name of the package to set as the default SMS application.
- * @throws SecurityException if {@code admin} is not a device owner.
+ * @throws SecurityException if {@code admin} is not a device or profile owner or if
+ * called on the parent profile and the {@code admin} is not a
+ * profile owner of an organization-owned managed profile.
+ * @throws IllegalArgumentException if called on the parent profile and the package
+ * provided is not a pre-installed system package.
*/
public void setDefaultSmsApplication(@NonNull ComponentName admin,
@NonNull String packageName) {
- throwIfParentInstance("setDefaultSmsApplication");
if (mService != null) {
try {
- mService.setDefaultSmsApplication(admin, packageName);
+ mService.setDefaultSmsApplication(admin, packageName, mParentInstance);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index e3dba310ab44..7fd0ae4a1a00 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -202,7 +202,7 @@ interface IDevicePolicyManager {
void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity);
void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName);
- void setDefaultSmsApplication(in ComponentName admin, String packageName);
+ void setDefaultSmsApplication(in ComponentName admin, String packageName, boolean parent);
void setApplicationRestrictions(in ComponentName who, in String callerPackage, in String packageName, in Bundle settings);
Bundle getApplicationRestrictions(in ComponentName who, in String callerPackage, in String packageName);
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 01800c6751fb..14442a2088cd 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -539,13 +539,13 @@ public class NetworkPolicyManager {
/** @hide */
public static String resolveNetworkId(WifiConfiguration config) {
- return WifiInfo.removeDoubleQuotes(config.isPasspoint()
+ return WifiInfo.sanitizeSsid(config.isPasspoint()
? config.providerFriendlyName : config.SSID);
}
/** @hide */
public static String resolveNetworkId(String ssid) {
- return WifiInfo.removeDoubleQuotes(ssid);
+ return WifiInfo.sanitizeSsid(ssid);
}
/** @hide */
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 5e6c47a47a8e..5498f74ba2cc 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -32,7 +32,7 @@ import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkStats.ROAMING_ALL;
import static android.net.NetworkStats.ROAMING_NO;
import static android.net.NetworkStats.ROAMING_YES;
-import static android.net.wifi.WifiInfo.removeDoubleQuotes;
+import static android.net.wifi.WifiInfo.sanitizeSsid;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
@@ -401,7 +401,7 @@ public class NetworkTemplate implements Parcelable {
switch (ident.mType) {
case TYPE_WIFI:
return Objects.equals(
- removeDoubleQuotes(mNetworkId), removeDoubleQuotes(ident.mNetworkId));
+ sanitizeSsid(mNetworkId), sanitizeSsid(ident.mNetworkId));
default:
return false;
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 3564589e35a4..6ed1d2c345f8 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1775,9 +1775,10 @@ public class UserManager {
}
/**
- * Returns whether the context user's user is of the given user type, such as
- * {@link UserManager#USER_TYPE_FULL_GUEST}.
+ * Returns whether the context user is of the given user type.
*
+ * @param userType the name of the user's user type, e.g.
+ * {@link UserManager#USER_TYPE_PROFILE_MANAGED}.
* @return true if the user is of the given user type.
* @hide
*/
@@ -1793,26 +1794,6 @@ public class UserManager {
}
/**
- * Returns whether the given user is of the given user type, such as
- * {@link UserManager#USER_TYPE_FULL_GUEST}.
- *
- * @param userHandle the user handle of the user whose type is being requested.
- * @param userType the name of the user's user type, e.g.
- * {@link UserManager#USER_TYPE_PROFILE_MANAGED}.
- * @return true if the userHandle user is of type userType
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
- public boolean isUserOfType(@NonNull UserHandle userHandle, @NonNull String userType) {
- try {
- return mService.isUserOfType(userHandle.getIdentifier(), userType);
- } catch (RemoteException re) {
- throw re.rethrowFromSystemServer();
- }
- }
-
- /**
* Returns whether the user type is a
* {@link UserManager#USER_TYPE_PROFILE_MANAGED managed profile}.
* @hide
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 9666c12699e8..605c585215a6 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8711,6 +8711,14 @@ public final class Settings {
"back_gesture_inset_scale_right";
/**
+ * Current provider of proximity-based sharing services.
+ * Default value in @string/config_defaultNearbySharingComponent.
+ * No VALIDATOR as this setting will not be backed up.
+ * @hide
+ */
+ public static final String NEARBY_SHARING_COMPONENT = "nearby_sharing_component";
+
+ /**
* Controls whether aware is enabled.
* @hide
*/
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index c5d97b718ff0..74b913645ad4 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -35,6 +35,7 @@ import android.os.Parcelable;
import android.os.UserHandle;
import android.text.TextUtils;
+import com.android.internal.logging.InstanceId;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -68,6 +69,8 @@ public class StatusBarNotification implements Parcelable {
private final UserHandle user;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private final long postTime;
+ // A small per-notification ID, used for statsd logging.
+ private InstanceId mInstanceId; // Not final, see setInstanceId()
private Context mContext; // used for inflation & icon expansion
@@ -131,8 +134,9 @@ public class StatusBarNotification implements Parcelable {
this.postTime = in.readLong();
if (in.readInt() != 0) {
this.overrideGroupKey = in.readString();
- } else {
- this.overrideGroupKey = null;
+ }
+ if (in.readInt() != 0) {
+ this.mInstanceId = InstanceId.CREATOR.createFromParcel(in);
}
this.key = key();
this.groupKey = groupKey();
@@ -196,7 +200,6 @@ public class StatusBarNotification implements Parcelable {
out.writeInt(this.initialPid);
this.notification.writeToParcel(out, flags);
user.writeToParcel(out, flags);
-
out.writeLong(this.postTime);
if (this.overrideGroupKey != null) {
out.writeInt(1);
@@ -204,6 +207,12 @@ public class StatusBarNotification implements Parcelable {
} else {
out.writeInt(0);
}
+ if (this.mInstanceId != null) {
+ out.writeInt(1);
+ mInstanceId.writeToParcel(out, flags);
+ } else {
+ out.writeInt(0);
+ }
}
public int describeContents() {
@@ -390,6 +399,20 @@ public class StatusBarNotification implements Parcelable {
/**
* @hide
*/
+ public InstanceId getInstanceId() {
+ return mInstanceId;
+ }
+
+ /**
+ * @hide
+ */
+ public void setInstanceId(InstanceId instanceId) {
+ mInstanceId = instanceId;
+ }
+
+ /**
+ * @hide
+ */
@UnsupportedAppUsage
public Context getPackageContext(Context context) {
if (mContext == null) {
diff --git a/core/java/android/service/quickaccesswallet/TEST_MAPPING b/core/java/android/service/quickaccesswallet/TEST_MAPPING
new file mode 100644
index 000000000000..4d97ab6e612d
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsQuickAccessWalletTestCases"
+ }
+ ]
+}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 0304328f734a..d79fc9a48116 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -57,8 +57,8 @@ import java.util.List;
* <li>The application display area specifies the part of the display that may contain
* an application window, excluding the system decorations. The application display area may
* be smaller than the real display area because the system subtracts the space needed
- * for decor elements such as the status bar. Use the following methods to query the
- * application display area: {@link #getSize}, {@link #getRectSize} and {@link #getMetrics}.</li>
+ * for decor elements such as the status bar. Use {@link WindowMetrics#getSize()} to query the
+ * application window size.</li>
* <li>The real display area specifies the part of the display that contains content
* including the system decorations. Even so, the real display area may be smaller than the
* physical size of the display if the window manager is emulating a smaller display
@@ -97,7 +97,7 @@ public final class Display {
// We cache the app width and height properties briefly between calls
// to getHeight() and getWidth() to ensure that applications perceive
// consistent results when the size changes (most of the time).
- // Applications should now be using getSize() instead.
+ // Applications should now be using WindowMetrics instead.
private static final int CACHED_APP_SIZE_DURATION_MILLIS = 20;
private long mLastCachedAppSizeUpdate;
private int mCachedAppWidthCompat;
@@ -674,7 +674,10 @@ public final class Display {
* </p>
*
* @param outSize A {@link Point} object to receive the size information.
+ * @deprecated Use {@link WindowManager#getCurrentWindowMetrics()} to obtain an instance of
+ * {@link WindowMetrics} and use {@link WindowMetrics#getSize()} instead.
*/
+ @Deprecated
public void getSize(Point outSize) {
synchronized (this) {
updateDisplayInfoLocked();
@@ -688,8 +691,10 @@ public final class Display {
* Gets the size of the display as a rectangle, in pixels.
*
* @param outSize A {@link Rect} object to receive the size information.
- * @see #getSize(Point)
+ * @deprecated Use {@link WindowMetrics#getSize()} to get the dimensions of the application
+ * window area.
*/
+ @Deprecated
public void getRectSize(Rect outSize) {
synchronized (this) {
updateDisplayInfoLocked();
@@ -752,7 +757,7 @@ public final class Display {
}
/**
- * @deprecated Use {@link #getSize(Point)} instead.
+ * @deprecated Use {@link WindowMetrics#getSize()} instead.
*/
@Deprecated
public int getWidth() {
@@ -763,7 +768,7 @@ public final class Display {
}
/**
- * @deprecated Use {@link #getSize(Point)} instead.
+ * @deprecated Use {@link WindowMetrics#getSize()} instead.
*/
@Deprecated
public int getHeight() {
@@ -1102,7 +1107,10 @@ public final class Display {
* </p>
*
* @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
+ * @deprecated Use {@link WindowMetrics#getSize()} to get the dimensions of the application
+ * window area, and {@link Configuration#densityDpi} to get the current density.
*/
+ @Deprecated
public void getMetrics(DisplayMetrics outMetrics) {
synchronized (this) {
updateDisplayInfoLocked();
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index ddfd38c0320b..9901d053184c 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -181,8 +181,9 @@ public class InsetsSourceConsumer {
}
private void applyHiddenToControl() {
- if (mSourceControl == null || mSourceControl.getLeash() == null
- || mController.getAnimationType(mType) != ANIMATION_TYPE_NONE) {
+
+ // TODO: Handle case properly when animation is running already (it shouldn't!)
+ if (mSourceControl == null || mSourceControl.getLeash() == null) {
return;
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 841c43fb1392..51ea30b41741 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -216,7 +216,7 @@ public final class ViewRootImpl implements ViewParent,
* If set to 1, this will switch to a mode where we only use the new approach for IME, but not
* for the status/navigation bar.
*/
- private static final String USE_NEW_INSETS_PROPERTY = "persist.wm.new_insets";
+ private static final String USE_NEW_INSETS_PROPERTY = "persist.debug.new_insets";
/**
* @see #USE_NEW_INSETS_PROPERTY
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index c8a7c079994c..78d4e61ea953 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -28,6 +28,7 @@ import android.app.ITransientNotification;
import android.app.ITransientNotificationCallback;
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Configuration;
@@ -112,11 +113,9 @@ public class Toast {
/**
* Text toasts will be rendered by SystemUI instead of in-app, so apps can't circumvent
* background custom toast restrictions.
- *
- * TODO(b/144152069): Add @EnabledAfter(Q) to target R+ after assessing impact on dogfood
*/
@ChangeId
- // @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
private static final long CHANGE_TEXT_TOASTS_IN_THE_SYSTEM = 147798919L;
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
index 77d8e0290f20..ab8c19ea8861 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -18,7 +18,9 @@ package com.android.internal.app;
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.pm.ResolveInfo;
import android.os.UserHandle;
+import android.os.UserManager;
import android.view.View;
import android.view.ViewGroup;
@@ -27,6 +29,7 @@ import com.android.internal.widget.PagerAdapter;
import com.android.internal.widget.ViewPager;
import java.util.HashSet;
+import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -46,11 +49,17 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
private int mCurrentPage;
private OnProfileSelectedListener mOnProfileSelectedListener;
private Set<Integer> mLoadedPages;
+ private final UserHandle mPersonalProfileUserHandle;
+ private final UserHandle mWorkProfileUserHandle;
- AbstractMultiProfilePagerAdapter(Context context, int currentPage) {
+ AbstractMultiProfilePagerAdapter(Context context, int currentPage,
+ UserHandle personalProfileUserHandle,
+ UserHandle workProfileUserHandle) {
mContext = Objects.requireNonNull(context);
mCurrentPage = currentPage;
mLoadedPages = new HashSet<>();
+ mPersonalProfileUserHandle = personalProfileUserHandle;
+ mWorkProfileUserHandle = workProfileUserHandle;
}
void setOnProfileSelectedListener(OnProfileSelectedListener listener) {
@@ -72,7 +81,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
public void onPageSelected(int position) {
mCurrentPage = position;
if (!mLoadedPages.contains(position)) {
- getActiveListAdapter().rebuildList();
+ rebuildActiveTab(true);
mLoadedPages.add(position);
}
if (mOnProfileSelectedListener != null) {
@@ -85,6 +94,13 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
mLoadedPages.add(mCurrentPage);
}
+ void clearInactiveProfileCache() {
+ if (mLoadedPages.size() == 1) {
+ return;
+ }
+ mLoadedPages.remove(1 - mCurrentPage);
+ }
+
@Override
public ViewGroup instantiateItem(ViewGroup container, int position) {
final ProfileDescriptor profileDescriptor = getItem(position);
@@ -187,12 +203,53 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
@VisibleForTesting
public abstract @Nullable ResolverListAdapter getInactiveListAdapter();
+ public abstract ResolverListAdapter getPersonalListAdapter();
+
+ public abstract @Nullable ResolverListAdapter getWorkListAdapter();
+
abstract Object getCurrentRootAdapter();
abstract ViewGroup getActiveAdapterView();
abstract @Nullable ViewGroup getInactiveAdapterView();
+ boolean rebuildActiveTab(boolean post) {
+ return rebuildTab(getActiveListAdapter(), post);
+ }
+
+ boolean rebuildInactiveTab(boolean post) {
+ if (getItemCount() == 1) {
+ return false;
+ }
+ return rebuildTab(getInactiveListAdapter(), post);
+ }
+
+ private boolean rebuildTab(ResolverListAdapter activeListAdapter, boolean doPostProcessing) {
+ UserHandle listUserHandle = activeListAdapter.getUserHandle();
+ if (UserHandle.myUserId() != listUserHandle.getIdentifier() &&
+ !hasAppsInOtherProfile(activeListAdapter)) {
+ // TODO(arangelov): Show empty state UX here
+ return false;
+ } else {
+ return activeListAdapter.rebuildList(doPostProcessing);
+ }
+ }
+
+ private boolean hasAppsInOtherProfile(ResolverListAdapter adapter) {
+ if (mWorkProfileUserHandle == null) {
+ return false;
+ }
+ List<ResolverActivity.ResolvedComponentInfo> resolversForIntent =
+ adapter.getResolversForUser(UserHandle.of(UserHandle.myUserId()));
+ for (ResolverActivity.ResolvedComponentInfo info : resolversForIntent) {
+ ResolveInfo resolveInfo = info.getResolveInfoAt(0);
+ if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) {
+ return true;
+ }
+ }
+ return false;
+ }
+
protected class ProfileDescriptor {
final ViewGroup rootView;
ProfileDescriptor(ViewGroup rootView) {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 65128e4a2eda..a43e4fe118a9 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -53,6 +53,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
@@ -81,6 +82,7 @@ import android.provider.DeviceConfig;
import android.provider.DocumentsContract;
import android.provider.Downloads;
import android.provider.OpenableColumns;
+import android.provider.Settings;
import android.service.chooser.ChooserTarget;
import android.service.chooser.ChooserTargetService;
import android.service.chooser.IChooserTargetResult;
@@ -101,6 +103,7 @@ import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
+import android.widget.Button;
import android.widget.ImageView;
import android.widget.Space;
import android.widget.TextView;
@@ -131,6 +134,7 @@ import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.net.URISyntaxException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
@@ -166,6 +170,9 @@ public class ChooserActivity extends ResolverActivity implements
private static final String PREF_NUM_SHEET_EXPANSIONS = "pref_num_sheet_expansions";
+ private static final String CHIP_LABEL_METADATA_KEY = "android.service.chooser.chip_label";
+ private static final String CHIP_ICON_METADATA_KEY = "android.service.chooser.chip_icon";
+
private static final boolean DEBUG = true;
private static final boolean USE_PREDICTION_MANAGER_FOR_SHARE_ACTIVITIES = true;
@@ -527,6 +534,15 @@ public class ChooserActivity extends ResolverActivity implements
mIsSuccessfullySelected = false;
Intent intent = getIntent();
Parcelable targetParcelable = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+ if (targetParcelable instanceof Uri) {
+ try {
+ targetParcelable = Intent.parseUri(targetParcelable.toString(),
+ Intent.URI_INTENT_SCHEME);
+ } catch (URISyntaxException ex) {
+ // doesn't parse as an intent; let the next test fail and error out
+ }
+ }
+
if (!(targetParcelable instanceof Intent)) {
Log.w("ChooserActivity", "Target is not an intent: " + targetParcelable);
finish();
@@ -777,7 +793,9 @@ public class ChooserActivity extends ResolverActivity implements
/* userHandle */ UserHandle.of(UserHandle.myUserId()));
return new ChooserMultiProfilePagerAdapter(
/* context */ this,
- adapter);
+ adapter,
+ getPersonalProfileUserHandle(),
+ /* workProfileUserHandle= */ null);
}
private ChooserMultiProfilePagerAdapter createChooserMultiProfilePagerAdapterForTwoProfiles(
@@ -804,7 +822,9 @@ public class ChooserActivity extends ResolverActivity implements
/* context */ this,
personalAdapter,
workAdapter,
- /* defaultProfile */ getCurrentProfile());
+ /* defaultProfile */ getCurrentProfile(),
+ getPersonalProfileUserHandle(),
+ getWorkProfileUserHandle());
}
@Override
@@ -856,11 +876,11 @@ public class ChooserActivity extends ResolverActivity implements
}
@Override
- protected PackageMonitor createPackageMonitor() {
+ protected PackageMonitor createPackageMonitor(ResolverListAdapter listAdapter) {
return new PackageMonitor() {
@Override
public void onSomePackagesChanged() {
- handlePackagesChanged();
+ handlePackagesChanged(listAdapter);
}
};
}
@@ -869,9 +889,19 @@ public class ChooserActivity extends ResolverActivity implements
* Update UI to reflect changes in data.
*/
public void handlePackagesChanged() {
- // TODO(arangelov): Dispatch this to all adapters when we have the helper methods
- // in a follow-up CL
- mChooserMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged();
+ handlePackagesChanged(/* listAdapter */ null);
+ }
+
+ /**
+ * Update UI to reflect changes in data.
+ * <p>If {@code listAdapter} is {@code null}, both profile list adapters are updated.
+ */
+ private void handlePackagesChanged(@Nullable ResolverListAdapter listAdapter) {
+ if (listAdapter == null) {
+ mChooserMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged();
+ } else {
+ listAdapter.handlePackagesChanged();
+ }
updateProfileViewButton();
}
@@ -965,6 +995,108 @@ public class ChooserActivity extends ResolverActivity implements
return displayContentPreview(previewType, targetIntent, getLayoutInflater(), parent);
}
+ private ComponentName getNearbySharingComponent() {
+ String nearbyComponent = Settings.Secure.getString(
+ getContentResolver(),
+ Settings.Secure.NEARBY_SHARING_COMPONENT);
+ if (TextUtils.isEmpty(nearbyComponent)) {
+ nearbyComponent = getString(R.string.config_defaultNearbySharingComponent);
+ }
+ if (TextUtils.isEmpty(nearbyComponent)) {
+ return null;
+ }
+ return ComponentName.unflattenFromString(nearbyComponent);
+ }
+
+ private TargetInfo getNearbySharingTarget(Intent originalIntent) {
+ final ComponentName cn = getNearbySharingComponent();
+ if (cn == null) return null;
+
+ final Intent resolveIntent = new Intent();
+ resolveIntent.setComponent(cn);
+ final ResolveInfo ri = getPackageManager().resolveActivity(
+ resolveIntent, PackageManager.GET_META_DATA);
+ if (ri == null || ri.activityInfo == null) {
+ Log.e(TAG, "Device-specified nearby sharing component (" + cn
+ + ") not available");
+ return null;
+ }
+
+ // Allow the nearby sharing component to provide a more appropriate icon and label
+ // for the chip.
+ CharSequence name = null;
+ Drawable icon = null;
+ final Bundle metaData = ri.activityInfo.metaData;
+ if (metaData != null) {
+ try {
+ final Resources pkgRes = getPackageManager().getResourcesForActivity(cn);
+ final int nameResId = metaData.getInt(CHIP_LABEL_METADATA_KEY);
+ name = pkgRes.getString(nameResId);
+ final int resId = metaData.getInt(CHIP_ICON_METADATA_KEY);
+ icon = pkgRes.getDrawable(resId);
+ } catch (Resources.NotFoundException ex) {
+ } catch (NameNotFoundException ex) {
+ }
+ }
+ if (TextUtils.isEmpty(name)) {
+ name = ri.loadLabel(getPackageManager());
+ }
+ if (icon == null) {
+ icon = ri.loadIcon(getPackageManager());
+ }
+
+ final DisplayResolveInfo dri = new DisplayResolveInfo(
+ originalIntent, ri, name, "", resolveIntent, null);
+ dri.setDisplayIcon(icon);
+ return dri;
+ }
+
+ private Button createActionButton(Drawable icon, CharSequence title, View.OnClickListener r) {
+ Button b = (Button) LayoutInflater.from(this).inflate(R.layout.chooser_action_button, null);
+ if (icon != null) {
+ final int size = getResources()
+ .getDimensionPixelSize(R.dimen.chooser_action_button_icon_size);
+ icon.setBounds(0, 0, size, size);
+ b.setCompoundDrawablesRelative(icon, null, null, null);
+ }
+ b.setText(title);
+ b.setOnClickListener(r);
+ return b;
+ }
+
+ private Button createCopyButton() {
+ final Button b = createActionButton(
+ getDrawable(R.drawable.ic_menu_copy_material),
+ getString(R.string.copy), this::onCopyButtonClicked);
+ b.setId(R.id.chooser_copy_button);
+ return b;
+ }
+
+ private @Nullable Button createNearbyButton(Intent originalIntent) {
+ final TargetInfo ti = getNearbySharingTarget(originalIntent);
+ if (ti == null) return null;
+
+ return createActionButton(
+ ti.getDisplayIcon(this),
+ ti.getDisplayLabel(),
+ (View unused) -> {
+ safelyStartActivity(ti);
+ finish();
+ }
+ );
+ }
+
+ private void addActionButton(ViewGroup parent, Button b) {
+ if (b == null) return;
+ final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ );
+ final int gap = getResources().getDimensionPixelSize(R.dimen.resolver_icon_margin) / 2;
+ lp.setMarginsRelative(gap, 0, gap, 0);
+ parent.addView(b, lp);
+ }
+
private ViewGroup displayContentPreview(@ContentPreviewType int previewType,
Intent targetIntent, LayoutInflater layoutInflater, ViewGroup parent) {
ViewGroup layout = null;
@@ -995,8 +1127,10 @@ public class ChooserActivity extends ResolverActivity implements
ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate(
R.layout.chooser_grid_preview_text, parent, false);
- contentPreviewLayout.findViewById(R.id.copy_button).setOnClickListener(
- this::onCopyButtonClicked);
+ final ViewGroup actionRow =
+ (ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row);
+ addActionButton(actionRow, createCopyButton());
+ addActionButton(actionRow, createNearbyButton(targetIntent));
CharSequence sharingText = targetIntent.getCharSequenceExtra(Intent.EXTRA_TEXT);
if (sharingText == null) {
@@ -1154,7 +1288,8 @@ public class ChooserActivity extends ResolverActivity implements
// TODO(b/120417119): Disable file copy until after moving to sysui,
// due to permissions issues
- contentPreviewLayout.findViewById(R.id.file_copy_button).setVisibility(View.GONE);
+ //((ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row))
+ // .addView(createCopyButton());
String action = targetIntent.getAction();
if (Intent.ACTION_SEND.equals(action)) {
@@ -1680,7 +1815,7 @@ public class ChooserActivity extends ResolverActivity implements
}
return intentFilter;
} catch (Exception e) {
- Log.e(TAG, "failed to get target intent filter " + e);
+ Log.e(TAG, "failed to get target intent filter", e);
return null;
}
}
@@ -2337,10 +2472,10 @@ public class ChooserActivity extends ResolverActivity implements
}
@Override // ResolverListCommunicator
- public void onHandlePackagesChanged() {
+ public void onHandlePackagesChanged(ResolverListAdapter listAdapter) {
mServicesRequested.clear();
mChooserMultiProfilePagerAdapter.getActiveListAdapter().notifyDataSetChanged();
- super.onHandlePackagesChanged();
+ super.onHandlePackagesChanged(listAdapter);
}
@Override // SelectableTargetInfoCommunicator
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index ca3b7e7a7837..74ae29117b59 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -19,7 +19,6 @@ package com.android.internal.app;
import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE;
import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER;
-import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.prediction.AppPredictor;
import android.content.ComponentName;
@@ -176,7 +175,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
Log.d(TAG, "clearing queryTargets on package change");
}
createPlaceHolders();
- mChooserListCommunicator.onHandlePackagesChanged();
+ mChooserListCommunicator.onHandlePackagesChanged(this);
}
@@ -541,7 +540,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
@Override
AsyncTask<List<ResolvedComponentInfo>,
Void,
- List<ResolvedComponentInfo>> createSortingTask() {
+ List<ResolvedComponentInfo>> createSortingTask(boolean doPostProcessing) {
return new AsyncTask<List<ResolvedComponentInfo>,
Void,
List<ResolvedComponentInfo>>() {
@@ -554,9 +553,11 @@ public class ChooserListAdapter extends ResolverListAdapter {
}
@Override
protected void onPostExecute(List<ResolvedComponentInfo> sortedComponents) {
- processSortedList(sortedComponents);
- mChooserListCommunicator.updateProfileViewButton();
- notifyDataSetChanged();
+ processSortedList(sortedComponents, doPostProcessing);
+ if (doPostProcessing) {
+ mChooserListCommunicator.updateProfileViewButton();
+ notifyDataSetChanged();
+ }
}
};
}
diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
index 663e0255feb9..e3501422f915 100644
--- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
@@ -38,8 +38,10 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd
private final ChooserProfileDescriptor[] mItems;
ChooserMultiProfilePagerAdapter(Context context,
- ChooserActivity.ChooserGridAdapter adapter) {
- super(context, /* currentPage */ 0);
+ ChooserActivity.ChooserGridAdapter adapter,
+ UserHandle personalProfileUserHandle,
+ UserHandle workProfileUserHandle) {
+ super(context, /* currentPage */ 0, personalProfileUserHandle, workProfileUserHandle);
mItems = new ChooserProfileDescriptor[] {
createProfileDescriptor(adapter)
};
@@ -48,8 +50,11 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd
ChooserMultiProfilePagerAdapter(Context context,
ChooserActivity.ChooserGridAdapter personalAdapter,
ChooserActivity.ChooserGridAdapter workAdapter,
- @Profile int defaultProfile) {
- super(context, /* currentPage */ defaultProfile);
+ @Profile int defaultProfile,
+ UserHandle personalProfileUserHandle,
+ UserHandle workProfileUserHandle) {
+ super(context, /* currentPage */ defaultProfile, personalProfileUserHandle,
+ workProfileUserHandle);
mItems = new ChooserProfileDescriptor[] {
createProfileDescriptor(personalAdapter),
createProfileDescriptor(workAdapter)
@@ -131,6 +136,17 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd
}
@Override
+ public ResolverListAdapter getPersonalListAdapter() {
+ return getAdapterForIndex(PROFILE_PERSONAL).getListAdapter();
+ }
+
+ @Override
+ @Nullable
+ public ResolverListAdapter getWorkListAdapter() {
+ return getAdapterForIndex(PROFILE_WORK).getListAdapter();
+ }
+
+ @Override
ChooserActivity.ChooserGridAdapter getCurrentRootAdapter() {
return getAdapterForIndex(getCurrentPage());
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 30a41d338806..051534cc3eb1 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -16,7 +16,9 @@
package com.android.internal.app;
+import static android.Manifest.permission.INTERACT_ACROSS_PROFILES;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.PermissionChecker.PID_UNKNOWN;
import static com.android.internal.app.AbstractMultiProfilePagerAdapter.PROFILE_PERSONAL;
import static com.android.internal.app.AbstractMultiProfilePagerAdapter.PROFILE_WORK;
@@ -36,6 +38,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.PermissionChecker;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -157,7 +160,8 @@ public class ResolverActivity extends Activity implements
private static final String TAB_TAG_PERSONAL = "personal";
private static final String TAB_TAG_WORK = "work";
- private final PackageMonitor mPackageMonitor = createPackageMonitor();
+ private PackageMonitor mPersonalPackageMonitor;
+ private PackageMonitor mWorkPackageMonitor;
@VisibleForTesting
protected AbstractMultiProfilePagerAdapter mMultiProfilePagerAdapter;
@@ -243,11 +247,11 @@ public class ResolverActivity extends Activity implements
}
}
- protected PackageMonitor createPackageMonitor() {
+ protected PackageMonitor createPackageMonitor(ResolverListAdapter listAdapter) {
return new PackageMonitor() {
@Override
public void onSomePackagesChanged() {
- mMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged();
+ listAdapter.handlePackagesChanged();
updateProfileViewButton();
}
@@ -327,8 +331,6 @@ public class ResolverActivity extends Activity implements
mPm = getPackageManager();
- mPackageMonitor.register(this, getMainLooper(), false);
- mRegistered = true;
mReferrerPackage = getReferrerPackageName();
// Add our initial intent as the first item, regardless of what else has already been added.
@@ -353,6 +355,18 @@ public class ResolverActivity extends Activity implements
return;
}
+ mPersonalPackageMonitor = createPackageMonitor(
+ mMultiProfilePagerAdapter.getPersonalListAdapter());
+ mPersonalPackageMonitor.register(
+ this, getMainLooper(), getPersonalProfileUserHandle(), false);
+ if (hasWorkProfile()) {
+ mWorkPackageMonitor = createPackageMonitor(
+ mMultiProfilePagerAdapter.getWorkListAdapter());
+ mWorkPackageMonitor.register(this, getMainLooper(), getWorkProfileUserHandle(), false);
+ }
+
+ mRegistered = true;
+
final ResolverDrawerLayout rdl = findViewById(R.id.contentPanel);
if (rdl != null) {
rdl.setOnDismissedListener(new ResolverDrawerLayout.OnDismissedListener() {
@@ -419,7 +433,9 @@ public class ResolverActivity extends Activity implements
/* userHandle */ UserHandle.of(UserHandle.myUserId()));
return new ResolverMultiProfilePagerAdapter(
/* context */ this,
- adapter);
+ adapter,
+ getPersonalProfileUserHandle(),
+ /* workProfileUserHandle= */ null);
}
private ResolverMultiProfilePagerAdapter createResolverMultiProfilePagerAdapterForTwoProfiles(
@@ -438,20 +454,23 @@ public class ResolverActivity extends Activity implements
== getPersonalProfileUserHandle().getIdentifier()),
mUseLayoutForBrowsables,
/* userHandle */ getPersonalProfileUserHandle());
+ UserHandle workProfileUserHandle = getWorkProfileUserHandle();
ResolverListAdapter workAdapter = createResolverListAdapter(
/* context */ this,
/* payloadIntents */ mIntents,
initialIntents,
rList,
(filterLastUsed && UserHandle.myUserId()
- == getWorkProfileUserHandle().getIdentifier()),
+ == workProfileUserHandle.getIdentifier()),
mUseLayoutForBrowsables,
- /* userHandle */ getWorkProfileUserHandle());
+ /* userHandle */ workProfileUserHandle);
return new ResolverMultiProfilePagerAdapter(
/* context */ this,
personalAdapter,
workAdapter,
- /* defaultProfile */ getCurrentProfile());
+ /* defaultProfile */ getCurrentProfile(),
+ getPersonalProfileUserHandle(),
+ getWorkProfileUserHandle());
}
protected @Profile int getCurrentProfile() {
@@ -543,9 +562,6 @@ public class ResolverActivity extends Activity implements
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged();
- if (mMultiProfilePagerAdapter.getInactiveListAdapter() != null) {
- mMultiProfilePagerAdapter.getInactiveListAdapter().handlePackagesChanged();
- }
if (mSystemWindowInsets != null) {
mResolverDrawerLayout.setPadding(mSystemWindowInsets.left, mSystemWindowInsets.top,
@@ -707,7 +723,16 @@ public class ResolverActivity extends Activity implements
protected void onRestart() {
super.onRestart();
if (!mRegistered) {
- mPackageMonitor.register(this, getMainLooper(), false);
+ mPersonalPackageMonitor.register(this, getMainLooper(),
+ getPersonalProfileUserHandle(), false);
+ if (hasWorkProfile()) {
+ if (mWorkPackageMonitor == null) {
+ mWorkPackageMonitor = createPackageMonitor(
+ mMultiProfilePagerAdapter.getWorkListAdapter());
+ }
+ mWorkPackageMonitor.register(this, getMainLooper(),
+ getWorkProfileUserHandle(), false);
+ }
mRegistered = true;
}
mMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged();
@@ -718,7 +743,10 @@ public class ResolverActivity extends Activity implements
protected void onStop() {
super.onStop();
if (mRegistered) {
- mPackageMonitor.unregister();
+ mPersonalPackageMonitor.unregister();
+ if (mWorkPackageMonitor != null) {
+ mWorkPackageMonitor.unregister();
+ }
mRegistered = false;
}
final Intent intent = getIntent();
@@ -913,26 +941,21 @@ public class ResolverActivity extends Activity implements
}
@Override // ResolverListCommunicator
- public void onPostListReady(ResolverListAdapter listAdapter) {
- if (mMultiProfilePagerAdapter.getCurrentUserHandle().getIdentifier()
- == UserHandle.myUserId()) {
- setHeader();
+ public void onPostListReady(ResolverListAdapter listAdapter, boolean doPostProcessing) {
+ if (isAutolaunching() || maybeAutolaunchActivity()) {
+ return;
}
- resetButtonBar();
- onListRebuilt(listAdapter);
- }
-
- protected void onListRebuilt(ResolverListAdapter listAdapter) {
- int count = listAdapter.getUnfilteredCount();
- if (count == 1 && listAdapter.getOtherProfile() == null) {
- // Only one target, so we're a candidate to auto-launch!
- final TargetInfo target = listAdapter.targetInfoForPosition(0, false);
- if (shouldAutoLaunchSingleChoice(target)) {
- safelyStartActivity(target);
- finish();
+ if (doPostProcessing) {
+ if (mMultiProfilePagerAdapter.getCurrentUserHandle().getIdentifier()
+ == UserHandle.myUserId()) {
+ setHeader();
}
+ resetButtonBar();
+ onListRebuilt(listAdapter);
}
+ }
+ protected void onListRebuilt(ResolverListAdapter listAdapter) {
final ItemClickListener listener = new ItemClickListener();
setupAdapterListView((ListView) mMultiProfilePagerAdapter.getActiveAdapterView(), listener);
}
@@ -1132,6 +1155,11 @@ public class ResolverActivity extends Activity implements
}
private void safelyStartActivityInternal(TargetInfo cti) {
+ mPersonalPackageMonitor.unregister();
+ if (mWorkPackageMonitor != null) {
+ mWorkPackageMonitor.unregister();
+ }
+ mRegistered = false;
// If needed, show that intent is forwarded
// from managed profile to owner or other way around.
if (mProfileSwitchMessageId != -1) {
@@ -1247,7 +1275,11 @@ public class ResolverActivity extends Activity implements
throw new IllegalStateException("mMultiProfilePagerAdapter.getCurrentListAdapter() "
+ "cannot be null.");
}
- boolean rebuildCompleted = mMultiProfilePagerAdapter.getActiveListAdapter().rebuildList();
+ boolean rebuildCompleted = mMultiProfilePagerAdapter.rebuildActiveTab(true);
+
+ // We partially rebuild the inactive adapter to determine if we should auto launch
+ mMultiProfilePagerAdapter.rebuildInactiveTab(false);
+
if (useLayoutWithDefault()) {
mLayoutId = R.layout.resolver_list_with_default;
} else {
@@ -1274,25 +1306,12 @@ public class ResolverActivity extends Activity implements
* @return <code>true</code> if the activity is finishing and creation should halt.
*/
final boolean postRebuildListInternal(boolean rebuildCompleted) {
-
int count = mMultiProfilePagerAdapter.getActiveListAdapter().getUnfilteredCount();
// We only rebuild asynchronously when we have multiple elements to sort. In the case where
// we're already done, we can check if we should auto-launch immediately.
- if (rebuildCompleted) {
- if (count == 1
- && mMultiProfilePagerAdapter.getActiveListAdapter().getOtherProfile() == null) {
- // Only one target, so we're a candidate to auto-launch!
- final TargetInfo target = mMultiProfilePagerAdapter.getActiveListAdapter()
- .targetInfoForPosition(0, false);
- if (shouldAutoLaunchSingleChoice(target)) {
- safelyStartActivity(target);
- mPackageMonitor.unregister();
- mRegistered = false;
- finish();
- return true;
- }
- }
+ if (rebuildCompleted && maybeAutolaunchActivity()) {
+ return true;
}
setupViewVisibilities();
@@ -1304,6 +1323,129 @@ public class ResolverActivity extends Activity implements
return false;
}
+ private int isPermissionGranted(String permission, int uid) {
+ return ActivityManager.checkComponentPermission(permission, uid,
+ /* owningUid= */-1, /* exported= */ true);
+ }
+
+ /**
+ * @return {@code true} if a resolved target is autolaunched, otherwise {@code false}
+ */
+ private boolean maybeAutolaunchActivity() {
+ int numberOfProfiles = mMultiProfilePagerAdapter.getItemCount();
+ if (numberOfProfiles == 1 && maybeAutolaunchIfSingleTarget()) {
+ return true;
+ } else if (numberOfProfiles == 2 && maybeAutolaunchIfCrossProfileSupported()) {
+ // note that autolaunching when we have 2 profiles, 1 resolved target on the active
+ // tab and 0 resolved targets on the inactive tab, is already handled before launching
+ // ResolverActivity
+ return true;
+ }
+ return false;
+ }
+
+ private boolean maybeAutolaunchIfSingleTarget() {
+ int count = mMultiProfilePagerAdapter.getActiveListAdapter().getUnfilteredCount();
+ if (count != 1) {
+ return false;
+ }
+
+ // Only one target, so we're a candidate to auto-launch!
+ final TargetInfo target = mMultiProfilePagerAdapter.getActiveListAdapter()
+ .targetInfoForPosition(0, false);
+ if (shouldAutoLaunchSingleChoice(target)) {
+ safelyStartActivity(target);
+ finish();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * When we have a personal and a work profile, we auto launch in the following scenario:
+ * - There is 1 resolved target on each profile
+ * - That target is the same app on both profiles
+ * - The target app has permission to communicate cross profiles
+ * - The target app has declared it supports cross-profile communication via manifest metadata
+ */
+ private boolean maybeAutolaunchIfCrossProfileSupported() {
+ int count = mMultiProfilePagerAdapter.getActiveListAdapter().getUnfilteredCount();
+ if (count != 1) {
+ return false;
+ }
+ ResolverListAdapter inactiveListAdapter =
+ mMultiProfilePagerAdapter.getInactiveListAdapter();
+ if (inactiveListAdapter.getUnfilteredCount() != 1) {
+ return false;
+ }
+ TargetInfo activeProfileTarget = mMultiProfilePagerAdapter.getActiveListAdapter()
+ .targetInfoForPosition(0, false);
+ TargetInfo inactiveProfileTarget = inactiveListAdapter.targetInfoForPosition(0, false);
+ if (!Objects.equals(activeProfileTarget.getResolvedComponentName(),
+ inactiveProfileTarget.getResolvedComponentName())) {
+ return false;
+ }
+ if (!shouldAutoLaunchSingleChoice(activeProfileTarget)) {
+ return false;
+ }
+ String packageName = activeProfileTarget.getResolvedComponentName().getPackageName();
+ if (!canAppInteractCrossProfiles(packageName)) {
+ return false;
+ }
+
+ safelyStartActivity(activeProfileTarget);
+ finish();
+ return true;
+ }
+
+ /**
+ * Returns whether the package has the necessary permissions to interact across profiles on
+ * behalf of a given user.
+ *
+ * <p>This means meeting the following condition:
+ * <ul>
+ * <li>The app's {@link ApplicationInfo#crossProfile} flag must be true, and at least
+ * one of the following conditions must be fulfilled</li>
+ * <li>{@code Manifest.permission.INTERACT_ACROSS_USERS_FULL} granted.</li>
+ * <li>{@code Manifest.permission.INTERACT_ACROSS_USERS} granted.</li>
+ * <li>{@code Manifest.permission.INTERACT_ACROSS_PROFILES} granted, or the corresponding
+ * AppOps {@code android:interact_across_profiles} is set to "allow".</li>
+ * </ul>
+ *
+ */
+ private boolean canAppInteractCrossProfiles(String packageName) {
+ ApplicationInfo applicationInfo;
+ try {
+ applicationInfo = getPackageManager().getApplicationInfo(packageName, 0);
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Package " + packageName + " does not exist on current user.");
+ return false;
+ }
+ if (!applicationInfo.crossProfile) {
+ return false;
+ }
+
+ int packageUid = applicationInfo.uid;
+
+ if (isPermissionGranted(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ packageUid) == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ if (isPermissionGranted(android.Manifest.permission.INTERACT_ACROSS_USERS, packageUid)
+ == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ if (PermissionChecker.checkPermissionForPreflight(this, INTERACT_ACROSS_PROFILES,
+ PID_UNKNOWN, packageUid, packageName) == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isAutolaunching() {
+ return !mRegistered && isFinishing();
+ }
+
private void setupProfileTabs() {
TabHost tabHost = findViewById(R.id.profile_tabhost);
tabHost.setup();
@@ -1499,12 +1641,20 @@ public class ResolverActivity extends Activity implements
}
@Override // ResolverListCommunicator
- public void onHandlePackagesChanged() {
- ResolverListAdapter activeListAdapter = mMultiProfilePagerAdapter.getActiveListAdapter();
- activeListAdapter.rebuildList();
- if (activeListAdapter.getCount() == 0) {
- // We no longer have any items... just finish the activity.
- finish();
+ public void onHandlePackagesChanged(ResolverListAdapter listAdapter) {
+ if (listAdapter == mMultiProfilePagerAdapter.getActiveListAdapter()) {
+ boolean listRebuilt = mMultiProfilePagerAdapter.rebuildActiveTab(true);
+ if (listRebuilt) {
+ ResolverListAdapter activeListAdapter =
+ mMultiProfilePagerAdapter.getActiveListAdapter();
+ activeListAdapter.notifyDataSetChanged();
+ if (activeListAdapter.getCount() == 0) {
+ // We no longer have any items... just finish the activity.
+ finish();
+ }
+ }
+ } else {
+ mMultiProfilePagerAdapter.clearInactiveProfileCache();
}
}
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index 405112d99fe7..2321da14cebe 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -113,7 +113,7 @@ public class ResolverListAdapter extends BaseAdapter {
}
public void handlePackagesChanged() {
- mResolverListCommunicator.onHandlePackagesChanged();
+ mResolverListCommunicator.onHandlePackagesChanged(this);
}
public void setPlaceholderCount(int count) {
@@ -176,9 +176,14 @@ public class ResolverListAdapter extends BaseAdapter {
* Rebuild the list of resolvers. In some cases some parts will need some asynchronous work
* to complete.
*
+ * The {@code doPostProcessing } parameter is used to specify whether to update the UI and
+ * load additional targets (e.g. direct share) after the list has been rebuilt. This is used
+ * in the case where we want to load the inactive profile's resolved apps to know the
+ * number of targets.
+ *
* @return Whether or not the list building is completed.
*/
- protected boolean rebuildList() {
+ protected boolean rebuildList(boolean doPostProcessing) {
List<ResolvedComponentInfo> currentResolveList = null;
// Clear the value of mOtherProfile from previous call.
mOtherProfile = null;
@@ -186,6 +191,7 @@ public class ResolverListAdapter extends BaseAdapter {
mLastChosenPosition = -1;
mAllTargetsAreBrowsers = false;
mDisplayList.clear();
+
if (mBaseResolveList != null) {
currentResolveList = mUnfilteredResolveList = new ArrayList<>();
mResolverListController.addResolveListDedupe(currentResolveList,
@@ -198,7 +204,7 @@ public class ResolverListAdapter extends BaseAdapter {
mResolverListCommunicator.shouldGetActivityMetadata(),
mIntents);
if (currentResolveList == null) {
- processSortedList(currentResolveList);
+ processSortedList(currentResolveList, doPostProcessing);
return true;
}
List<ResolvedComponentInfo> originalList =
@@ -256,22 +262,22 @@ public class ResolverListAdapter extends BaseAdapter {
--placeholderCount;
}
setPlaceholderCount(placeholderCount);
- createSortingTask().execute(currentResolveList);
- postListReadyRunnable();
+ createSortingTask(doPostProcessing).execute(currentResolveList);
+ postListReadyRunnable(doPostProcessing);
return false;
} else {
- processSortedList(currentResolveList);
+ processSortedList(currentResolveList, doPostProcessing);
return true;
}
} else {
- processSortedList(currentResolveList);
+ processSortedList(currentResolveList, doPostProcessing);
return true;
}
}
AsyncTask<List<ResolvedComponentInfo>,
Void,
- List<ResolvedComponentInfo>> createSortingTask() {
+ List<ResolvedComponentInfo>> createSortingTask(boolean doPostProcessing) {
return new AsyncTask<List<ResolvedComponentInfo>,
Void,
List<ResolvedComponentInfo>>() {
@@ -283,15 +289,17 @@ public class ResolverListAdapter extends BaseAdapter {
}
@Override
protected void onPostExecute(List<ResolvedComponentInfo> sortedComponents) {
- processSortedList(sortedComponents);
- mResolverListCommunicator.updateProfileViewButton();
+ processSortedList(sortedComponents, doPostProcessing);
notifyDataSetChanged();
+ if (doPostProcessing) {
+ mResolverListCommunicator.updateProfileViewButton();
+ }
}
};
}
-
- protected void processSortedList(List<ResolvedComponentInfo> sortedComponents) {
+ protected void processSortedList(List<ResolvedComponentInfo> sortedComponents,
+ boolean doPostProcessing) {
int n;
if (sortedComponents != null && (n = sortedComponents.size()) != 0) {
mAllTargetsAreBrowsers = mUseLayoutForBrowsables;
@@ -343,20 +351,23 @@ public class ResolverListAdapter extends BaseAdapter {
}
mResolverListCommunicator.sendVoiceChoicesIfNeeded();
- postListReadyRunnable();
+ postListReadyRunnable(doPostProcessing);
}
/**
* Some necessary methods for creating the list are initiated in onCreate and will also
* determine the layout known. We therefore can't update the UI inline and post to the
* handler thread to update after the current task is finished.
+ * @param doPostProcessing Whether to update the UI and load additional direct share targets
+ * after the list has been rebuilt
*/
- void postListReadyRunnable() {
+ void postListReadyRunnable(boolean doPostProcessing) {
if (mPostListReadyRunnable == null) {
mPostListReadyRunnable = new Runnable() {
@Override
public void run() {
- mResolverListCommunicator.onPostListReady(ResolverListAdapter.this);
+ mResolverListCommunicator.onPostListReady(ResolverListAdapter.this,
+ doPostProcessing);
mPostListReadyRunnable = null;
}
};
@@ -590,6 +601,12 @@ public class ResolverListAdapter extends BaseAdapter {
return mResolverListController.getUserHandle();
}
+ protected List<ResolvedComponentInfo> getResolversForUser(UserHandle userHandle) {
+ return mResolverListController.getResolversForIntentAsUser(true,
+ mResolverListCommunicator.shouldGetActivityMetadata(),
+ mIntents, userHandle);
+ }
+
/**
* Necessary methods to communicate between {@link ResolverListAdapter}
* and {@link ResolverActivity}.
@@ -600,7 +617,7 @@ public class ResolverListAdapter extends BaseAdapter {
Intent getReplacementIntent(ActivityInfo activityInfo, Intent defIntent);
- void onPostListReady(ResolverListAdapter listAdapter);
+ void onPostListReady(ResolverListAdapter listAdapter, boolean updateUi);
void sendVoiceChoicesIfNeeded();
@@ -612,7 +629,7 @@ public class ResolverListAdapter extends BaseAdapter {
Intent getTargetIntent();
- void onHandlePackagesChanged();
+ void onHandlePackagesChanged(ResolverListAdapter listAdapter);
}
static class ViewHolder {
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 0bfe9eb04d28..022aded188fa 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -111,6 +111,15 @@ public class ResolverListController {
boolean shouldGetResolvedFilter,
boolean shouldGetActivityMetadata,
List<Intent> intents) {
+ return getResolversForIntentAsUser(shouldGetResolvedFilter, shouldGetActivityMetadata,
+ intents, mUserHandle);
+ }
+
+ public List<ResolverActivity.ResolvedComponentInfo> getResolversForIntentAsUser(
+ boolean shouldGetResolvedFilter,
+ boolean shouldGetActivityMetadata,
+ List<Intent> intents,
+ UserHandle userHandle) {
List<ResolverActivity.ResolvedComponentInfo> resolvedComponents = null;
for (int i = 0, N = intents.size(); i < N; i++) {
final Intent intent = intents.get(i);
@@ -122,7 +131,7 @@ public class ResolverListController {
flags |= PackageManager.MATCH_INSTANT;
}
final List<ResolveInfo> infos = mpm.queryIntentActivitiesAsUser(intent, flags,
- mUserHandle);
+ userHandle);
if (infos != null) {
if (resolvedComponents == null) {
resolvedComponents = new ArrayList<>();
diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
index 9d3c6c9ad8b1..96dc83a3f683 100644
--- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
@@ -36,8 +36,10 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA
private final ResolverProfileDescriptor[] mItems;
ResolverMultiProfilePagerAdapter(Context context,
- ResolverListAdapter adapter) {
- super(context, /* currentPage */ 0);
+ ResolverListAdapter adapter,
+ UserHandle personalProfileUserHandle,
+ UserHandle workProfileUserHandle) {
+ super(context, /* currentPage */ 0, personalProfileUserHandle, workProfileUserHandle);
mItems = new ResolverProfileDescriptor[] {
createProfileDescriptor(adapter)
};
@@ -46,8 +48,11 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA
ResolverMultiProfilePagerAdapter(Context context,
ResolverListAdapter personalAdapter,
ResolverListAdapter workAdapter,
- @Profile int defaultProfile) {
- super(context, /* currentPage */ defaultProfile);
+ @Profile int defaultProfile,
+ UserHandle personalProfileUserHandle,
+ UserHandle workProfileUserHandle) {
+ super(context, /* currentPage */ defaultProfile, personalProfileUserHandle,
+ workProfileUserHandle);
mItems = new ResolverProfileDescriptor[] {
createProfileDescriptor(personalAdapter),
createProfileDescriptor(workAdapter)
@@ -116,6 +121,17 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA
}
@Override
+ public ResolverListAdapter getPersonalListAdapter() {
+ return getAdapterForIndex(PROFILE_PERSONAL);
+ }
+
+ @Override
+ @Nullable
+ public ResolverListAdapter getWorkListAdapter() {
+ return getAdapterForIndex(PROFILE_WORK);
+ }
+
+ @Override
ResolverListAdapter getCurrentRootAdapter() {
return getActiveListAdapter();
}
diff --git a/core/java/com/android/internal/logging/InstanceId.java b/core/java/com/android/internal/logging/InstanceId.java
index 85dbac3f59bb..85643fcffa2f 100644
--- a/core/java/com/android/internal/logging/InstanceId.java
+++ b/core/java/com/android/internal/logging/InstanceId.java
@@ -16,20 +16,33 @@
package com.android.internal.logging;
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+
import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
import com.android.internal.annotations.VisibleForTesting;
/**
* An opaque identifier used to disambiguate which logs refer to a particular instance of some
* UI element. Useful when there might be multiple instances simultaneously active.
- * Obtain from InstanceIdSequence.
+ * Obtain from InstanceIdSequence. Clipped to range [0, INSTANCE_ID_MAX].
*/
-public class InstanceId {
- private int mId;
- protected InstanceId(int id) {
- mId = id;
+public final class InstanceId implements Parcelable {
+ // At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values
+ static final int INSTANCE_ID_MAX = 1 << 20;
+
+ private final int mId;
+ InstanceId(int id) {
+ mId = min(max(0, id), INSTANCE_ID_MAX);
+ }
+
+ private InstanceId(Parcel in) {
+ this(in.readInt());
}
+
@VisibleForTesting
public int getId() {
return mId;
@@ -47,4 +60,28 @@ public class InstanceId {
}
return mId == ((InstanceId) obj).mId;
}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(mId);
+ }
+
+ public static final Parcelable.Creator<InstanceId> CREATOR =
+ new Parcelable.Creator<InstanceId>() {
+ @Override
+ public InstanceId createFromParcel(Parcel in) {
+ return new InstanceId(in);
+ }
+
+ @Override
+ public InstanceId[] newArray(int size) {
+ return new InstanceId[size];
+ }
+ };
+
}
diff --git a/core/java/com/android/internal/logging/InstanceIdSequence.java b/core/java/com/android/internal/logging/InstanceIdSequence.java
index 2e78ed8c5185..aa507e538944 100644
--- a/core/java/com/android/internal/logging/InstanceIdSequence.java
+++ b/core/java/com/android/internal/logging/InstanceIdSequence.java
@@ -19,6 +19,8 @@ package com.android.internal.logging;
import static java.lang.Math.max;
import static java.lang.Math.min;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.security.SecureRandom;
import java.util.Random;
@@ -28,8 +30,6 @@ import java.util.Random;
* first use; try to give it a long lifetime. Safe for concurrent use.
*/
public class InstanceIdSequence {
- // At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values
- private static final int INSTANCE_ID_MAX = 1 << 20;
protected final int mInstanceIdMax;
private final Random mRandom = new SecureRandom();
@@ -39,7 +39,7 @@ public class InstanceIdSequence {
* an all-zero sequence.
*/
public InstanceIdSequence(int instanceIdMax) {
- mInstanceIdMax = min(max(0, instanceIdMax), INSTANCE_ID_MAX);
+ mInstanceIdMax = min(max(0, instanceIdMax), InstanceId.INSTANCE_ID_MAX);
}
/**
@@ -47,6 +47,16 @@ public class InstanceIdSequence {
* @return new InstanceId
*/
public InstanceId newInstanceId() {
- return new InstanceId(mRandom.nextInt(mInstanceIdMax));
+ return newInstanceIdInternal(mRandom.nextInt(mInstanceIdMax));
+ }
+
+ /**
+ * Factory function for instance IDs, used for testing.
+ * @param id
+ * @return new InstanceId(id)
+ */
+ @VisibleForTesting
+ protected InstanceId newInstanceIdInternal(int id) {
+ return new InstanceId(id);
}
}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 7adb27cd9e36..db009f68d28a 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -468,7 +468,8 @@ public class RuntimeInit {
try {
if (ActivityManager.getService().handleApplicationWtf(
mApplicationObject, tag, system,
- new ApplicationErrorReport.ParcelableCrashInfo(t))) {
+ new ApplicationErrorReport.ParcelableCrashInfo(t),
+ Process.myPid())) {
// The Activity Manager has already written us off -- now exit.
Process.killProcess(Process.myPid());
System.exit(10);
diff --git a/core/res/res/drawable-hdpi/sym_app_on_sd_unavailable_icon.png b/core/res/res/drawable-hdpi/sym_app_on_sd_unavailable_icon.png
deleted file mode 100644
index d915d416ff30..000000000000
--- a/core/res/res/drawable-hdpi/sym_app_on_sd_unavailable_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_app_on_sd_unavailable_icon.png b/core/res/res/drawable-ldpi/sym_app_on_sd_unavailable_icon.png
deleted file mode 100644
index d88250ae2325..000000000000
--- a/core/res/res/drawable-ldpi/sym_app_on_sd_unavailable_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_app_on_sd_unavailable_icon.png b/core/res/res/drawable-mdpi/sym_app_on_sd_unavailable_icon.png
deleted file mode 100644
index 47306683f374..000000000000
--- a/core/res/res/drawable-mdpi/sym_app_on_sd_unavailable_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/sym_app_on_sd_unavailable_icon.png b/core/res/res/drawable-xhdpi/sym_app_on_sd_unavailable_icon.png
deleted file mode 100644
index e4e6a5a70df2..000000000000
--- a/core/res/res/drawable-xhdpi/sym_app_on_sd_unavailable_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/chooser_action_button_bg.xml b/core/res/res/drawable/chooser_action_button_bg.xml
new file mode 100644
index 000000000000..a434c0b9b6a9
--- /dev/null
+++ b/core/res/res/drawable/chooser_action_button_bg.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="@color/lighter_gray">
+ <item>
+ <inset
+ android:insetLeft="0dp"
+ android:insetTop="8dp"
+ android:insetRight="0dp"
+ android:insetBottom="8dp">
+ <shape android:shape="rectangle">
+ <corners android:radius="16dp"></corners>
+ <stroke android:width="1dp"
+ android:color="?attr/textColorSecondary" />
+ <solid android:color="?attr/colorBackground" />
+ </shape>
+ </inset>
+ </item>
+</ripple>
diff --git a/core/res/res/drawable/ic_content_copy_gm2.xml b/core/res/res/drawable/ic_content_copy_gm2.xml
deleted file mode 100644
index ee58738b75d0..000000000000
--- a/core/res/res/drawable/ic_content_copy_gm2.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:fillColor="?android:attr/textColorSecondary"
- android:pathData="M18,21L4,21L4,7L2,7v14c0,1.1 0.9,2 2,2h14v-2zM21,17L21,3c0,-1.1 -0.9,-2 -2,-2L8,1c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2zM19,17L8,17L8,3h11v14z"/>
-</vector>
diff --git a/core/res/res/drawable/ic_menu_copy_material.xml b/core/res/res/drawable/ic_menu_copy_material.xml
index c03723b1fb33..8c9f1c514b97 100644
--- a/core/res/res/drawable/ic_menu_copy_material.xml
+++ b/core/res/res/drawable/ic_menu_copy_material.xml
@@ -1,26 +1,27 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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
+ 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
+ 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.
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"
- android:autoMirrored="true"
- android:tint="?attr/colorControlNormal">
- <path
- android:pathData="M16,1L4,1C2.9,1 2,1.9 2,3l0,14l2,0L4,3l12,0L16,1zM19,5L8,5C6.9,5 6,5.9 6,7l0,14c0,1.1 0.9,2 2,2l11,0c1.1,0 2,-0.9 2,-2L21,7C21,5.9 20.1,5 19,5zM19,21L8,21L8,7l11,0L19,21z"
- android:fillColor="@color/white"/>
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:autoMirrored="true"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@color/white"
+ android:pathData="M18,21L4,21L4,7L2,7v14c0,1.1 0.9,2 2,2h14v-2zM21,17L21,3c0,-1.1 -0.9,-2 -2,-2L8,1c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2zM19,17L8,17L8,3h11v14z"/>
</vector>
diff --git a/core/res/res/drawable/sym_app_on_sd_unavailable_icon.xml b/core/res/res/drawable/sym_app_on_sd_unavailable_icon.xml
new file mode 100644
index 000000000000..50f15cab1814
--- /dev/null
+++ b/core/res/res/drawable/sym_app_on_sd_unavailable_icon.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+ <background android:drawable="@drawable/sym_def_app_icon_background" />
+ <foreground >
+ <vector
+ android:height="108dp"
+ android:width="108dp"
+ android:viewportHeight="108.0"
+ android:viewportWidth="108.0">
+ <path android:fillColor="#202124" android:pathData="
+M68,54h-7.25L54,60.75V76c0,2.2,1.8,4,4,4h10c2.2,0,4-1.8,4-4V58C72,55.8,70.2,54,68,54z"/>
+
+ <path android:fillColor="#FFFFFF" android:pathData="
+M64.59,34.48l3.9-3.9c0.6-0.6,0.6-1.53,0-2.13c-0.6-0.6-1.53-0.6-2.13,0l-4.44,4.44
+C59.55,31.69,56.85,31,54,31c-2.88,0-5.58,0.69-7.98,1.89l-4.47-4.44c-0.6-0.6-1.53-0.6-2.13,0c-0.6,0.6-0.6,1.53,0,2.13l3.93,3.93
+C38.91,37.78,36,43.03,36,49h36C72,43.03,69.09,37.75,64.59,34.48z M48,43h-3v-3h3V43z M63,43h-3v-3h3V43z
+
+M52,76.01C52,76,52,76,52,76.01l0-15.26v-0.83l0,0v-0.01h0.01l0.58-0.58l6.75-6.75L59.92,52v0H40
+c-2.21,0-4,1.79-4,4v20c0,2.21,1.79,4,4,4h12V76.01z
+
+M66.84,68.75h-2.81v6.75h2.81c0.93,0,1.69-0.75,1.69-1.69v-3.38C68.52,69.5,67.77,68.75,66.84,68.75z
+M66.84,73.81h-1.12v-3.38h1.12V73.81z
+
+M63.02,70.16h-3.09v1.27h1.97c0.62,0,1.12,0.64,1.12,1.26v1.69c0,0.62-0.51,1.12-1.12,1.12h-3.38v-1.41
+h3.09v-1.27h-1.96c-0.62,0-1.12-0.64-1.12-1.26v-1.69c0-0.62,0.51-1.12,1.12-1.12h3.36V70.16z"/>
+
+ <path android:fillColor="#FFE082" android:pathData="
+M 59 58.5 h 2.5 v 4.5 h -2.5z
+M 62.5 58.5 h 2.5 v 4.5 h -2.5z
+M 66 58.5 h 2.5 v 4.5 h -2.5z"/>
+ </vector>
+ </foreground>
+</adaptive-icon>
diff --git a/core/res/res/layout/chooser_action_button.xml b/core/res/res/layout/chooser_action_button.xml
new file mode 100644
index 000000000000..119b2e90292d
--- /dev/null
+++ b/core/res/res/layout/chooser_action_button.xml
@@ -0,0 +1,30 @@
+<!--
+ ~ 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
+ -->
+
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+ android:gravity="center_vertical|start"
+ android:paddingStart="12dp"
+ android:paddingEnd="12dp"
+ android:drawablePadding="8dp"
+ android:textColor="?android:textColorSecondary"
+ android:textSize="12sp"
+ android:maxWidth="192dp"
+ android:singleLine="true"
+ android:clickable="true"
+ android:background="@drawable/chooser_action_button_bg"
+ android:drawableTint="?android:attr/colorControlNormal"
+ android:drawableTintMode="src_in"
+ />
diff --git a/core/res/res/layout/chooser_action_row.xml b/core/res/res/layout/chooser_action_row.xml
new file mode 100644
index 000000000000..ea7561124181
--- /dev/null
+++ b/core/res/res/layout/chooser_action_row.xml
@@ -0,0 +1,26 @@
+<!--
+ ~ 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
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/chooser_edge_margin_normal"
+ android:paddingRight="@dimen/chooser_edge_margin_normal"
+ android:gravity="center"
+ >
+
+</LinearLayout>
diff --git a/core/res/res/layout/chooser_grid_preview_file.xml b/core/res/res/layout/chooser_grid_preview_file.xml
index f7d60c91052d..2a39215a4bd8 100644
--- a/core/res/res/layout/chooser_grid_preview_file.xml
+++ b/core/res/res/layout/chooser_grid_preview_file.xml
@@ -65,13 +65,15 @@
android:gravity="start|top"
android:paddingRight="24dp"
android:singleLine="true"/>
- <Button
- android:id="@+id/file_copy_button"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:gravity="center"
- android:layout_gravity="center_vertical"
- android:background="@drawable/ic_content_copy_gm2"/>
</LinearLayout>
+
+ <include
+ android:id="@+id/chooser_action_row"
+ layout="@layout/chooser_action_row"
+ android:layout_width="@dimen/chooser_preview_width"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/chooser_view_spacing"
+ android:layout_gravity="center"
+ />
</LinearLayout>
diff --git a/core/res/res/layout/chooser_grid_preview_image.xml b/core/res/res/layout/chooser_grid_preview_image.xml
index 79a0de4b271f..62df1650612a 100644
--- a/core/res/res/layout/chooser_grid_preview_image.xml
+++ b/core/res/res/layout/chooser_grid_preview_image.xml
@@ -78,5 +78,15 @@
android:scaleType="centerCrop"/>
</RelativeLayout>
+
+ <include
+ android:id="@+id/chooser_action_row"
+ layout="@layout/chooser_action_row"
+ android:layout_width="@dimen/chooser_preview_width"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/chooser_view_spacing"
+ android:layout_gravity="center"
+ />
+
</LinearLayout>
diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml
index 4d7846dfb9cc..002917463ab3 100644
--- a/core/res/res/layout/chooser_grid_preview_text.xml
+++ b/core/res/res/layout/chooser_grid_preview_text.xml
@@ -37,10 +37,9 @@
<TextView
android:id="@+id/content_preview_text"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
- android:layout_toStartOf="@id/copy_button"
android:layout_centerVertical="true"
android:ellipsize="end"
android:fontFamily="@android:string/config_headlineFontFamily"
@@ -48,40 +47,17 @@
android:maxLines="2"
android:focusable="true"/>
- <LinearLayout
- android:id="@+id/copy_button"
- android:orientation="vertical"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_alignParentEnd="true"
- android:layout_marginStart="@dimen/chooser_view_spacing"
- android:gravity="center"
- android:minWidth="48dp"
- android:minHeight="48dp"
- android:clickable="true"
- style="?attr/borderlessButtonStyle">
-
- <ImageView
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:gravity="top|center_horizontal"
- android:src="@drawable/ic_content_copy_gm2" />
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="4dp"
- android:gravity="center_horizontal"
- android:text="@string/copy"
- android:textColor="?android:textColorSecondary"
- android:textSize="12sp"
- android:maxWidth="72dp"
- android:maxLines="2"
- android:ellipsize="end" />
- </LinearLayout>
</RelativeLayout>
+ <include
+ android:id="@+id/chooser_action_row"
+ layout="@layout/chooser_action_row"
+ android:layout_width="@dimen/chooser_preview_width"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/chooser_view_spacing"
+ android:layout_gravity="center"
+ />
+
<!-- Required sub-layout so we can get the nice rounded corners-->
<!-- around this section -->
<LinearLayout
diff --git a/core/res/res/mipmap-hdpi/sym_app_on_sd_unavailable_icon.png b/core/res/res/mipmap-hdpi/sym_app_on_sd_unavailable_icon.png
deleted file mode 100644
index d915d416ff30..000000000000
--- a/core/res/res/mipmap-hdpi/sym_app_on_sd_unavailable_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/mipmap-ldpi/sym_app_on_sd_unavailable_icon.png b/core/res/res/mipmap-ldpi/sym_app_on_sd_unavailable_icon.png
deleted file mode 100644
index d88250ae2325..000000000000
--- a/core/res/res/mipmap-ldpi/sym_app_on_sd_unavailable_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/mipmap-mdpi/sym_app_on_sd_unavailable_icon.png b/core/res/res/mipmap-mdpi/sym_app_on_sd_unavailable_icon.png
deleted file mode 100644
index 47306683f374..000000000000
--- a/core/res/res/mipmap-mdpi/sym_app_on_sd_unavailable_icon.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e98f8ba3cda7..52b92d2660da 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4323,4 +4323,12 @@
<item>4</item> <!-- PROCESS_STATE_FOREGROUND_SERVICE -->
<item>12</item> <!-- PROCESS_STATE_TOP_SLEEPING -->
</integer-array>
+
+ <!-- Component name that accepts ACTION_SEND intents for nearby (proximity-based) sharing.
+ Used by ChooserActivity. -->
+ <string translatable="false" name="config_defaultNearbySharingComponent"></string>
+
+ <!-- Boolean indicating whether frameworks needs to reset cell broadcast geo-fencing
+ check after reboot or airplane mode toggling -->
+ <bool translatable="false" name="reset_geo_fencing_check_after_boot_or_apm">false</bool>
</resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index d437aa1c340c..0b5082cdaf94 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -774,6 +774,8 @@
<dimen name="resolver_edge_margin">24dp</dimen>
<dimen name="resolver_elevation">1dp</dimen>
+ <dimen name="chooser_action_button_icon_size">18dp</dimen>
+
<!-- Assistant handles -->
<dimen name="assist_handle_shadow_radius">2dp</dimen>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index ddd9ba43fe09..51ed08b88111 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -194,6 +194,9 @@
<!-- A tag used to save the index where the custom view is stored -->
<item type="id" name="notification_custom_view_index_tag" />
+ <!-- Marks the "copy to clipboard" button in the ChooserActivity -->
+ <item type="id" name="chooser_copy_button" />
+
<!-- Accessibility action identifier for {@link android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_BACK}. -->
<item type="id" name="accessibilitySystemActionBack" />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e4717f817688..21128e33b6e5 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -66,8 +66,7 @@
<java-symbol type="id" name="content_preview_text_layout" />
<java-symbol type="id" name="content_preview_title" />
<java-symbol type="id" name="content_preview_title_layout" />
- <java-symbol type="id" name="copy_button" />
- <java-symbol type="id" name="file_copy_button" />
+ <java-symbol type="id" name="chooser_action_row" />
<java-symbol type="id" name="current_scene" />
<java-symbol type="id" name="scene_layoutid_cache" />
<java-symbol type="id" name="customPanel" />
@@ -3783,6 +3782,11 @@
<java-symbol type="string" name="config_factoryResetPackage" />
<java-symbol type="array" name="config_highRefreshRateBlacklist" />
+ <java-symbol type="id" name="chooser_copy_button" />
+ <java-symbol type="layout" name="chooser_action_button" />
+ <java-symbol type="dimen" name="chooser_action_button_icon_size" />
+ <java-symbol type="string" name="config_defaultNearbySharingComponent" />
+
<java-symbol type="bool" name="config_automotiveHideNavBarForKeyboard" />
<java-symbol type="bool" name="config_showBuiltinWirelessChargingAnim" />
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index d4c362143bf0..df6b9066ea5c 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -64,7 +64,6 @@ import android.graphics.Paint;
import android.graphics.drawable.Icon;
import android.metrics.LogMaker;
import android.net.Uri;
-import android.os.Bundle;
import android.os.UserHandle;
import android.service.chooser.ChooserTarget;
@@ -77,9 +76,6 @@ import com.android.internal.app.chooser.DisplayResolveInfo;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
@@ -482,8 +478,8 @@ public class ChooserActivityTest {
.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
- onView(withId(R.id.copy_button)).check(matches(isDisplayed()));
- onView(withId(R.id.copy_button)).perform(click());
+ onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed()));
+ onView(withId(R.id.chooser_copy_button)).perform(click());
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(
Context.CLIPBOARD_SERVICE);
ClipData clipData = clipboard.getPrimaryClip();
@@ -510,8 +506,8 @@ public class ChooserActivityTest {
.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
- onView(withId(R.id.copy_button)).check(matches(isDisplayed()));
- onView(withId(R.id.copy_button)).perform(click());
+ onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed()));
+ onView(withId(R.id.chooser_copy_button)).perform(click());
verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture());
// First is Activity shown, Second is "with preview"
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index 42f7736d37b0..911490f30799 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -27,12 +27,14 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static com.android.internal.app.MatcherUtils.first;
import static com.android.internal.app.ResolverDataProvider.createPackageManagerMockedInfo;
+import static com.android.internal.app.ResolverDataProvider.createResolvedComponentInfoWithOtherId;
import static com.android.internal.app.ResolverWrapperActivity.sOverrides;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import android.content.Intent;
@@ -465,14 +467,33 @@ public class ResolverActivityTest {
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
List<ResolvedComponentInfo> personalResolvedComponentInfos =
- createResolvedComponentsForTest(3);
+ createResolvedComponentsForTestWithOtherProfile(3);
List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
- when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ when(sOverrides.resolverListController.getResolversForIntentAsUser(
Mockito.anyBoolean(),
- Mockito.isA(List.class))).thenReturn(personalResolvedComponentInfos);
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+ when(sOverrides.resolverListController.getResolversForIntentAsUser(
+ Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
+ when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
- Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
+ Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+ when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+
Intent sendIntent = createSendImageIntent();
markWorkProfileUserAvailable();
@@ -502,9 +523,9 @@ public class ResolverActivityTest {
final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
waitForIdle();
+
onView(withText(R.string.resolver_work_tab))
.perform(click());
-
waitForIdle();
assertThat(activity.getWorkListAdapter().getCount(), is(4));
}
@@ -553,10 +574,35 @@ public class ResolverActivityTest {
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
markWorkProfileUserAvailable();
+ List<ResolvedComponentInfo> personalResolvedComponentInfos =
+ createResolvedComponentsForTestWithOtherProfile(1);
List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+
+ when(sOverrides.resolverListController.getResolversForIntentAsUser(
+ Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+ when(sOverrides.resolverListController.getResolversForIntentAsUser(
+ Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
+ when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
- Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
+ Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+ when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class),
+ eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+
Intent sendIntent = createSendImageIntent();
final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 79589bf13853..91c5fbec888a 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -331,6 +331,12 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimation.java"
},
+ "-1410260105": {
+ "message": "Schedule IME show for %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_IME",
+ "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
+ },
"-1391944764": {
"message": "SURFACE DESTROY: %s. %s",
"level": "INFO",
@@ -733,12 +739,6 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DisplayRotation.java"
},
- "-554834595": {
- "message": "Display id=%d is frozen, return %d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_ORIENTATION",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"-549028919": {
"message": "enableScreenIfNeededLocked: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
"level": "INFO",
@@ -1063,6 +1063,12 @@
"group": "WM_SHOW_TRANSACTIONS",
"at": "com\/android\/server\/wm\/WindowSurfaceController.java"
},
+ "140319294": {
+ "message": "IME target changed within ActivityRecord",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_IME",
+ "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
+ },
"146871307": {
"message": "Tried to remove starting window but startingWindow was null: %s",
"level": "VERBOSE",
@@ -1267,6 +1273,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "438102669": {
+ "message": "call showInsets(ime) on %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_IME",
+ "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
+ },
"457951957": {
"message": "\tNot visible=%s",
"level": "DEBUG",
@@ -1387,6 +1399,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "632168013": {
+ "message": "dcTarget: %s mImeTargetFromIme: %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_IME",
+ "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
+ },
"633654009": {
"message": "SURFACE POS (setPositionInTransaction) @ (%f,%f): %s",
"level": "INFO",
@@ -1693,6 +1711,12 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "1373000889": {
+ "message": "abortShowImePostLayout",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_IME",
+ "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
+ },
"1401700824": {
"message": "Window drawn win=%s",
"level": "DEBUG",
@@ -1987,6 +2011,12 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/WindowState.java"
},
+ "1928325128": {
+ "message": "Run showImeRunner",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_IME",
+ "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
+ },
"1947239194": {
"message": "Deferring rotation, still finishing previous rotation",
"level": "VERBOSE",
@@ -2139,6 +2169,9 @@
"WM_DEBUG_FOCUS_LIGHT": {
"tag": "WindowManager"
},
+ "WM_DEBUG_IME": {
+ "tag": "WindowManager"
+ },
"WM_DEBUG_KEEP_SCREEN_ON": {
"tag": "WindowManager"
},
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 7c0efe16838e..58cc08bc2d73 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -479,6 +479,14 @@ bool Bitmap::compress(JavaCompressFormat format, int32_t quality, SkWStream* str
bool Bitmap::compress(const SkBitmap& bitmap, JavaCompressFormat format,
int32_t quality, SkWStream* stream) {
+ if (bitmap.colorType() == kAlpha_8_SkColorType) {
+ // None of the JavaCompressFormats have a sensible way to compress an
+ // ALPHA_8 Bitmap. SkPngEncoder will compress one, but it uses a non-
+ // standard format that most decoders do not understand, so this is
+ // likely not useful.
+ return false;
+ }
+
SkEncodedImageFormat fm;
switch (format) {
case JavaCompressFormat::Jpeg:
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRoute2InfoTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRoute2InfoTest.java
deleted file mode 100644
index c46966fdc6d8..000000000000
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRoute2InfoTest.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaroutertest;
-
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.testng.Assert.assertThrows;
-
-import android.media.MediaRoute2Info;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tests {@link MediaRoute2Info} and its {@link MediaRoute2Info.Builder builder}.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaRoute2InfoTest {
-
- public static final String TEST_ID = "test_id";
- public static final String TEST_NAME = "test_name";
- public static final String TEST_ROUTE_TYPE_0 = "test_route_type_0";
- public static final String TEST_ROUTE_TYPE_1 = "test_route_type_1";
- public static final int TEST_DEVICE_TYPE = MediaRoute2Info.DEVICE_TYPE_REMOTE_SPEAKER;
- public static final Uri TEST_ICON_URI = Uri.parse("https://developer.android.com");
- public static final String TEST_DESCRIPTION = "test_description";
- public static final int TEST_CONNECTION_STATE = MediaRoute2Info.CONNECTION_STATE_CONNECTING;
- public static final String TEST_CLIENT_PACKAGE_NAME = "com.test.client.package.name";
- public static final int TEST_VOLUME_HANDLING = MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
- public static final int TEST_VOLUME_MAX = 100;
- public static final int TEST_VOLUME = 65;
-
- public static final String TEST_KEY = "test_key";
- public static final String TEST_VALUE = "test_value";
-
- @Test
- public void testBuilderConstructorWithInvalidValues() {
- final String nullId = null;
- final String nullName = null;
- final String emptyId = "";
- final String emptyName = "";
- final String validId = "valid_id";
- final String validName = "valid_name";
-
- // ID is invalid
- assertThrows(IllegalArgumentException.class,
- () -> new MediaRoute2Info.Builder(nullId, validName));
- assertThrows(IllegalArgumentException.class,
- () -> new MediaRoute2Info.Builder(emptyId, validName));
-
- // name is invalid
- assertThrows(IllegalArgumentException.class,
- () -> new MediaRoute2Info.Builder(validId, nullName));
- assertThrows(IllegalArgumentException.class,
- () -> new MediaRoute2Info.Builder(validId, emptyName));
-
- // Both are invalid
- assertThrows(IllegalArgumentException.class,
- () -> new MediaRoute2Info.Builder(nullId, nullName));
- assertThrows(IllegalArgumentException.class,
- () -> new MediaRoute2Info.Builder(nullId, emptyName));
- assertThrows(IllegalArgumentException.class,
- () -> new MediaRoute2Info.Builder(emptyId, nullName));
- assertThrows(IllegalArgumentException.class,
- () -> new MediaRoute2Info.Builder(emptyId, emptyName));
-
-
- // Null RouteInfo (1-argument constructor)
- final MediaRoute2Info nullRouteInfo = null;
- assertThrows(NullPointerException.class,
- () -> new MediaRoute2Info.Builder(nullRouteInfo));
- }
-
- @Test
- public void testBuilderBuildWithEmptyRouteTypesShouldThrowIAE() {
- MediaRoute2Info.Builder builder = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME);
- assertThrows(IllegalArgumentException.class, () -> builder.build());
- }
-
- @Test
- public void testBuilderAndGettersOfMediaRoute2Info() {
- Bundle extras = new Bundle();
- extras.putString(TEST_KEY, TEST_VALUE);
-
- MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
- .addFeature(TEST_ROUTE_TYPE_0)
- .addFeature(TEST_ROUTE_TYPE_1)
- .setDeviceType(TEST_DEVICE_TYPE)
- .setIconUri(TEST_ICON_URI)
- .setDescription(TEST_DESCRIPTION)
- .setConnectionState(TEST_CONNECTION_STATE)
- .setClientPackageName(TEST_CLIENT_PACKAGE_NAME)
- .setVolumeHandling(TEST_VOLUME_HANDLING)
- .setVolumeMax(TEST_VOLUME_MAX)
- .setVolume(TEST_VOLUME)
- .setExtras(extras)
- .build();
-
- assertEquals(TEST_ID, routeInfo.getId());
- assertEquals(TEST_NAME, routeInfo.getName());
-
- assertEquals(2, routeInfo.getFeatures().size());
- assertEquals(TEST_ROUTE_TYPE_0, routeInfo.getFeatures().get(0));
- assertEquals(TEST_ROUTE_TYPE_1, routeInfo.getFeatures().get(1));
-
- assertEquals(TEST_DEVICE_TYPE, routeInfo.getDeviceType());
- assertEquals(TEST_ICON_URI, routeInfo.getIconUri());
- assertEquals(TEST_DESCRIPTION, routeInfo.getDescription());
- assertEquals(TEST_CONNECTION_STATE, routeInfo.getConnectionState());
- assertEquals(TEST_CLIENT_PACKAGE_NAME, routeInfo.getClientPackageName());
- assertEquals(TEST_VOLUME_HANDLING, routeInfo.getVolumeHandling());
- assertEquals(TEST_VOLUME_MAX, routeInfo.getVolumeMax());
- assertEquals(TEST_VOLUME, routeInfo.getVolume());
-
- Bundle extrasOut = routeInfo.getExtras();
- assertNotNull(extrasOut);
- assertTrue(extrasOut.containsKey(TEST_KEY));
- assertEquals(TEST_VALUE, extrasOut.getString(TEST_KEY));
- }
-
- @Test
- public void testBuilderSetExtrasWithNull() {
- MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
- .addFeature(TEST_ROUTE_TYPE_0)
- .setExtras(null)
- .build();
-
- assertNull(routeInfo.getExtras());
- }
-
- @Test
- public void testBuilderaddFeatures() {
- List<String> routeTypes = new ArrayList<>();
- routeTypes.add(TEST_ROUTE_TYPE_0);
- routeTypes.add(TEST_ROUTE_TYPE_1);
-
- MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
- .addFeatures(routeTypes)
- .build();
-
- assertEquals(routeTypes, routeInfo.getFeatures());
- }
-
- @Test
- public void testBuilderclearFeatures() {
- MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
- .addFeature(TEST_ROUTE_TYPE_0)
- .addFeature(TEST_ROUTE_TYPE_1)
- // clearFeatures should clear the route types.
- .clearFeatures()
- .addFeature(TEST_ROUTE_TYPE_1)
- .build();
-
- assertEquals(1, routeInfo.getFeatures().size());
- assertEquals(TEST_ROUTE_TYPE_1, routeInfo.getFeatures().get(0));
- }
-
- @Test
- public void testhasAnyFeaturesReturnsFalse() {
- MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
- .addFeature(TEST_ROUTE_TYPE_0)
- .addFeature(TEST_ROUTE_TYPE_1)
- .build();
-
- List<String> testRouteTypes = new ArrayList<>();
- testRouteTypes.add("non_matching_route_type_1");
- testRouteTypes.add("non_matching_route_type_2");
- testRouteTypes.add("non_matching_route_type_3");
- testRouteTypes.add("non_matching_route_type_4");
-
- assertFalse(routeInfo.hasAnyFeatures(testRouteTypes));
- }
-
- @Test
- public void testhasAnyFeaturesReturnsTrue() {
- MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
- .addFeature(TEST_ROUTE_TYPE_0)
- .addFeature(TEST_ROUTE_TYPE_1)
- .build();
-
- List<String> testRouteTypes = new ArrayList<>();
- testRouteTypes.add("non_matching_route_type_1");
- testRouteTypes.add("non_matching_route_type_2");
- testRouteTypes.add("non_matching_route_type_3");
- testRouteTypes.add(TEST_ROUTE_TYPE_1);
-
- assertTrue(routeInfo.hasAnyFeatures(testRouteTypes));
- }
-
- @Test
- public void testEqualsCreatedWithSameArguments() {
- Bundle extras = new Bundle();
- extras.putString(TEST_KEY, TEST_VALUE);
-
- MediaRoute2Info routeInfo1 = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
- .addFeature(TEST_ROUTE_TYPE_0)
- .addFeature(TEST_ROUTE_TYPE_1)
- .setDeviceType(TEST_DEVICE_TYPE)
- .setIconUri(TEST_ICON_URI)
- .setDescription(TEST_DESCRIPTION)
- .setConnectionState(TEST_CONNECTION_STATE)
- .setClientPackageName(TEST_CLIENT_PACKAGE_NAME)
- .setVolumeHandling(TEST_VOLUME_HANDLING)
- .setVolumeMax(TEST_VOLUME_MAX)
- .setVolume(TEST_VOLUME)
- .setExtras(extras)
- .build();
-
- MediaRoute2Info routeInfo2 = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
- .addFeature(TEST_ROUTE_TYPE_0)
- .addFeature(TEST_ROUTE_TYPE_1)
- .setDeviceType(TEST_DEVICE_TYPE)
- .setIconUri(TEST_ICON_URI)
- .setDescription(TEST_DESCRIPTION)
- .setConnectionState(TEST_CONNECTION_STATE)
- .setClientPackageName(TEST_CLIENT_PACKAGE_NAME)
- .setVolumeHandling(TEST_VOLUME_HANDLING)
- .setVolumeMax(TEST_VOLUME_MAX)
- .setVolume(TEST_VOLUME)
- .setExtras(extras)
- .build();
-
- assertEquals(routeInfo1, routeInfo2);
- assertEquals(routeInfo1.hashCode(), routeInfo2.hashCode());
- }
-
- @Test
- public void testEqualsCreatedWithBuilderCopyConstructor() {
- Bundle extras = new Bundle();
- extras.putString(TEST_KEY, TEST_VALUE);
-
- MediaRoute2Info routeInfo1 = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
- .addFeature(TEST_ROUTE_TYPE_0)
- .addFeature(TEST_ROUTE_TYPE_1)
- .setDeviceType(TEST_DEVICE_TYPE)
- .setIconUri(TEST_ICON_URI)
- .setDescription(TEST_DESCRIPTION)
- .setConnectionState(TEST_CONNECTION_STATE)
- .setClientPackageName(TEST_CLIENT_PACKAGE_NAME)
- .setVolumeHandling(TEST_VOLUME_HANDLING)
- .setVolumeMax(TEST_VOLUME_MAX)
- .setVolume(TEST_VOLUME)
- .setExtras(extras)
- .build();
-
- MediaRoute2Info routeInfo2 = new MediaRoute2Info.Builder(routeInfo1).build();
-
- assertEquals(routeInfo1, routeInfo2);
- assertEquals(routeInfo1.hashCode(), routeInfo2.hashCode());
- }
-
- @Test
- public void testEqualsReturnFalse() {
- Bundle extras = new Bundle();
- extras.putString(TEST_KEY, TEST_VALUE);
-
- MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
- .addFeature(TEST_ROUTE_TYPE_0)
- .addFeature(TEST_ROUTE_TYPE_1)
- .setDeviceType(TEST_DEVICE_TYPE)
- .setIconUri(TEST_ICON_URI)
- .setDescription(TEST_DESCRIPTION)
- .setConnectionState(TEST_CONNECTION_STATE)
- .setClientPackageName(TEST_CLIENT_PACKAGE_NAME)
- .setVolumeHandling(TEST_VOLUME_HANDLING)
- .setVolumeMax(TEST_VOLUME_MAX)
- .setVolume(TEST_VOLUME)
- .setExtras(extras)
- .build();
-
- // Now, we will use copy constructor
- assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
- .addFeature("randomRouteType")
- .build());
- assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
- .setDeviceType(TEST_DEVICE_TYPE + 1)
- .build());
- assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
- .setIconUri(Uri.parse("randomUri"))
- .build());
- assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
- .setDescription("randomDescription")
- .build());
- assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
- .setConnectionState(TEST_CONNECTION_STATE + 1)
- .build());
- assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
- .setClientPackageName("randomPackageName")
- .build());
- assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
- .setVolumeHandling(TEST_VOLUME_HANDLING + 1)
- .build());
- assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
- .setVolumeMax(TEST_VOLUME_MAX + 100)
- .build());
- assertNotEquals(routeInfo, new MediaRoute2Info.Builder(routeInfo)
- .setVolume(TEST_VOLUME + 10)
- .build());
- // Note: Extras will not affect the equals.
- }
-
- @Test
- public void testParcelingAndUnParceling() {
- Bundle extras = new Bundle();
- extras.putString(TEST_KEY, TEST_VALUE);
-
- MediaRoute2Info routeInfo = new MediaRoute2Info.Builder(TEST_ID, TEST_NAME)
- .addFeature(TEST_ROUTE_TYPE_0)
- .addFeature(TEST_ROUTE_TYPE_1)
- .setDeviceType(TEST_DEVICE_TYPE)
- .setIconUri(TEST_ICON_URI)
- .setDescription(TEST_DESCRIPTION)
- .setConnectionState(TEST_CONNECTION_STATE)
- .setClientPackageName(TEST_CLIENT_PACKAGE_NAME)
- .setVolumeHandling(TEST_VOLUME_HANDLING)
- .setVolumeMax(TEST_VOLUME_MAX)
- .setVolume(TEST_VOLUME)
- .setExtras(extras)
- .build();
-
- Parcel parcel = Parcel.obtain();
- routeInfo.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
-
- MediaRoute2Info routeInfoFromParcel = MediaRoute2Info.CREATOR.createFromParcel(parcel);
- assertEquals(routeInfo, routeInfoFromParcel);
- assertEquals(routeInfo.hashCode(), routeInfoFromParcel.hashCode());
-
- // Check extras
- Bundle extrasOut = routeInfoFromParcel.getExtras();
- assertNotNull(extrasOut);
- assertTrue(extrasOut.containsKey(TEST_KEY));
- assertEquals(TEST_VALUE, extrasOut.getString(TEST_KEY));
- }
-}
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java
deleted file mode 100644
index e0b454559456..000000000000
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java
+++ /dev/null
@@ -1,780 +0,0 @@
-/*
- * Copyright 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.mediaroutertest;
-
-import static android.media.MediaRoute2Info.CONNECTION_STATE_CONNECTING;
-import static android.media.MediaRoute2Info.DEVICE_TYPE_REMOTE_SPEAKER;
-import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
-
-import static com.android.mediaroutertest.MediaRouterManagerTest.FEATURES_ALL;
-import static com.android.mediaroutertest.MediaRouterManagerTest.FEATURES_SPECIAL;
-import static com.android.mediaroutertest.MediaRouterManagerTest.FEATURE_SAMPLE;
-import static com.android.mediaroutertest.MediaRouterManagerTest.ROUTE_ID1;
-import static com.android.mediaroutertest.MediaRouterManagerTest.ROUTE_ID2;
-import static com.android.mediaroutertest.MediaRouterManagerTest.ROUTE_ID3_SESSION_CREATION_FAILED;
-import static com.android.mediaroutertest.MediaRouterManagerTest.ROUTE_ID4_TO_SELECT_AND_DESELECT;
-import static com.android.mediaroutertest.MediaRouterManagerTest.ROUTE_ID5_TO_TRANSFER_TO;
-import static com.android.mediaroutertest.MediaRouterManagerTest.ROUTE_ID_SPECIAL_FEATURE;
-import static com.android.mediaroutertest.MediaRouterManagerTest.ROUTE_ID_VARIABLE_VOLUME;
-import static com.android.mediaroutertest.MediaRouterManagerTest.SYSTEM_PROVIDER_ID;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.testng.Assert.assertThrows;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.media.MediaRoute2Info;
-import android.media.MediaRouter2;
-import android.media.MediaRouter2.OnGetControllerHintsListener;
-import android.media.MediaRouter2.RouteCallback;
-import android.media.MediaRouter2.RoutingController;
-import android.media.MediaRouter2.RoutingControllerCallback;
-import android.media.RouteDiscoveryPreference;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.text.TextUtils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Predicate;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaRouter2Test {
- private static final String TAG = "MediaRouter2Test";
- Context mContext;
- private MediaRouter2 mRouter2;
- private Executor mExecutor;
-
- private static final int TIMEOUT_MS = 5000;
-
- private static final String TEST_KEY = "test_key";
- private static final String TEST_VALUE = "test_value";
-
- @Before
- public void setUp() throws Exception {
- mContext = InstrumentationRegistry.getTargetContext();
- mRouter2 = MediaRouter2.getInstance(mContext);
- mExecutor = Executors.newSingleThreadExecutor();
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- /**
- * Tests if we get proper routes for application that has special route type.
- */
- @Test
- public void testGetRoutes() throws Exception {
- Map<String, MediaRoute2Info> routes = waitAndGetRoutes(FEATURES_SPECIAL);
-
- assertEquals(1, routes.size());
- assertNotNull(routes.get(ROUTE_ID_SPECIAL_FEATURE));
- }
-
- @Test
- public void testRouteInfoEquality() {
- MediaRoute2Info routeInfo = new MediaRoute2Info.Builder("id", "name")
- .setDescription("description")
- .setClientPackageName("com.android.mediaroutertest")
- .setConnectionState(CONNECTION_STATE_CONNECTING)
- .setIconUri(new Uri.Builder().path("icon").build())
- .setVolume(5)
- .setVolumeMax(20)
- .addFeature(FEATURE_SAMPLE)
- .setVolumeHandling(PLAYBACK_VOLUME_VARIABLE)
- .setDeviceType(DEVICE_TYPE_REMOTE_SPEAKER)
- .build();
-
- MediaRoute2Info routeInfoRebuilt = new MediaRoute2Info.Builder(routeInfo).build();
- assertEquals(routeInfo, routeInfoRebuilt);
-
- Parcel parcel = Parcel.obtain();
- parcel.writeParcelable(routeInfo, 0);
- parcel.setDataPosition(0);
- MediaRoute2Info routeInfoFromParcel = parcel.readParcelable(null);
-
- assertEquals(routeInfo, routeInfoFromParcel);
- }
-
- @Test
- public void testControlVolumeWithRouter() throws Exception {
- Map<String, MediaRoute2Info> routes = waitAndGetRoutes(FEATURES_ALL);
-
- MediaRoute2Info volRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME);
- assertNotNull(volRoute);
-
- int originalVolume = volRoute.getVolume();
- int deltaVolume = (originalVolume == volRoute.getVolumeMax() ? -1 : 1);
-
- awaitOnRouteChanged(
- () -> mRouter2.requestUpdateVolume(volRoute, deltaVolume),
- ROUTE_ID_VARIABLE_VOLUME,
- (route -> route.getVolume() == originalVolume + deltaVolume),
- FEATURES_ALL);
-
- awaitOnRouteChanged(
- () -> mRouter2.requestSetVolume(volRoute, originalVolume),
- ROUTE_ID_VARIABLE_VOLUME,
- (route -> route.getVolume() == originalVolume),
- FEATURES_ALL);
- }
-
- @Test
- public void testRegisterControllerCallbackWithInvalidArguments() {
- Executor executor = mExecutor;
- RoutingControllerCallback callback = new RoutingControllerCallback();
-
- // Tests null executor
- assertThrows(NullPointerException.class,
- () -> mRouter2.registerControllerCallback(null, callback));
-
- // Tests null callback
- assertThrows(NullPointerException.class,
- () -> mRouter2.registerControllerCallback(executor, null));
- }
-
- @Test
- public void testUnregisterControllerCallbackWithNullCallback() {
- // Tests null callback
- assertThrows(NullPointerException.class,
- () -> mRouter2.unregisterControllerCallback(null));
- }
-
- @Test
- public void testRequestCreateControllerWithNullRoute() {
- assertThrows(NullPointerException.class,
- () -> mRouter2.requestCreateController(null));
- }
-
- @Test
- public void testRequestCreateControllerSuccess() throws Exception {
- final List<String> sampleRouteFeature = new ArrayList<>();
- sampleRouteFeature.add(FEATURE_SAMPLE);
-
- Map<String, MediaRoute2Info> routes = waitAndGetRoutes(sampleRouteFeature);
- MediaRoute2Info route = routes.get(ROUTE_ID1);
- assertNotNull(route);
-
- final CountDownLatch successLatch = new CountDownLatch(1);
- final CountDownLatch failureLatch = new CountDownLatch(1);
- final List<RoutingController> controllers = new ArrayList<>();
-
- // Create session with this route
- RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
- @Override
- public void onControllerCreated(RoutingController controller) {
- assertNotNull(controller);
- assertTrue(createRouteMap(controller.getSelectedRoutes()).containsKey(ROUTE_ID1));
- controllers.add(controller);
- successLatch.countDown();
- }
-
- @Override
- public void onControllerCreationFailed(MediaRoute2Info requestedRoute) {
- failureLatch.countDown();
- }
- };
-
- // TODO: Remove this once the MediaRouter2 becomes always connected to the service.
- RouteCallback routeCallback = new RouteCallback();
- mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
-
- try {
- mRouter2.registerControllerCallback(mExecutor, controllerCallback);
- mRouter2.requestCreateController(route);
- assertTrue(successLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- // onSessionCreationFailed should not be called.
- assertFalse(failureLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- } finally {
- releaseControllers(controllers);
- mRouter2.unregisterRouteCallback(routeCallback);
- mRouter2.unregisterControllerCallback(controllerCallback);
- }
- }
-
- @Test
- public void testRequestCreateControllerFailure() throws Exception {
- final List<String> sampleRouteType = new ArrayList<>();
- sampleRouteType.add(FEATURE_SAMPLE);
-
- Map<String, MediaRoute2Info> routes = waitAndGetRoutes(sampleRouteType);
- MediaRoute2Info route = routes.get(ROUTE_ID3_SESSION_CREATION_FAILED);
- assertNotNull(route);
-
- final CountDownLatch successLatch = new CountDownLatch(1);
- final CountDownLatch failureLatch = new CountDownLatch(1);
- final List<RoutingController> controllers = new ArrayList<>();
-
- // Create session with this route
- RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
- @Override
- public void onControllerCreated(RoutingController controller) {
- controllers.add(controller);
- successLatch.countDown();
- }
-
- @Override
- public void onControllerCreationFailed(MediaRoute2Info requestedRoute) {
- assertEquals(route, requestedRoute);
- failureLatch.countDown();
- }
- };
-
- // TODO: Remove this once the MediaRouter2 becomes always connected to the service.
- RouteCallback routeCallback = new RouteCallback();
- mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
-
- try {
- mRouter2.registerControllerCallback(mExecutor, controllerCallback);
- mRouter2.requestCreateController(route);
- assertTrue(failureLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- // onSessionCreated should not be called.
- assertFalse(successLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- } finally {
- releaseControllers(controllers);
- mRouter2.unregisterRouteCallback(routeCallback);
- mRouter2.unregisterControllerCallback(controllerCallback);
- }
- }
-
- @Test
- public void testRequestCreateControllerMultipleSessions() throws Exception {
- final List<String> sampleRouteType = new ArrayList<>();
- sampleRouteType.add(FEATURE_SAMPLE);
-
- final CountDownLatch successLatch = new CountDownLatch(2);
- final CountDownLatch failureLatch = new CountDownLatch(1);
- final List<RoutingController> createdControllers = new ArrayList<>();
-
- // Create session with this route
- RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
- @Override
- public void onControllerCreated(RoutingController controller) {
- createdControllers.add(controller);
- successLatch.countDown();
- }
-
- @Override
- public void onControllerCreationFailed(MediaRoute2Info requestedRoute) {
- failureLatch.countDown();
- }
- };
-
- Map<String, MediaRoute2Info> routes = waitAndGetRoutes(sampleRouteType);
- MediaRoute2Info route1 = routes.get(ROUTE_ID1);
- MediaRoute2Info route2 = routes.get(ROUTE_ID2);
- assertNotNull(route1);
- assertNotNull(route2);
-
- // TODO: Remove this once the MediaRouter2 becomes always connected to the service.
- RouteCallback routeCallback = new RouteCallback();
- mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
-
- try {
- mRouter2.registerControllerCallback(mExecutor, controllerCallback);
- mRouter2.requestCreateController(route1);
- mRouter2.requestCreateController(route2);
- assertTrue(successLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- // onSessionCreationFailed should not be called.
- assertFalse(failureLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- // Created controllers should have proper info
- assertEquals(2, createdControllers.size());
- RoutingController controller1 = createdControllers.get(0);
- RoutingController controller2 = createdControllers.get(1);
-
- assertNotEquals(controller1.getId(), controller2.getId());
- assertTrue(createRouteMap(controller1.getSelectedRoutes()).containsKey(ROUTE_ID1));
- assertTrue(createRouteMap(controller2.getSelectedRoutes()).containsKey(ROUTE_ID2));
-
- } finally {
- releaseControllers(createdControllers);
- mRouter2.unregisterRouteCallback(routeCallback);
- mRouter2.unregisterControllerCallback(controllerCallback);
- }
- }
-
- @Test
- public void testSetOnGetControllerHintsListener() throws Exception {
- final List<String> sampleRouteFeature = new ArrayList<>();
- sampleRouteFeature.add(FEATURE_SAMPLE);
-
- Map<String, MediaRoute2Info> routes = waitAndGetRoutes(sampleRouteFeature);
- MediaRoute2Info route = routes.get(ROUTE_ID1);
- assertNotNull(route);
-
- final Bundle createSessionHints = new Bundle();
- createSessionHints.putString(TEST_KEY, TEST_VALUE);
- final OnGetControllerHintsListener listener = new OnGetControllerHintsListener() {
- @Override
- public Bundle onGetControllerHints(MediaRoute2Info route) {
- return createSessionHints;
- }
- };
-
- final CountDownLatch successLatch = new CountDownLatch(1);
- final CountDownLatch failureLatch = new CountDownLatch(1);
- final List<RoutingController> controllers = new ArrayList<>();
-
- // Create session with this route
- RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
- @Override
- public void onControllerCreated(RoutingController controller) {
- assertNotNull(controller);
- assertTrue(createRouteMap(controller.getSelectedRoutes()).containsKey(ROUTE_ID1));
-
- // The SampleMediaRoute2ProviderService supposed to set control hints
- // with the given creationSessionHints.
- Bundle controlHints = controller.getControlHints();
- assertNotNull(controlHints);
- assertTrue(controlHints.containsKey(TEST_KEY));
- assertEquals(TEST_VALUE, controlHints.getString(TEST_KEY));
-
- controllers.add(controller);
- successLatch.countDown();
- }
-
- @Override
- public void onControllerCreationFailed(MediaRoute2Info requestedRoute) {
- failureLatch.countDown();
- }
- };
-
- // TODO: Remove this once the MediaRouter2 becomes always connected to the service.
- RouteCallback routeCallback = new RouteCallback();
- mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
-
- try {
- mRouter2.registerControllerCallback(mExecutor, controllerCallback);
-
- // The SampleMediaRoute2ProviderService supposed to set control hints
- // with the given creationSessionHints.
- mRouter2.setOnGetControllerHintsListener(listener);
- mRouter2.requestCreateController(route);
- assertTrue(successLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- // onSessionCreationFailed should not be called.
- assertFalse(failureLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- } finally {
- releaseControllers(controllers);
- mRouter2.unregisterRouteCallback(routeCallback);
- mRouter2.unregisterControllerCallback(controllerCallback);
- }
- }
-
- @Test
- public void testRoutingControllerCallbackIsNotCalledAfterUnregistered() throws Exception {
- final List<String> sampleRouteType = new ArrayList<>();
- sampleRouteType.add(FEATURE_SAMPLE);
-
- Map<String, MediaRoute2Info> routes = waitAndGetRoutes(sampleRouteType);
- MediaRoute2Info route = routes.get(ROUTE_ID1);
- assertNotNull(route);
-
- final CountDownLatch successLatch = new CountDownLatch(1);
- final CountDownLatch failureLatch = new CountDownLatch(1);
- final List<RoutingController> controllers = new ArrayList<>();
-
- // Create session with this route
- RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
- @Override
- public void onControllerCreated(RoutingController controller) {
- controllers.add(controller);
- successLatch.countDown();
- }
-
- @Override
- public void onControllerCreationFailed(MediaRoute2Info requestedRoute) {
- failureLatch.countDown();
- }
- };
-
- // TODO: Remove this once the MediaRouter2 becomes always connected to the service.
- RouteCallback routeCallback = new RouteCallback();
- mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
-
- try {
- mRouter2.registerControllerCallback(mExecutor, controllerCallback);
- mRouter2.requestCreateController(route);
-
- // Unregisters session callback
- mRouter2.unregisterControllerCallback(controllerCallback);
-
- // No session callback methods should be called.
- assertFalse(successLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- assertFalse(failureLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- } finally {
- releaseControllers(controllers);
- mRouter2.unregisterRouteCallback(routeCallback);
- mRouter2.unregisterControllerCallback(controllerCallback);
- }
- }
-
- // TODO: Add tests for illegal inputs if needed (e.g. selecting already selected route)
- @Test
- public void testRoutingControllerSelectAndDeselectRoute() throws Exception {
- final List<String> sampleRouteType = new ArrayList<>();
- sampleRouteType.add(FEATURE_SAMPLE);
-
- Map<String, MediaRoute2Info> routes = waitAndGetRoutes(sampleRouteType);
- MediaRoute2Info routeToCreateSessionWith = routes.get(ROUTE_ID1);
- assertNotNull(routeToCreateSessionWith);
-
- final CountDownLatch onControllerCreatedLatch = new CountDownLatch(1);
- final CountDownLatch onControllerUpdatedLatchForSelect = new CountDownLatch(1);
- final CountDownLatch onControllerUpdatedLatchForDeselect = new CountDownLatch(1);
- final List<RoutingController> controllers = new ArrayList<>();
-
- // Create session with ROUTE_ID1
- RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
- @Override
- public void onControllerCreated(RoutingController controller) {
- assertNotNull(controller);
- assertTrue(getRouteIds(controller.getSelectedRoutes()).contains(ROUTE_ID1));
- controllers.add(controller);
- onControllerCreatedLatch.countDown();
- }
-
- @Override
- public void onControllerUpdated(RoutingController controller) {
- if (onControllerCreatedLatch.getCount() != 0
- || !TextUtils.equals(
- controllers.get(0).getId(), controller.getId())) {
- return;
- }
-
- if (onControllerUpdatedLatchForSelect.getCount() != 0) {
- assertEquals(2, controller.getSelectedRoutes().size());
- assertTrue(getRouteIds(controller.getSelectedRoutes())
- .contains(ROUTE_ID1));
- assertTrue(getRouteIds(controller.getSelectedRoutes())
- .contains(ROUTE_ID4_TO_SELECT_AND_DESELECT));
- assertFalse(getRouteIds(controller.getSelectableRoutes())
- .contains(ROUTE_ID4_TO_SELECT_AND_DESELECT));
-
- onControllerUpdatedLatchForSelect.countDown();
- } else {
- assertEquals(1, controller.getSelectedRoutes().size());
- assertTrue(getRouteIds(controller.getSelectedRoutes())
- .contains(ROUTE_ID1));
- assertFalse(getRouteIds(controller.getSelectedRoutes())
- .contains(ROUTE_ID4_TO_SELECT_AND_DESELECT));
- assertTrue(getRouteIds(controller.getSelectableRoutes())
- .contains(ROUTE_ID4_TO_SELECT_AND_DESELECT));
-
- onControllerUpdatedLatchForDeselect.countDown();
- }
- }
- };
-
- // TODO: Remove this once the MediaRouter2 becomes always connected to the service.
- RouteCallback routeCallback = new RouteCallback();
- mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
-
- try {
- mRouter2.registerControllerCallback(mExecutor, controllerCallback);
- mRouter2.requestCreateController(routeToCreateSessionWith);
- assertTrue(onControllerCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertEquals(1, controllers.size());
- RoutingController controller = controllers.get(0);
- assertTrue(getRouteIds(controller.getSelectableRoutes())
- .contains(ROUTE_ID4_TO_SELECT_AND_DESELECT));
-
- // Select ROUTE_ID4_TO_SELECT_AND_DESELECT
- MediaRoute2Info routeToSelectAndDeselect = routes.get(
- ROUTE_ID4_TO_SELECT_AND_DESELECT);
- assertNotNull(routeToSelectAndDeselect);
-
- controller.selectRoute(routeToSelectAndDeselect);
- assertTrue(onControllerUpdatedLatchForSelect.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- controller.deselectRoute(routeToSelectAndDeselect);
- assertTrue(onControllerUpdatedLatchForDeselect.await(
- TIMEOUT_MS, TimeUnit.MILLISECONDS));
- } finally {
- releaseControllers(controllers);
- mRouter2.unregisterRouteCallback(routeCallback);
- mRouter2.unregisterControllerCallback(controllerCallback);
- }
- }
-
- @Test
- public void testRoutingControllerTransferToRoute() throws Exception {
- final List<String> sampleRouteType = new ArrayList<>();
- sampleRouteType.add(FEATURE_SAMPLE);
-
- Map<String, MediaRoute2Info> routes = waitAndGetRoutes(sampleRouteType);
- MediaRoute2Info routeToCreateSessionWith = routes.get(ROUTE_ID1);
- assertNotNull(routeToCreateSessionWith);
-
- final CountDownLatch onControllerCreatedLatch = new CountDownLatch(1);
- final CountDownLatch onControllerUpdatedLatch = new CountDownLatch(1);
- final List<RoutingController> controllers = new ArrayList<>();
-
- // Create session with ROUTE_ID1
- RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
- @Override
- public void onControllerCreated(RoutingController controller) {
- assertNotNull(controller);
- assertTrue(getRouteIds(controller.getSelectedRoutes()).contains(ROUTE_ID1));
- controllers.add(controller);
- onControllerCreatedLatch.countDown();
- }
-
- @Override
- public void onControllerUpdated(RoutingController controller) {
- if (onControllerCreatedLatch.getCount() != 0
- || !TextUtils.equals(
- controllers.get(0).getId(), controller.getId())) {
- return;
- }
- assertEquals(1, controller.getSelectedRoutes().size());
- assertFalse(getRouteIds(controller.getSelectedRoutes()).contains(ROUTE_ID1));
- assertTrue(getRouteIds(controller.getSelectedRoutes())
- .contains(ROUTE_ID5_TO_TRANSFER_TO));
- assertFalse(getRouteIds(controller.getTransferrableRoutes())
- .contains(ROUTE_ID5_TO_TRANSFER_TO));
-
- onControllerUpdatedLatch.countDown();
- }
- };
-
- // TODO: Remove this once the MediaRouter2 becomes always connected to the service.
- RouteCallback routeCallback = new RouteCallback();
- mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
-
- try {
- mRouter2.registerControllerCallback(mExecutor, controllerCallback);
- mRouter2.requestCreateController(routeToCreateSessionWith);
- assertTrue(onControllerCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertEquals(1, controllers.size());
- RoutingController controller = controllers.get(0);
- assertTrue(getRouteIds(controller.getTransferrableRoutes())
- .contains(ROUTE_ID5_TO_TRANSFER_TO));
-
- // Transfer to ROUTE_ID5_TO_TRANSFER_TO
- MediaRoute2Info routeToTransferTo = routes.get(ROUTE_ID5_TO_TRANSFER_TO);
- assertNotNull(routeToTransferTo);
-
- controller.transferToRoute(routeToTransferTo);
- assertTrue(onControllerUpdatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- } finally {
- releaseControllers(controllers);
- mRouter2.unregisterRouteCallback(routeCallback);
- mRouter2.unregisterControllerCallback(controllerCallback);
- }
- }
-
- // TODO: Add tests for onSessionReleased() when provider releases the session.
-
- @Test
- public void testRoutingControllerRelease() throws Exception {
- final List<String> sampleRouteType = new ArrayList<>();
- sampleRouteType.add(FEATURE_SAMPLE);
-
- Map<String, MediaRoute2Info> routes = waitAndGetRoutes(sampleRouteType);
- MediaRoute2Info routeToCreateSessionWith = routes.get(ROUTE_ID1);
- assertNotNull(routeToCreateSessionWith);
-
- final CountDownLatch onControllerCreatedLatch = new CountDownLatch(1);
- final CountDownLatch onControllerUpdatedLatch = new CountDownLatch(1);
- final CountDownLatch onControllerReleasedLatch = new CountDownLatch(1);
- final List<RoutingController> controllers = new ArrayList<>();
-
- // Create session with ROUTE_ID1
- RoutingControllerCallback controllerCallback = new RoutingControllerCallback() {
- @Override
- public void onControllerCreated(RoutingController controller) {
- assertNotNull(controller);
- assertTrue(getRouteIds(controller.getSelectedRoutes()).contains(ROUTE_ID1));
- controllers.add(controller);
- onControllerCreatedLatch.countDown();
- }
-
- @Override
- public void onControllerUpdated(RoutingController controller) {
- if (onControllerCreatedLatch.getCount() != 0
- || !TextUtils.equals(controllers.get(0).getId(), controller.getId())) {
- return;
- }
- onControllerUpdatedLatch.countDown();
- }
-
- @Override
- public void onControllerReleased(RoutingController controller) {
- if (onControllerCreatedLatch.getCount() != 0
- || !TextUtils.equals(controllers.get(0).getId(), controller.getId())) {
- return;
- }
- onControllerReleasedLatch.countDown();
- }
- };
-
- // TODO: Remove this once the MediaRouter2 becomes always connected to the service.
- RouteCallback routeCallback = new RouteCallback();
- mRouter2.registerRouteCallback(mExecutor, routeCallback, RouteDiscoveryPreference.EMPTY);
-
- try {
- mRouter2.registerControllerCallback(mExecutor, controllerCallback);
- mRouter2.requestCreateController(routeToCreateSessionWith);
- assertTrue(onControllerCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertEquals(1, controllers.size());
- RoutingController controller = controllers.get(0);
- assertTrue(getRouteIds(controller.getTransferrableRoutes())
- .contains(ROUTE_ID5_TO_TRANSFER_TO));
-
- // Release controller. Future calls should be ignored.
- controller.release();
-
- // Transfer to ROUTE_ID5_TO_TRANSFER_TO
- MediaRoute2Info routeToTransferTo = routes.get(ROUTE_ID5_TO_TRANSFER_TO);
- assertNotNull(routeToTransferTo);
-
- // This call should be ignored.
- // The onSessionInfoChanged() shouldn't be called.
- controller.transferToRoute(routeToTransferTo);
- assertFalse(onControllerUpdatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- // onControllerReleased should be called.
- assertTrue(onControllerReleasedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- } finally {
- releaseControllers(controllers);
- mRouter2.unregisterRouteCallback(routeCallback);
- mRouter2.unregisterControllerCallback(controllerCallback);
- }
- }
-
- // TODO: Consider adding tests with bluetooth connection/disconnection.
- @Test
- public void testGetSystemController() {
- final RoutingController systemController = mRouter2.getSystemController();
- assertNotNull(systemController);
- assertFalse(systemController.isReleased());
- }
-
- @Test
- public void testControllers() {
- List<RoutingController> controllers = mRouter2.getControllers();
- assertNotNull(controllers);
- assertFalse(controllers.isEmpty());
- assertSame(mRouter2.getSystemController(), controllers.get(0));
- }
-
- // Helper for getting routes easily
- static Map<String, MediaRoute2Info> createRouteMap(List<MediaRoute2Info> routes) {
- Map<String, MediaRoute2Info> routeMap = new HashMap<>();
- for (MediaRoute2Info route : routes) {
- routeMap.put(route.getId(), route);
- }
- return routeMap;
- }
-
- Map<String, MediaRoute2Info> waitAndGetRoutes(List<String> routeTypes)
- throws Exception {
- CountDownLatch latch = new CountDownLatch(1);
-
- // A dummy callback is required to send route type info.
- RouteCallback routeCallback = new RouteCallback() {
- @Override
- public void onRoutesAdded(List<MediaRoute2Info> routes) {
- for (int i = 0; i < routes.size(); i++) {
- //TODO: use isSystem() or similar method when it's ready
- if (!TextUtils.equals(routes.get(i).getProviderId(), SYSTEM_PROVIDER_ID)) {
- latch.countDown();
- }
- }
- }
- };
-
- mRouter2.registerRouteCallback(mExecutor, routeCallback,
- new RouteDiscoveryPreference.Builder(routeTypes, true).build());
- try {
- latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
- return createRouteMap(mRouter2.getRoutes());
- } finally {
- mRouter2.unregisterRouteCallback(routeCallback);
- }
- }
-
- static void releaseControllers(@NonNull List<RoutingController> controllers) {
- for (RoutingController controller : controllers) {
- controller.release();
- }
- }
-
- /**
- * Returns a list of IDs of the given route list.
- */
- List<String> getRouteIds(@NonNull List<MediaRoute2Info> routes) {
- List<String> result = new ArrayList<>();
- for (MediaRoute2Info route : routes) {
- result.add(route.getId());
- }
- return result;
- }
-
- void awaitOnRouteChanged(Runnable task, String routeId,
- Predicate<MediaRoute2Info> predicate,
- List<String> routeTypes) throws Exception {
- CountDownLatch latch = new CountDownLatch(1);
- RouteCallback routeCallback = new RouteCallback() {
- @Override
- public void onRoutesChanged(List<MediaRoute2Info> changed) {
- MediaRoute2Info route = createRouteMap(changed).get(routeId);
- if (route != null && predicate.test(route)) {
- latch.countDown();
- }
- }
- };
- mRouter2.registerRouteCallback(mExecutor, routeCallback,
- new RouteDiscoveryPreference.Builder(routeTypes, true).build());
- try {
- task.run();
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- } finally {
- mRouter2.unregisterRouteCallback(routeCallback);
- }
- }
-}
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/RouteDiscoveryPreferenceTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/RouteDiscoveryPreferenceTest.java
deleted file mode 100644
index fa129350ed8b..000000000000
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/RouteDiscoveryPreferenceTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaroutertest;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import android.media.RouteDiscoveryPreference;
-import android.os.Parcel;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class RouteDiscoveryPreferenceTest {
- @Before
- public void setUp() throws Exception { }
-
- @After
- public void tearDown() throws Exception { }
-
- @Test
- public void testEquality() {
- List<String> testTypes = new ArrayList<>();
- testTypes.add("TEST_TYPE_1");
- testTypes.add("TEST_TYPE_2");
- RouteDiscoveryPreference request = new RouteDiscoveryPreference.Builder(testTypes, true)
- .build();
-
- RouteDiscoveryPreference requestRebuilt = new RouteDiscoveryPreference.Builder(request)
- .build();
-
- assertEquals(request, requestRebuilt);
-
- Parcel parcel = Parcel.obtain();
- parcel.writeParcelable(request, 0);
- parcel.setDataPosition(0);
- RouteDiscoveryPreference requestFromParcel = parcel.readParcelable(null);
-
- assertEquals(request, requestFromParcel);
- }
-
- @Test
- public void testInequality() {
- List<String> testTypes = new ArrayList<>();
- testTypes.add("TEST_TYPE_1");
- testTypes.add("TEST_TYPE_2");
-
- List<String> testTypes2 = new ArrayList<>();
- testTypes.add("TEST_TYPE_3");
-
- RouteDiscoveryPreference request = new RouteDiscoveryPreference.Builder(testTypes, true)
- .build();
-
- RouteDiscoveryPreference requestTypes = new RouteDiscoveryPreference.Builder(request)
- .setPreferredFeatures(testTypes2)
- .build();
- assertNotEquals(request, requestTypes);
-
- RouteDiscoveryPreference requestActiveScan = new RouteDiscoveryPreference.Builder(request)
- .setActiveScan(false)
- .build();
- assertNotEquals(request, requestActiveScan);
- }
-}
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/RoutingSessionInfoTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/RoutingSessionInfoTest.java
deleted file mode 100644
index 704dca0427ed..000000000000
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/RoutingSessionInfoTest.java
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaroutertest;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.testng.Assert.assertThrows;
-
-import android.media.RoutingSessionInfo;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests {@link RoutingSessionInfo} and its {@link RoutingSessionInfo.Builder builder}.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class RoutingSessionInfoTest {
- public static final String TEST_ID = "test_id";
- public static final String TEST_CLIENT_PACKAGE_NAME = "com.test.client.package.name";
- public static final String TEST_ROUTE_FEATURE = "test_route_feature";
-
- public static final String TEST_ROUTE_ID_0 = "test_route_type_0";
- public static final String TEST_ROUTE_ID_1 = "test_route_type_1";
- public static final String TEST_ROUTE_ID_2 = "test_route_type_2";
- public static final String TEST_ROUTE_ID_3 = "test_route_type_3";
- public static final String TEST_ROUTE_ID_4 = "test_route_type_4";
- public static final String TEST_ROUTE_ID_5 = "test_route_type_5";
- public static final String TEST_ROUTE_ID_6 = "test_route_type_6";
- public static final String TEST_ROUTE_ID_7 = "test_route_type_7";
-
- public static final String TEST_KEY = "test_key";
- public static final String TEST_VALUE = "test_value";
-
- @Test
- public void testBuilderConstructorWithInvalidValues() {
- final String nullId = null;
- final String nullClientPackageName = null;
-
- final String emptyId = "";
- // Note: An empty string as client package name is valid.
-
- final String validId = TEST_ID;
- final String validClientPackageName = TEST_CLIENT_PACKAGE_NAME;
-
- // ID is invalid
- assertThrows(IllegalArgumentException.class, () -> new RoutingSessionInfo.Builder(
- nullId, validClientPackageName));
- assertThrows(IllegalArgumentException.class, () -> new RoutingSessionInfo.Builder(
- emptyId, validClientPackageName));
-
- // client package name is invalid (null)
- assertThrows(NullPointerException.class, () -> new RoutingSessionInfo.Builder(
- validId, nullClientPackageName));
-
- // Both are invalid
- assertThrows(IllegalArgumentException.class, () -> new RoutingSessionInfo.Builder(
- nullId, nullClientPackageName));
- assertThrows(IllegalArgumentException.class, () -> new RoutingSessionInfo.Builder(
- emptyId, nullClientPackageName));
- }
-
- @Test
- public void testBuilderCopyConstructorWithNull() {
- // Null RouteInfo (1-argument constructor)
- final RoutingSessionInfo nullRoutingSessionInfo = null;
- assertThrows(NullPointerException.class,
- () -> new RoutingSessionInfo.Builder(nullRoutingSessionInfo));
- }
-
- @Test
- public void testBuilderConstructorWithEmptyClientPackageName() {
- // An empty string for client package name is valid. (for unknown cases)
- // Creating builder with it should not throw any exception.
- RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
- TEST_ID, "" /* clientPackageName*/);
- }
-
- @Test
- public void testBuilderBuildWithEmptySelectedRoutesThrowsIAE() {
- RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME);
- // Note: Calling build() without adding any selected routes.
- assertThrows(IllegalArgumentException.class, () -> builder.build());
- }
-
- @Test
- public void testBuilderAddRouteMethodsWithIllegalArgumentsThrowsIAE() {
- RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME);
-
- final String nullRouteId = null;
- final String emptyRouteId = "";
-
- assertThrows(IllegalArgumentException.class,
- () -> builder.addSelectedRoute(nullRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.addSelectableRoute(nullRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.addDeselectableRoute(nullRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.addTransferrableRoute(nullRouteId));
-
- assertThrows(IllegalArgumentException.class,
- () -> builder.addSelectedRoute(emptyRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.addSelectableRoute(emptyRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.addDeselectableRoute(emptyRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.addTransferrableRoute(emptyRouteId));
- }
-
- @Test
- public void testBuilderRemoveRouteMethodsWithIllegalArgumentsThrowsIAE() {
- RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME);
-
- final String nullRouteId = null;
- final String emptyRouteId = "";
-
- assertThrows(IllegalArgumentException.class,
- () -> builder.removeSelectedRoute(nullRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.removeSelectableRoute(nullRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.removeDeselectableRoute(nullRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.removeTransferrableRoute(nullRouteId));
-
- assertThrows(IllegalArgumentException.class,
- () -> builder.removeSelectedRoute(emptyRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.removeSelectableRoute(emptyRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.removeDeselectableRoute(emptyRouteId));
- assertThrows(IllegalArgumentException.class,
- () -> builder.removeTransferrableRoute(emptyRouteId));
- }
-
- @Test
- public void testBuilderAndGettersOfRoutingSessionInfo() {
- Bundle controlHints = new Bundle();
- controlHints.putString(TEST_KEY, TEST_VALUE);
-
- RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME)
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .addSelectedRoute(TEST_ROUTE_ID_1)
- .addSelectableRoute(TEST_ROUTE_ID_2)
- .addSelectableRoute(TEST_ROUTE_ID_3)
- .addDeselectableRoute(TEST_ROUTE_ID_4)
- .addDeselectableRoute(TEST_ROUTE_ID_5)
- .addTransferrableRoute(TEST_ROUTE_ID_6)
- .addTransferrableRoute(TEST_ROUTE_ID_7)
- .setControlHints(controlHints)
- .build();
-
- assertEquals(TEST_ID, sessionInfo.getId());
- assertEquals(TEST_CLIENT_PACKAGE_NAME, sessionInfo.getClientPackageName());
-
- assertEquals(2, sessionInfo.getSelectedRoutes().size());
- assertEquals(TEST_ROUTE_ID_0, sessionInfo.getSelectedRoutes().get(0));
- assertEquals(TEST_ROUTE_ID_1, sessionInfo.getSelectedRoutes().get(1));
-
- assertEquals(2, sessionInfo.getSelectableRoutes().size());
- assertEquals(TEST_ROUTE_ID_2, sessionInfo.getSelectableRoutes().get(0));
- assertEquals(TEST_ROUTE_ID_3, sessionInfo.getSelectableRoutes().get(1));
-
- assertEquals(2, sessionInfo.getDeselectableRoutes().size());
- assertEquals(TEST_ROUTE_ID_4, sessionInfo.getDeselectableRoutes().get(0));
- assertEquals(TEST_ROUTE_ID_5, sessionInfo.getDeselectableRoutes().get(1));
-
- assertEquals(2, sessionInfo.getTransferrableRoutes().size());
- assertEquals(TEST_ROUTE_ID_6, sessionInfo.getTransferrableRoutes().get(0));
- assertEquals(TEST_ROUTE_ID_7, sessionInfo.getTransferrableRoutes().get(1));
-
- Bundle controlHintsOut = sessionInfo.getControlHints();
- assertNotNull(controlHintsOut);
- assertTrue(controlHintsOut.containsKey(TEST_KEY));
- assertEquals(TEST_VALUE, controlHintsOut.getString(TEST_KEY));
- }
-
- @Test
- public void testBuilderAddRouteMethodsWithBuilderCopyConstructor() {
- RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME)
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .addSelectableRoute(TEST_ROUTE_ID_2)
- .addDeselectableRoute(TEST_ROUTE_ID_4)
- .addTransferrableRoute(TEST_ROUTE_ID_6)
- .build();
-
- RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo)
- .addSelectedRoute(TEST_ROUTE_ID_1)
- .addSelectableRoute(TEST_ROUTE_ID_3)
- .addDeselectableRoute(TEST_ROUTE_ID_5)
- .addTransferrableRoute(TEST_ROUTE_ID_7)
- .build();
-
- assertEquals(2, newSessionInfo.getSelectedRoutes().size());
- assertEquals(TEST_ROUTE_ID_0, newSessionInfo.getSelectedRoutes().get(0));
- assertEquals(TEST_ROUTE_ID_1, newSessionInfo.getSelectedRoutes().get(1));
-
- assertEquals(2, newSessionInfo.getSelectableRoutes().size());
- assertEquals(TEST_ROUTE_ID_2, newSessionInfo.getSelectableRoutes().get(0));
- assertEquals(TEST_ROUTE_ID_3, newSessionInfo.getSelectableRoutes().get(1));
-
- assertEquals(2, newSessionInfo.getDeselectableRoutes().size());
- assertEquals(TEST_ROUTE_ID_4, newSessionInfo.getDeselectableRoutes().get(0));
- assertEquals(TEST_ROUTE_ID_5, newSessionInfo.getDeselectableRoutes().get(1));
-
- assertEquals(2, newSessionInfo.getTransferrableRoutes().size());
- assertEquals(TEST_ROUTE_ID_6, newSessionInfo.getTransferrableRoutes().get(0));
- assertEquals(TEST_ROUTE_ID_7, newSessionInfo.getTransferrableRoutes().get(1));
- }
-
- @Test
- public void testBuilderRemoveRouteMethods() {
- RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME)
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .addSelectedRoute(TEST_ROUTE_ID_1)
- .removeSelectedRoute(TEST_ROUTE_ID_1)
-
- .addSelectableRoute(TEST_ROUTE_ID_2)
- .addSelectableRoute(TEST_ROUTE_ID_3)
- .removeSelectableRoute(TEST_ROUTE_ID_3)
-
- .addDeselectableRoute(TEST_ROUTE_ID_4)
- .addDeselectableRoute(TEST_ROUTE_ID_5)
- .removeDeselectableRoute(TEST_ROUTE_ID_5)
-
- .addTransferrableRoute(TEST_ROUTE_ID_6)
- .addTransferrableRoute(TEST_ROUTE_ID_7)
- .removeTransferrableRoute(TEST_ROUTE_ID_7)
-
- .build();
-
- assertEquals(1, sessionInfo.getSelectedRoutes().size());
- assertEquals(TEST_ROUTE_ID_0, sessionInfo.getSelectedRoutes().get(0));
-
- assertEquals(1, sessionInfo.getSelectableRoutes().size());
- assertEquals(TEST_ROUTE_ID_2, sessionInfo.getSelectableRoutes().get(0));
-
- assertEquals(1, sessionInfo.getDeselectableRoutes().size());
- assertEquals(TEST_ROUTE_ID_4, sessionInfo.getDeselectableRoutes().get(0));
-
- assertEquals(1, sessionInfo.getTransferrableRoutes().size());
- assertEquals(TEST_ROUTE_ID_6, sessionInfo.getTransferrableRoutes().get(0));
- }
-
- @Test
- public void testBuilderRemoveRouteMethodsWithBuilderCopyConstructor() {
- RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME)
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .addSelectedRoute(TEST_ROUTE_ID_1)
- .addSelectableRoute(TEST_ROUTE_ID_2)
- .addSelectableRoute(TEST_ROUTE_ID_3)
- .addDeselectableRoute(TEST_ROUTE_ID_4)
- .addDeselectableRoute(TEST_ROUTE_ID_5)
- .addTransferrableRoute(TEST_ROUTE_ID_6)
- .addTransferrableRoute(TEST_ROUTE_ID_7)
- .build();
-
- RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo)
- .removeSelectedRoute(TEST_ROUTE_ID_1)
- .removeSelectableRoute(TEST_ROUTE_ID_3)
- .removeDeselectableRoute(TEST_ROUTE_ID_5)
- .removeTransferrableRoute(TEST_ROUTE_ID_7)
- .build();
-
- assertEquals(1, newSessionInfo.getSelectedRoutes().size());
- assertEquals(TEST_ROUTE_ID_0, newSessionInfo.getSelectedRoutes().get(0));
-
- assertEquals(1, newSessionInfo.getSelectableRoutes().size());
- assertEquals(TEST_ROUTE_ID_2, newSessionInfo.getSelectableRoutes().get(0));
-
- assertEquals(1, newSessionInfo.getDeselectableRoutes().size());
- assertEquals(TEST_ROUTE_ID_4, newSessionInfo.getDeselectableRoutes().get(0));
-
- assertEquals(1, newSessionInfo.getTransferrableRoutes().size());
- assertEquals(TEST_ROUTE_ID_6, newSessionInfo.getTransferrableRoutes().get(0));
- }
-
- @Test
- public void testBuilderClearRouteMethods() {
- RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME)
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .addSelectedRoute(TEST_ROUTE_ID_1)
- .clearSelectedRoutes()
-
- .addSelectableRoute(TEST_ROUTE_ID_2)
- .addSelectableRoute(TEST_ROUTE_ID_3)
- .clearSelectableRoutes()
-
- .addDeselectableRoute(TEST_ROUTE_ID_4)
- .addDeselectableRoute(TEST_ROUTE_ID_5)
- .clearDeselectableRoutes()
-
- .addTransferrableRoute(TEST_ROUTE_ID_6)
- .addTransferrableRoute(TEST_ROUTE_ID_7)
- .clearTransferrableRoutes()
-
- // SelectedRoutes must not be empty
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .build();
-
- assertEquals(1, sessionInfo.getSelectedRoutes().size());
- assertEquals(TEST_ROUTE_ID_0, sessionInfo.getSelectedRoutes().get(0));
-
- assertTrue(sessionInfo.getSelectableRoutes().isEmpty());
- assertTrue(sessionInfo.getDeselectableRoutes().isEmpty());
- assertTrue(sessionInfo.getTransferrableRoutes().isEmpty());
- }
-
- @Test
- public void testBuilderClearRouteMethodsWithBuilderCopyConstructor() {
- RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME)
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .addSelectedRoute(TEST_ROUTE_ID_1)
- .addSelectableRoute(TEST_ROUTE_ID_2)
- .addSelectableRoute(TEST_ROUTE_ID_3)
- .addDeselectableRoute(TEST_ROUTE_ID_4)
- .addDeselectableRoute(TEST_ROUTE_ID_5)
- .addTransferrableRoute(TEST_ROUTE_ID_6)
- .addTransferrableRoute(TEST_ROUTE_ID_7)
- .build();
-
- RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo)
- .clearSelectedRoutes()
- .clearSelectableRoutes()
- .clearDeselectableRoutes()
- .clearTransferrableRoutes()
- // SelectedRoutes must not be empty
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .build();
-
- assertEquals(1, newSessionInfo.getSelectedRoutes().size());
- assertEquals(TEST_ROUTE_ID_0, newSessionInfo.getSelectedRoutes().get(0));
-
- assertTrue(newSessionInfo.getSelectableRoutes().isEmpty());
- assertTrue(newSessionInfo.getDeselectableRoutes().isEmpty());
- assertTrue(newSessionInfo.getTransferrableRoutes().isEmpty());
- }
-
- @Test
- public void testEqualsCreatedWithSameArguments() {
- Bundle controlHints = new Bundle();
- controlHints.putString(TEST_KEY, TEST_VALUE);
-
- RoutingSessionInfo sessionInfo1 = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME)
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .addSelectedRoute(TEST_ROUTE_ID_1)
- .addSelectableRoute(TEST_ROUTE_ID_2)
- .addSelectableRoute(TEST_ROUTE_ID_3)
- .addDeselectableRoute(TEST_ROUTE_ID_4)
- .addDeselectableRoute(TEST_ROUTE_ID_5)
- .addTransferrableRoute(TEST_ROUTE_ID_6)
- .addTransferrableRoute(TEST_ROUTE_ID_7)
- .setControlHints(controlHints)
- .build();
-
- RoutingSessionInfo sessionInfo2 = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME)
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .addSelectedRoute(TEST_ROUTE_ID_1)
- .addSelectableRoute(TEST_ROUTE_ID_2)
- .addSelectableRoute(TEST_ROUTE_ID_3)
- .addDeselectableRoute(TEST_ROUTE_ID_4)
- .addDeselectableRoute(TEST_ROUTE_ID_5)
- .addTransferrableRoute(TEST_ROUTE_ID_6)
- .addTransferrableRoute(TEST_ROUTE_ID_7)
- .setControlHints(controlHints)
- .build();
-
- assertEquals(sessionInfo1, sessionInfo2);
- assertEquals(sessionInfo1.hashCode(), sessionInfo2.hashCode());
- }
-
- @Test
- public void testEqualsCreatedWithBuilderCopyConstructor() {
- Bundle controlHints = new Bundle();
- controlHints.putString(TEST_KEY, TEST_VALUE);
-
- RoutingSessionInfo sessionInfo1 = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME)
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .addSelectedRoute(TEST_ROUTE_ID_1)
- .addSelectableRoute(TEST_ROUTE_ID_2)
- .addSelectableRoute(TEST_ROUTE_ID_3)
- .addDeselectableRoute(TEST_ROUTE_ID_4)
- .addDeselectableRoute(TEST_ROUTE_ID_5)
- .addTransferrableRoute(TEST_ROUTE_ID_6)
- .addTransferrableRoute(TEST_ROUTE_ID_7)
- .setControlHints(controlHints)
- .build();
-
- RoutingSessionInfo sessionInfo2 = new RoutingSessionInfo.Builder(sessionInfo1).build();
-
- assertEquals(sessionInfo1, sessionInfo2);
- assertEquals(sessionInfo1.hashCode(), sessionInfo2.hashCode());
- }
-
- @Test
- public void testEqualsReturnFalse() {
- Bundle controlHints = new Bundle();
- controlHints.putString(TEST_KEY, TEST_VALUE);
-
- RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME)
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .addSelectedRoute(TEST_ROUTE_ID_1)
- .addSelectableRoute(TEST_ROUTE_ID_2)
- .addSelectableRoute(TEST_ROUTE_ID_3)
- .addDeselectableRoute(TEST_ROUTE_ID_4)
- .addDeselectableRoute(TEST_ROUTE_ID_5)
- .addTransferrableRoute(TEST_ROUTE_ID_6)
- .addTransferrableRoute(TEST_ROUTE_ID_7)
- .setControlHints(controlHints)
- .build();
-
- // Now, we will use copy constructor
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .addSelectedRoute("randomRoute")
- .build());
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .addSelectableRoute("randomRoute")
- .build());
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .addDeselectableRoute("randomRoute")
- .build());
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .addTransferrableRoute("randomRoute")
- .build());
-
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .removeSelectedRoute(TEST_ROUTE_ID_1)
- .build());
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .removeSelectableRoute(TEST_ROUTE_ID_3)
- .build());
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .removeDeselectableRoute(TEST_ROUTE_ID_5)
- .build());
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .removeTransferrableRoute(TEST_ROUTE_ID_7)
- .build());
-
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .clearSelectedRoutes()
- // Note: Calling build() with empty selected routes will throw IAE.
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .build());
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .clearSelectableRoutes()
- .build());
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .clearDeselectableRoutes()
- .build());
- assertNotEquals(sessionInfo, new RoutingSessionInfo.Builder(sessionInfo)
- .clearTransferrableRoutes()
- .build());
-
- // Note: ControlHints will not affect the equals.
- }
-
- @Test
- public void testParcelingAndUnParceling() {
- Bundle controlHints = new Bundle();
- controlHints.putString(TEST_KEY, TEST_VALUE);
-
- RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(
- TEST_ID, TEST_CLIENT_PACKAGE_NAME)
- .addSelectedRoute(TEST_ROUTE_ID_0)
- .addSelectedRoute(TEST_ROUTE_ID_1)
- .addSelectableRoute(TEST_ROUTE_ID_2)
- .addSelectableRoute(TEST_ROUTE_ID_3)
- .addDeselectableRoute(TEST_ROUTE_ID_4)
- .addDeselectableRoute(TEST_ROUTE_ID_5)
- .addTransferrableRoute(TEST_ROUTE_ID_6)
- .addTransferrableRoute(TEST_ROUTE_ID_7)
- .setControlHints(controlHints)
- .build();
-
- Parcel parcel = Parcel.obtain();
- sessionInfo.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
-
- RoutingSessionInfo sessionInfoFromParcel =
- RoutingSessionInfo.CREATOR.createFromParcel(parcel);
- assertEquals(sessionInfo, sessionInfoFromParcel);
- assertEquals(sessionInfo.hashCode(), sessionInfoFromParcel.hashCode());
-
- // Check controlHints
- Bundle controlHintsOut = sessionInfoFromParcel.getControlHints();
- assertNotNull(controlHintsOut);
- assertTrue(controlHintsOut.containsKey(TEST_KEY));
- assertEquals(TEST_VALUE, controlHintsOut.getString(TEST_KEY));
- }
-}
diff --git a/mms/java/android/telephony/MmsManager.java b/mms/java/android/telephony/MmsManager.java
index cf55eba6e5ba..f07cd5e34062 100644
--- a/mms/java/android/telephony/MmsManager.java
+++ b/mms/java/android/telephony/MmsManager.java
@@ -55,10 +55,12 @@ public class MmsManager {
* sending the message.
* @param sentIntent if not NULL this <code>PendingIntent</code> is broadcast when the message
* is successfully sent, or failed
+ * @param messageId an id that uniquely identifies the message requested to be sent.
+ * Used for logging and diagnostics purposes. The id may be 0.
*/
public void sendMultimediaMessage(int subId, @NonNull Uri contentUri,
@Nullable String locationUrl, @Nullable Bundle configOverrides,
- @Nullable PendingIntent sentIntent) {
+ @Nullable PendingIntent sentIntent, long messageId) {
try {
final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms"));
if (iMms == null) {
@@ -66,7 +68,7 @@ public class MmsManager {
}
iMms.sendMessage(subId, ActivityThread.currentPackageName(), contentUri,
- locationUrl, configOverrides, sentIntent);
+ locationUrl, configOverrides, sentIntent, messageId);
} catch (RemoteException e) {
// Ignore it
}
@@ -83,18 +85,22 @@ public class MmsManager {
* downloading the message.
* @param downloadedIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is downloaded, or the download is failed
+ * @param messageId an id that uniquely identifies the message requested to be downloaded.
+ * Used for logging and diagnostics purposes. The id may be 0.
+ * downloaded.
* @throws IllegalArgumentException if locationUrl or contentUri is empty
*/
public void downloadMultimediaMessage(int subId, @NonNull String locationUrl,
@NonNull Uri contentUri, @Nullable Bundle configOverrides,
- @Nullable PendingIntent downloadedIntent) {
+ @Nullable PendingIntent downloadedIntent, long messageId) {
try {
final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms"));
if (iMms == null) {
return;
}
iMms.downloadMessage(subId, ActivityThread.currentPackageName(),
- locationUrl, contentUri, configOverrides, downloadedIntent);
+ locationUrl, contentUri, configOverrides, downloadedIntent,
+ messageId);
} catch (RemoteException e) {
// Ignore it
}
diff --git a/mms/java/com/android/internal/telephony/IMms.aidl b/mms/java/com/android/internal/telephony/IMms.aidl
index 8be511186800..e0e0a4a812e4 100644
--- a/mms/java/com/android/internal/telephony/IMms.aidl
+++ b/mms/java/com/android/internal/telephony/IMms.aidl
@@ -37,9 +37,11 @@ interface IMms {
* sending the message. See {@link android.telephony.SmsManager} for the value names and types.
* @param sentIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is successfully sent, or failed
+ * @param messageId An id that uniquely identifies the message requested to be sent.
*/
void sendMessage(int subId, String callingPkg, in Uri contentUri,
- String locationUrl, in Bundle configOverrides, in PendingIntent sentIntent);
+ String locationUrl, in Bundle configOverrides, in PendingIntent sentIntent,
+ in long messageId);
/**
* Download an MMS message using known location and transaction id
@@ -54,10 +56,11 @@ interface IMms {
* types.
* @param downloadedIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is downloaded, or the download is failed
- */
+ * @param messageId An id that uniquely identifies the message requested to be downloaded.
+ */
void downloadMessage(int subId, String callingPkg, String locationUrl,
in Uri contentUri, in Bundle configOverrides,
- in PendingIntent downloadedIntent);
+ in PendingIntent downloadedIntent, in long messageId);
/**
* Import a text message into system's SMS store
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index 851a3d8f136a..d65d821e71ab 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -252,7 +252,7 @@
<item msgid="3474333938380896988">"عرض مناطق العجز في رؤية اللونين الأخضر والأحمر"</item>
</string-array>
<string-array name="app_process_limit_entries">
- <item msgid="794656271086646068">"الحد القياسي"</item>
+ <item msgid="794656271086646068">"الحدّ العادي"</item>
<item msgid="8628438298170567201">"ليست هناك عمليات بالخلفية"</item>
<item msgid="915752993383950932">"عملية واحدة بحد أقصى"</item>
<item msgid="8554877790859095133">"عمليتان بحد أقصى"</item>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 54856566e021..5103345401f4 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -124,7 +124,7 @@
<string name="bluetooth_talkback_headset" msgid="3406852564400882682">"سماعة رأس"</string>
<string name="bluetooth_talkback_phone" msgid="868393783858123880">"هاتف"</string>
<string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"تصوير"</string>
- <string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"سماعة أذن"</string>
+ <string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"السمّاعة"</string>
<string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"جهاز إدخال طرفي"</string>
<string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"بلوتوث"</string>
<string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"جارٍ إقران سماعة الأذن الطبية اليسرى…"</string>
@@ -157,7 +157,7 @@
<string name="tts_settings" msgid="8130616705989351312">"إعدادات تحويل النص إلى كلام"</string>
<string name="tts_settings_title" msgid="7602210956640483039">"تحويل النص إلى كلام"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"معدل سرعة الكلام"</string>
- <string name="tts_default_rate_summary" msgid="3781937042151716987">"سرعة نطق الكلام"</string>
+ <string name="tts_default_rate_summary" msgid="3781937042151716987">"سرعة قول الكلام"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"درجة الصوت"</string>
<string name="tts_default_pitch_summary" msgid="9132719475281551884">"للتأثير في نبرة الكلام المُرَكَّب"</string>
<string name="tts_default_lang_title" msgid="4698933575028098940">"اللغة"</string>
@@ -181,7 +181,7 @@
<string name="tts_engine_preference_section_title" msgid="3861562305498624904">"المحرّك المفضّل"</string>
<string name="tts_general_section_title" msgid="8919671529502364567">"عامة"</string>
<string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"إعادة ضبط طبقة صوت الكلام"</string>
- <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"إعادة ضبط طبقة الصوت التي يتم نطق النص بها على الإعداد التلقائي."</string>
+ <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"إعادة ضبط طبقة الصوت التي يتم قول النص بها على الإعداد التلقائي."</string>
<string-array name="tts_rate_entries">
<item msgid="9004239613505400644">"بطيء جدًا"</item>
<item msgid="1815382991399815061">"بطيء"</item>
@@ -353,7 +353,7 @@
<string-array name="color_mode_names">
<item msgid="3836559907767149216">"نابض بالحياة (تلقائي)"</item>
<item msgid="9112200311983078311">"طبيعي"</item>
- <item msgid="6564241960833766170">"قياسي"</item>
+ <item msgid="6564241960833766170">"عادي"</item>
</string-array>
<string-array name="color_mode_descriptions">
<item msgid="6828141153199944847">"ألوان محسَّنة"</item>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index cda42d348c45..5bcff5ad27b2 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -201,7 +201,7 @@
<string name="development_settings_summary" msgid="8718917813868735095">"Đặt tùy chọn cho phát triển ứng dụng"</string>
<string name="development_settings_not_available" msgid="355070198089140951">"Tùy chọn dành cho nhà phát triển không khả dụng cho người dùng này"</string>
<string name="vpn_settings_not_available" msgid="2894137119965668920">"Cài đặt VPN không khả dụng cho người dùng này"</string>
- <string name="tethering_settings_not_available" msgid="266821736434699780">"Cài đặt chia sẻ kết nối không khả dụng cho người dùng này"</string>
+ <string name="tethering_settings_not_available" msgid="266821736434699780">"Cài đặt cách chia sẻ kết nối không khả dụng cho người dùng này"</string>
<string name="apn_settings_not_available" msgid="1147111671403342300">"Cài đặt tên điểm truy cập không khả dụng cho người dùng này"</string>
<string name="enable_adb" msgid="8072776357237289039">"Gỡ lỗi qua USB"</string>
<string name="enable_adb_summary" msgid="3711526030096574316">"Bật chế độ gỡ lỗi khi kết nối USB"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java b/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java
index b01fc8541957..f5aa652f3194 100644
--- a/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java
+++ b/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java
@@ -216,7 +216,7 @@ public class NetworkPolicyEditor {
private static NetworkTemplate buildUnquotedNetworkTemplate(NetworkTemplate template) {
if (template == null) return null;
final String networkId = template.getNetworkId();
- final String strippedNetworkId = WifiInfo.removeDoubleQuotes(networkId);
+ final String strippedNetworkId = WifiInfo.sanitizeSsid(networkId);
if (!TextUtils.equals(strippedNetworkId, networkId)) {
return new NetworkTemplate(
template.getMatchRule(), template.getSubscriberId(), strippedNetworkId);
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 65269c9d5a89..dee1d7eced66 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -728,6 +728,7 @@ public class SettingsBackupTest {
Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
Settings.Secure.FACE_UNLOCK_RE_ENROLL,
Settings.Secure.TAP_GESTURE,
+ Settings.Secure.NEARBY_SHARING_COMPONENT, // not user configurable
Settings.Secure.WINDOW_MAGNIFICATION,
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER,
Settings.Secure.SUPPRESS_DOZE);
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index c238d7d49f9b..de174b13a459 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -69,10 +69,6 @@ android_library {
],
manifest: "AndroidManifest.xml",
- libs: [
- "telephony-common",
- ],
-
kotlincflags: ["-Xjvm-default=enable"],
plugins: ["dagger2-compiler-2.19"],
@@ -136,7 +132,6 @@ android_library {
],
libs: [
"android.test.runner",
- "telephony-common",
"android.test.base",
],
kotlincflags: ["-Xjvm-default=enable"],
@@ -163,10 +158,6 @@ android_app {
proguard_flags_files: ["proguard.flags"],
},
- libs: [
- "telephony-common",
- ],
-
kotlincflags: ["-Xjvm-default=enable"],
dxflags: ["--multi-dex"],
diff --git a/packages/SystemUI/docs/plugin_hooks.md b/packages/SystemUI/docs/plugin_hooks.md
index 2fb0c996111a..9fe2e181971a 100644
--- a/packages/SystemUI/docs/plugin_hooks.md
+++ b/packages/SystemUI/docs/plugin_hooks.md
@@ -56,11 +56,6 @@ Expected interface: [ClockPlugin](/packages/SystemUI/plugin/src/com/android/syst
Use: Allows replacement of the keyguard main clock.
-### Action: com.android.systemui.action.PLUGIN_NPV
-Expected interface: [NPVPlugin](/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java)
-
-Use: Attach a view under QQS for prototyping.
-
# Global plugin dependencies
These classes can be accessed by any plugin using PluginDependency as long as they @Requires them.
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/HomeControlsPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/HomeControlsPlugin.java
deleted file mode 100644
index c1d4b03b6620..000000000000
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/HomeControlsPlugin.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.plugins;
-
-import android.view.ViewGroup;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * Test plugin for home controls
- */
-@ProvidesInterface(action = HomeControlsPlugin.ACTION, version = HomeControlsPlugin.VERSION)
-public interface HomeControlsPlugin extends Plugin {
-
- String ACTION = "com.android.systemui.action.PLUGIN_HOME_CONTROLS";
- int VERSION = 1;
-
- /**
- * Pass the container for the plugin to use however it wants. Ideally the plugin impl
- * will add home controls to this space.
- */
- void sendParentGroup(ViewGroup group);
-
- /**
- * When visible, will poll for updates.
- */
- void setVisible(boolean visible);
-}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java
deleted file mode 100644
index 1426266a7048..000000000000
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins;
-
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * Plugin to attach custom views under QQS.
- *
- * A parent view is provided to the plugin to which they can add Views.
- * <br>
- * The parent is a {@link FrameLayout} with same background as QS and 96dp height.
- *
- * {@see NPVPluginManager}
- * {@see status_bar_expanded_plugin_frame}
- */
-@ProvidesInterface(action = NPVPlugin.ACTION, version = NPVPlugin.VERSION)
-public interface NPVPlugin extends Plugin {
- String ACTION = "com.android.systemui.action.PLUGIN_NPV";
- int VERSION = 1;
-
- /**
- * Attach views to the parent.
- *
- * @param parent a {@link FrameLayout} to which to attach views. Preferably a root view.
- * @return a view attached to parent.
- */
- View attachToRoot(FrameLayout parent);
-
- /**
- * Indicate to the plugin when it is listening (QS expanded)
- * @param listening
- */
- default void setListening(boolean listening) {};
-}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index 17f2f476c9f2..6518924ca0c2 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -133,7 +133,6 @@ public interface QSTile {
public CharSequence label;
public CharSequence secondaryLabel;
public CharSequence contentDescription;
- public CharSequence stateDescription;
public CharSequence dualLabelContentDescription;
public boolean disabledByPolicy;
public boolean dualTarget = false;
@@ -152,7 +151,6 @@ public interface QSTile {
|| !Objects.equals(other.label, label)
|| !Objects.equals(other.secondaryLabel, secondaryLabel)
|| !Objects.equals(other.contentDescription, contentDescription)
- || !Objects.equals(other.stateDescription, stateDescription)
|| !Objects.equals(other.dualLabelContentDescription,
dualLabelContentDescription)
|| !Objects.equals(other.expandedAccessibilityClassName,
@@ -170,7 +168,6 @@ public interface QSTile {
other.label = label;
other.secondaryLabel = secondaryLabel;
other.contentDescription = contentDescription;
- other.stateDescription = stateDescription;
other.dualLabelContentDescription = dualLabelContentDescription;
other.expandedAccessibilityClassName = expandedAccessibilityClassName;
other.disabledByPolicy = disabledByPolicy;
@@ -198,7 +195,6 @@ public interface QSTile {
sb.append(",label=").append(label);
sb.append(",secondaryLabel=").append(secondaryLabel);
sb.append(",contentDescription=").append(contentDescription);
- sb.append(",stateDescription=").append(stateDescription);
sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription);
sb.append(",expandedAccessibilityClassName=").append(expandedAccessibilityClassName);
sb.append(",disabledByPolicy=").append(disabledByPolicy);
diff --git a/packages/SystemUI/res/drawable/control_no_favorites_background.xml b/packages/SystemUI/res/drawable/control_no_favorites_background.xml
index 1e282ad0eec7..947c77b4e39e 100644
--- a/packages/SystemUI/res/drawable/control_no_favorites_background.xml
+++ b/packages/SystemUI/res/drawable/control_no_favorites_background.xml
@@ -17,6 +17,6 @@
*/
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <stroke android:width="1dp" android:color="?android:attr/colorBackgroundFloating"/>
+ <stroke android:width="1dp" android:color="@*android:color/foreground_material_dark"/>
<corners android:radius="@dimen/control_corner_radius" />
</shape>
diff --git a/packages/SystemUI/res/layout/controls_base_item.xml b/packages/SystemUI/res/layout/controls_base_item.xml
index 3c4c61e30bc1..cd7ec5eb5c81 100644
--- a/packages/SystemUI/res/layout/controls_base_item.xml
+++ b/packages/SystemUI/res/layout/controls_base_item.xml
@@ -23,8 +23,8 @@
android:padding="@dimen/control_padding"
android:clickable="true"
android:focusable="true"
- android:layout_marginLeft="3dp"
- android:layout_marginRight="3dp"
+ android:layout_marginLeft="2dp"
+ android:layout_marginRight="2dp"
android:background="@drawable/control_background">
<ImageView
@@ -60,9 +60,9 @@
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textSize="18sp"
+ android:textSize="14sp"
android:textColor="?android:attr/textColorPrimary"
- android:fontFamily="@*android:string/config_headlineFontFamily"
+ android:textAppearance="?android:attr/textAppearanceSmall"
app:layout_constraintBottom_toTopOf="@+id/subtitle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/icon" />
@@ -71,9 +71,9 @@
android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textSize="16sp"
+ android:textSize="12sp"
android:textColor="?android:attr/textColorSecondary"
- android:fontFamily="@*android:string/config_headlineFontFamily"
+ android:textAppearance="?android:attr/textAppearanceSmall"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout/controls_no_favorites.xml b/packages/SystemUI/res/layout/controls_no_favorites.xml
index 79672caed61b..096f1f49aaba 100644
--- a/packages/SystemUI/res/layout/controls_no_favorites.xml
+++ b/packages/SystemUI/res/layout/controls_no_favorites.xml
@@ -12,7 +12,7 @@
android:paddingBottom="40dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
- android:textColor="?android:attr/textColorPrimary"
+ android:textColor="@*android:color/foreground_material_dark"
android:fontFamily="@*android:string/config_headlineFontFamily"
android:background="@drawable/control_no_favorites_background"/>
</merge>
diff --git a/packages/SystemUI/res/layout/controls_with_favorites.xml b/packages/SystemUI/res/layout/controls_with_favorites.xml
index 7804fe6b6272..6a3e95d34358 100644
--- a/packages/SystemUI/res/layout/controls_with_favorites.xml
+++ b/packages/SystemUI/res/layout/controls_with_favorites.xml
@@ -4,7 +4,8 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content">
+ android:layout_height="wrap_content"
+ android:paddingBottom="20dp">
<TextView
android:text="@string/quick_controls_title"
@@ -13,17 +14,23 @@
android:singleLine="true"
android:gravity="center"
android:textSize="25dp"
- android:textColor="?android:attr/textColorPrimary"
+ android:textColor="@*android:color/foreground_material_dark"
android:fontFamily="@*android:string/config_headlineFontFamily"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"/>
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
<ImageView
android:id="@+id/controls_more"
android:src="@drawable/ic_more_vert"
android:layout_width="34dp"
android:layout_height="24dp"
android:layout_marginEnd="10dp"
- app:layout_constraintEnd_toEndOf="parent"/>
+ android:tint="@*android:color/foreground_material_dark"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout/global_actions_grid_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
index 674148495478..f90012d790e0 100644
--- a/packages/SystemUI/res/layout/global_actions_grid_v2.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
@@ -96,18 +96,18 @@
app:layout_constraintTop_toBottomOf="@id/global_actions_view">
<FrameLayout
- android:translationY="@dimen/global_actions_plugin_offset"
android:id="@+id/global_actions_panel_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
- android:translationY="@dimen/global_actions_plugin_offset"
android:id="@+id/global_actions_controls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
+ android:layout_marginRight="@dimen/global_actions_grid_horizontal_padding"
+ android:layout_marginLeft="@dimen/global_actions_grid_horizontal_padding"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/global_actions_panel">
diff --git a/packages/SystemUI/res/layout/home_controls.xml b/packages/SystemUI/res/layout/home_controls.xml
deleted file mode 100644
index 69a0e872dc8c..000000000000
--- a/packages/SystemUI/res/layout/home_controls.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/home_controls_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="@integer/notification_panel_layout_gravity"
- android:visibility="gone"
- android:padding="8dp"
- android:layout_margin="5dp"
- android:background="?android:attr/colorBackgroundFloating">
-</FrameLayout>
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index 76c1045ef1dd..4fae3c500a45 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -42,32 +42,6 @@
android:visibility="gone"
/>
- <LinearLayout
- android:id="@+id/divider_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- android:background="@color/transparent" >
-
- <android.widget.Space
- android:layout_height="match_parent"
- android:layout_width="0dp"
- android:layout_weight="@integer/qqs_split_fraction" />
-
- <com.android.systemui.DarkReceiverImpl
- android:id="@+id/divider"
- android:layout_height="match_parent"
- android:layout_width="1dp"
- android:layout_marginTop="4dp"
- android:layout_marginBottom="4dp" />
-
- <android.widget.Space
- android:layout_height="match_parent"
- android:layout_width="0dp"
- android:layout_weight="@integer/qs_split_fraction" />
-
- </LinearLayout>
-
<LinearLayout android:id="@+id/status_bar_contents"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 479f255b7e44..115b4a86b86d 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -55,9 +55,6 @@
android:clipChildren="false"
systemui:viewType="com.android.systemui.plugins.qs.QS" />
- <!-- Temporary area to test out home controls -->
- <include layout="@layout/home_controls" />
-
<com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
android:id="@+id/notification_stack_scroller"
android:layout_marginTop="@dimen/notification_panel_margin_top"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index cc58b2014496..1f9fb0511d26 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -972,7 +972,6 @@
<!-- Global actions power menu -->
<dimen name="global_actions_top_margin">12dp</dimen>
- <dimen name="global_actions_plugin_offset">-145dp</dimen>
<dimen name="global_actions_panel_width">120dp</dimen>
<dimen name="global_actions_padding">12dp</dimen>
@@ -1182,7 +1181,7 @@
<dimen name="magnifier_up_down_controls_height">40dp</dimen>
<!-- Home Controls -->
- <dimen name="control_spacing">5dp</dimen>
+ <dimen name="control_spacing">4dp</dimen>
<dimen name="control_corner_radius">15dp</dimen>
<dimen name="control_height">100dp</dimen>
<dimen name="control_padding">15dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 8d935ecc691d..1f13f8dc02fe 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2549,7 +2549,4 @@
<!-- Quick Controls strings [CHAR LIMIT=30] -->
<string name="quick_controls_title">Quick Controls</string>
-
- <!-- The tile in quick settings is unavailable. [CHAR LIMIT=32] -->
- <string name="tile_unavailable">Unvailable</string>
</resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java
deleted file mode 100644
index 78b1b26140d5..000000000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.shared.recents.model;
-
-import static android.content.pm.PackageManager.MATCH_ANY_USER;
-
-import android.app.ActivityManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.util.IconDrawableFactory;
-import android.util.Log;
-import android.util.LruCache;
-
-import com.android.systemui.shared.system.PackageManagerWrapper;
-
-public abstract class IconLoader {
-
- private static final String TAG = "IconLoader";
-
- protected final Context mContext;
- protected final TaskKeyLruCache<Drawable> mIconCache;
- protected final LruCache<ComponentName, ActivityInfo> mActivityInfoCache;
-
- public IconLoader(Context context, TaskKeyLruCache<Drawable> iconCache, LruCache<ComponentName,
- ActivityInfo> activityInfoCache) {
- mContext = context;
- mIconCache = iconCache;
- mActivityInfoCache = activityInfoCache;
- }
-
- /**
- * Returns the activity info for the given task key, retrieving one from the system if the
- * task key is expired.
- *
- * TODO: Move this to an ActivityInfoCache class
- */
- public ActivityInfo getAndUpdateActivityInfo(Task.TaskKey taskKey) {
- ComponentName cn = taskKey.getComponent();
- ActivityInfo activityInfo = mActivityInfoCache.get(cn);
- if (activityInfo == null) {
- activityInfo = PackageManagerWrapper.getInstance().getActivityInfo(cn, taskKey.userId);
- if (cn == null || activityInfo == null) {
- Log.e(TAG, "Unexpected null component name or activity info: " + cn + ", " +
- activityInfo);
- return null;
- }
- mActivityInfoCache.put(cn, activityInfo);
- }
- return activityInfo;
- }
-
- public Drawable getIcon(Task t) {
- Drawable cachedIcon = mIconCache.get(t.key);
- if (cachedIcon == null) {
- cachedIcon = createNewIconForTask(t.key, t.taskDescription, true /* returnDefault */);
- mIconCache.put(t.key, cachedIcon);
- }
- return cachedIcon;
- }
-
- /**
- * Returns the cached task icon if the task key is not expired, updating the cache if it is.
- */
- public Drawable getAndInvalidateIfModified(Task.TaskKey taskKey,
- ActivityManager.TaskDescription td, boolean loadIfNotCached) {
- // Return the cached activity icon if it exists
- Drawable icon = mIconCache.getAndInvalidateIfModified(taskKey);
- if (icon != null) {
- return icon;
- }
-
- if (loadIfNotCached) {
- icon = createNewIconForTask(taskKey, td, false /* returnDefault */);
- if (icon != null) {
- mIconCache.put(taskKey, icon);
- return icon;
- }
- }
-
- // We couldn't load any icon
- return null;
- }
-
- private Drawable createNewIconForTask(Task.TaskKey taskKey,
- ActivityManager.TaskDescription desc, boolean returnDefault) {
- int userId = taskKey.userId;
- Bitmap tdIcon = desc.getInMemoryIcon();
- if (tdIcon != null) {
- return createDrawableFromBitmap(tdIcon, userId, desc);
- }
- if (desc.getIconResource() != 0) {
- try {
- PackageManager pm = mContext.getPackageManager();
- ApplicationInfo appInfo = pm.getApplicationInfo(taskKey.getPackageName(),
- MATCH_ANY_USER);
- Resources res = pm.getResourcesForApplication(appInfo);
- return createBadgedDrawable(res.getDrawable(desc.getIconResource(), null), userId,
- desc);
- } catch (Resources.NotFoundException|PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Could not find icon drawable from resource", e);
- }
- }
-
- tdIcon = ActivityManager.TaskDescription.loadTaskDescriptionIcon(
- desc.getIconFilename(), userId);
- if (tdIcon != null) {
- return createDrawableFromBitmap(tdIcon, userId, desc);
- }
-
- // Load the icon from the activity info and cache it
- ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey);
- if (activityInfo != null) {
- Drawable icon = getBadgedActivityIcon(activityInfo, userId, desc);
- if (icon != null) {
- return icon;
- }
- }
-
- // At this point, even if we can't load the icon, we will set the default icon.
- return returnDefault ? getDefaultIcon(userId) : null;
- }
-
- public abstract Drawable getDefaultIcon(int userId);
-
- protected Drawable createDrawableFromBitmap(Bitmap icon, int userId,
- ActivityManager.TaskDescription desc) {
- return createBadgedDrawable(
- new BitmapDrawable(mContext.getResources(), icon), userId, desc);
- }
-
- protected abstract Drawable createBadgedDrawable(Drawable icon, int userId,
- ActivityManager.TaskDescription desc);
-
- /**
- * @return the activity icon for the ActivityInfo for a user, badging if necessary.
- */
- protected abstract Drawable getBadgedActivityIcon(ActivityInfo info, int userId,
- ActivityManager.TaskDescription desc);
-
- public static class DefaultIconLoader extends IconLoader {
-
- private final BitmapDrawable mDefaultIcon;
- private final IconDrawableFactory mDrawableFactory;
-
- public DefaultIconLoader(Context context, TaskKeyLruCache<Drawable> iconCache,
- LruCache<ComponentName, ActivityInfo> activityInfoCache) {
- super(context, iconCache, activityInfoCache);
-
- // Create the default assets
- Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
- icon.eraseColor(0);
- mDefaultIcon = new BitmapDrawable(context.getResources(), icon);
- mDrawableFactory = IconDrawableFactory.newInstance(context);
- }
-
- @Override
- public Drawable getDefaultIcon(int userId) {
- return mDefaultIcon;
- }
-
- @Override
- protected Drawable createBadgedDrawable(Drawable icon, int userId,
- ActivityManager.TaskDescription desc) {
- if (userId != UserHandle.myUserId()) {
- icon = mContext.getPackageManager().getUserBadgedIcon(icon, new UserHandle(userId));
- }
- return icon;
- }
-
- @Override
- protected Drawable getBadgedActivityIcon(ActivityInfo info, int userId,
- ActivityManager.TaskDescription desc) {
- return mDrawableFactory.getBadgedIcon(info, info.applicationInfo, userId);
- }
- }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java
deleted file mode 100644
index 8a244bf81c7c..000000000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.shared.recents.model;
-
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.systemui.shared.recents.model.Task.TaskKey;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Base class for both strong and LRU task key cache.
- */
-public abstract class TaskKeyCache<V> {
-
- protected static final String TAG = "TaskKeyCache";
-
- protected final SparseArray<TaskKey> mKeys = new SparseArray<>();
-
- /**
- * Gets a specific entry in the cache with the specified key, regardless of whether the cached
- * value is valid or not.
- */
- public final synchronized V get(TaskKey key) {
- return getCacheEntry(key.id);
- }
-
- /**
- * Returns the value only if the key is valid (has not been updated since the last time it was
- * in the cache)
- */
- public final synchronized V getAndInvalidateIfModified(TaskKey key) {
- TaskKey lastKey = mKeys.get(key.id);
- if (lastKey != null) {
- if ((lastKey.windowingMode != key.windowingMode) ||
- (lastKey.lastActiveTime != key.lastActiveTime)) {
- // The task has updated (been made active since the last time it was put into the
- // LRU cache) or the stack id for the task has changed, invalidate that cache item
- remove(key);
- return null;
- }
- }
- // Either the task does not exist in the cache, or the last active time is the same as
- // the key specified, so return what is in the cache
- return getCacheEntry(key.id);
- }
-
- /** Puts an entry in the cache for a specific key. */
- public final synchronized void put(TaskKey key, V value) {
- if (key == null || value == null) {
- Log.e(TAG, "Unexpected null key or value: " + key + ", " + value);
- return;
- }
- mKeys.put(key.id, key);
- putCacheEntry(key.id, value);
- }
-
-
- /** Removes a cache entry for a specific key. */
- public final synchronized void remove(TaskKey key) {
- // Remove the key after the cache value because we need it to make the callback
- removeCacheEntry(key.id);
- mKeys.remove(key.id);
- }
-
- /** @return {@link Collection} of {@link TaskKey} */
- public Collection<TaskKey> getValues() {
- Collection<TaskKey> result = new ArrayList<>(mKeys.size());
- for (int i = 0; i < mKeys.size(); i++) {
- result.add(mKeys.valueAt(i));
- }
- return result;
- }
-
- /** Removes all the entries in the cache. */
- public final synchronized void evictAll() {
- evictAllCache();
- mKeys.clear();
- }
-
- protected abstract V getCacheEntry(int id);
- protected abstract void putCacheEntry(int id, V value);
- protected abstract void removeCacheEntry(int id);
- protected abstract void evictAllCache();
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyLruCache.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyLruCache.java
deleted file mode 100644
index bc57b08236cf..000000000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyLruCache.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.systemui.shared.recents.model;
-
-import android.util.LruCache;
-
-import com.android.systemui.shared.recents.model.Task.TaskKey;
-
-import java.io.PrintWriter;
-
-/**
- * A mapping of {@link TaskKey} to value, with additional LRU functionality where the least
- * recently referenced key/values will be evicted as more values than the given cache size are
- * inserted.
- *
- * In addition, this also allows the caller to invalidate cached values for keys that have since
- * changed.
- */
-public class TaskKeyLruCache<V> extends TaskKeyCache<V> {
-
- public interface EvictionCallback {
- void onEntryEvicted(TaskKey key);
- }
-
- private final LruCache<Integer, V> mCache;
- private final EvictionCallback mEvictionCallback;
-
- public TaskKeyLruCache(int cacheSize) {
- this(cacheSize, null);
- }
-
- public TaskKeyLruCache(int cacheSize, EvictionCallback evictionCallback) {
- mEvictionCallback = evictionCallback;
- mCache = new LruCache<Integer, V>(cacheSize) {
-
- @Override
- protected void entryRemoved(boolean evicted, Integer taskId, V oldV, V newV) {
- if (mEvictionCallback != null && evicted) {
- mEvictionCallback.onEntryEvicted(mKeys.get(taskId));
- }
-
- // Only remove from mKeys on cache remove, not a cache update.
- if (newV == null) {
- mKeys.remove(taskId);
- }
- }
- };
- }
-
- /** Trims the cache to a specific size */
- public final void trimToSize(int cacheSize) {
- mCache.trimToSize(cacheSize);
- }
-
- public void dump(String prefix, PrintWriter writer) {
- String innerPrefix = prefix + " ";
-
- writer.print(prefix); writer.print(TAG);
- writer.print(" numEntries="); writer.print(mKeys.size());
- writer.println();
- int keyCount = mKeys.size();
- for (int i = 0; i < keyCount; i++) {
- writer.print(innerPrefix); writer.println(mKeys.get(mKeys.keyAt(i)));
- }
- }
-
- @Override
- protected V getCacheEntry(int id) {
- return mCache.get(id);
- }
-
- @Override
- protected void putCacheEntry(int id, V value) {
- mCache.put(id, value);
- }
-
- @Override
- protected void removeCacheEntry(int id) {
- mCache.remove(id);
- }
-
- @Override
- protected void evictAllCache() {
- mCache.evictAll();
- }
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
index ed1cd8191092..d5a08dda9853 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
@@ -409,15 +409,6 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback {
mAudioManager.dispatchMediaKeyEvent(keyEvent);
}
- @Override
- public void dispatchSystemUiVisibilityChanged(int visibility) {
- super.dispatchSystemUiVisibilityChanged(visibility);
-
- if (!(mContext instanceof Activity)) {
- setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
- }
- }
-
/**
* In general, we enable unlocking the insecure keyguard with the menu key. However, there are
* some cases where we wish to disable it, notably when the menu button placement or technology
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index ae787260adca..29c67ae1b4a6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -15,7 +15,12 @@
*/
package com.android.keyguard;
+import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
+import static android.view.ViewRootImpl.sNewInsetsMode;
+import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowInsets.Type.systemBars;
import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static java.lang.Integer.max;
import android.app.Activity;
import android.app.AlertDialog;
@@ -38,6 +43,7 @@ import android.view.SurfaceControl;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.WindowInsets;
import android.view.WindowManager;
import android.widget.FrameLayout;
@@ -339,13 +345,22 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
}
@Override
- protected boolean fitSystemWindows(Rect insets) {
+ public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+
// Consume bottom insets because we're setting the padding locally (for IME and navbar.)
- setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), insets.bottom);
- insets.bottom = 0;
- return false;
+ int inset;
+ if (sNewInsetsMode == NEW_INSETS_MODE_FULL) {
+ int bottomInset = insets.getInsetsIgnoringVisibility(systemBars()).bottom;
+ int imeInset = insets.getInsets(ime()).bottom;
+ inset = max(bottomInset, imeInset);
+ } else {
+ inset = insets.getSystemWindowInsetBottom();
+ }
+ setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), inset);
+ return insets.inset(0, 0, 0, inset);
}
+
private void showDialog(String title, String message) {
if (mAlertDialog != null) {
mAlertDialog.dismiss();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 58a6c17e8239..4e2f7d4ee862 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -371,7 +371,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
checkIsHandlerThread();
if (DEBUG_SIM_STATES) {
Log.v(TAG, "onSubscriptionInfoChanged()");
- List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
+ List<SubscriptionInfo> sil = mSubscriptionManager
+ .getActiveAndHiddenSubscriptionInfoList();
if (sil != null) {
for (SubscriptionInfo subInfo : sil) {
Log.v(TAG, "SubInfo:" + subInfo);
@@ -425,10 +426,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
List<SubscriptionInfo> sil = mSubscriptionInfo;
if (sil == null || forceReload) {
- sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
+ sil = mSubscriptionManager.getActiveAndHiddenSubscriptionInfoList();
}
if (sil == null) {
- // getActiveSubscriptionInfoList was null callers expect an empty list.
+ // getActiveAndHiddenSubscriptionInfoList was null callers expect an empty list.
mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
} else {
mSubscriptionInfo = sil;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index c243309d960a..581cf7a2fbef 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -86,6 +86,8 @@ public class WindowMagnificationController implements View.OnClickListener,
private SurfaceView mMirrorSurfaceView;
private View mControlsView;
private View mOverlayView;
+ // The boundary of magnification frame.
+ private final Rect mMagnificationFrameBoundary = new Rect();
private MoveMirrorRunnable mMoveMirrorRunnable = new MoveMirrorRunnable();
@@ -93,7 +95,7 @@ public class WindowMagnificationController implements View.OnClickListener,
mContext = context;
mHandler = handler;
Display display = mContext.getDisplay();
- display.getSize(mDisplaySize);
+ display.getRealSize(mDisplaySize);
mDisplayId = mContext.getDisplayId();
mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
@@ -114,6 +116,7 @@ public class WindowMagnificationController implements View.OnClickListener,
return;
}
setInitialStartBounds();
+ setMagnificationFrameBoundary();
createOverlayWindow();
}
@@ -330,7 +333,7 @@ public class WindowMagnificationController implements View.OnClickListener,
@Override
public void onClick(View v) {
setMoveOffset(v, mMoveFrameAmountShort);
- moveMirrorFromControls();
+ moveMirrorWindow(mMoveWindowOffset.x, mMoveWindowOffset.y);
}
@Override
@@ -370,10 +373,8 @@ public class WindowMagnificationController implements View.OnClickListener,
case MotionEvent.ACTION_MOVE:
int xDiff = (int) (event.getRawX() - mLastDrag.x);
int yDiff = (int) (event.getRawY() - mLastDrag.y);
- mMagnificationFrame.offset(xDiff, yDiff);
+ moveMirrorWindow(xDiff, yDiff);
mLastDrag.set(event.getRawX(), event.getRawY());
- modifyWindowMagnification(mTransaction);
- mTransaction.apply();
return true;
}
return false;
@@ -393,11 +394,11 @@ public class WindowMagnificationController implements View.OnClickListener,
}
}
- private void moveMirrorFromControls() {
- mMagnificationFrame.offset(mMoveWindowOffset.x, mMoveWindowOffset.y);
-
- modifyWindowMagnification(mTransaction);
- mTransaction.apply();
+ private void moveMirrorWindow(int xOffset, int yOffset) {
+ if (updateMagnificationFramePosition(xOffset, yOffset)) {
+ modifyWindowMagnification(mTransaction);
+ mTransaction.apply();
+ }
}
/**
@@ -414,6 +415,52 @@ public class WindowMagnificationController implements View.OnClickListener,
return new Rect(left, top, right, bottom);
}
+ private void setMagnificationFrameBoundary() {
+ // Calculates width and height for magnification frame could exceed out the screen.
+ // TODO : re-calculating again when scale is changed.
+ // The half width of magnification frame.
+ final int halfWidth = mMagnificationFrame.width() / 2;
+ // The half height of magnification frame.
+ final int halfHeight = mMagnificationFrame.height() / 2;
+ // The scaled half width of magnified region.
+ final int scaledWidth = (int) (halfWidth / mScale);
+ // The scaled half height of magnified region.
+ final int scaledHeight = (int) (halfHeight / mScale);
+ final int exceededWidth = halfWidth - scaledWidth;
+ final int exceededHeight = halfHeight - scaledHeight;
+
+ mMagnificationFrameBoundary.set(-exceededWidth, -exceededHeight,
+ mDisplaySize.x + exceededWidth, mDisplaySize.y + exceededHeight);
+ }
+
+ /**
+ * Calculates and sets the real position of magnification frame based on the magnified region
+ * should be limited by the region of the display.
+ */
+ private boolean updateMagnificationFramePosition(int xOffset, int yOffset) {
+ mTmpRect.set(mMagnificationFrame);
+ mTmpRect.offset(xOffset, yOffset);
+
+ if (mTmpRect.left < mMagnificationFrameBoundary.left) {
+ mTmpRect.offsetTo(mMagnificationFrameBoundary.left, mTmpRect.top);
+ } else if (mTmpRect.right > mMagnificationFrameBoundary.right) {
+ final int leftOffset = mMagnificationFrameBoundary.right - mMagnificationFrame.width();
+ mTmpRect.offsetTo(leftOffset, mTmpRect.top);
+ }
+
+ if (mTmpRect.top < mMagnificationFrameBoundary.top) {
+ mTmpRect.offsetTo(mTmpRect.left, mMagnificationFrameBoundary.top);
+ } else if (mTmpRect.bottom > mMagnificationFrameBoundary.bottom) {
+ final int topOffset = mMagnificationFrameBoundary.bottom - mMagnificationFrame.height();
+ mTmpRect.offsetTo(mTmpRect.left, topOffset);
+ }
+
+ if (!mTmpRect.equals(mMagnificationFrame)) {
+ mMagnificationFrame.set(mTmpRect);
+ return true;
+ }
+ return false;
+ }
@Override
public void surfaceCreated(SurfaceHolder holder) {
createMirror();
@@ -431,7 +478,7 @@ public class WindowMagnificationController implements View.OnClickListener,
@Override
public void run() {
if (mIsPressedDown) {
- moveMirrorFromControls();
+ moveMirrorWindow(mMoveWindowOffset.x, mMoveWindowOffset.y);
mHandler.postDelayed(mMoveMirrorRunnable, 100);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 926fb6e75594..40a93d69fef4 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -29,6 +29,8 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.Space
import android.widget.TextView
import com.android.systemui.controls.controller.ControlsController
@@ -144,10 +146,17 @@ class ControlsUiControllerImpl @Inject constructor (
inflater.inflate(R.layout.controls_no_favorites, parent, true)
val textView = parent.requireViewById(R.id.controls_title) as TextView
- textView.setOnClickListener {
+ textView.setOnClickListener(launchSelectorActivityListener(context))
+ }
+
+ private fun launchSelectorActivityListener(context: Context): (View) -> Unit {
+ return { _ ->
+ val closeDialog = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
+ context.sendBroadcast(closeDialog)
+
val i = Intent()
i.setComponent(ComponentName(context, ControlsProviderSelectorActivity::class.java))
- i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(i)
}
}
@@ -171,13 +180,12 @@ class ControlsUiControllerImpl @Inject constructor (
controlViewsById.put(it.controlId, cvh)
}
- val moreImageView = parent.requireViewById(R.id.controls_more) as View
- moreImageView.setOnClickListener {
- val i = Intent()
- i.setComponent(ComponentName(context, ControlsProviderSelectorActivity::class.java))
- i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
- context.startActivity(i)
+ if ((controlInfos.size % 2) == 1) {
+ lastRow.addView(Space(context), LinearLayout.LayoutParams(0, 0, 1f))
}
+
+ val moreImageView = parent.requireViewById(R.id.controls_more) as View
+ moreImageView.setOnClickListener(launchSelectorActivityListener(context))
}
override fun hide() {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java b/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java
deleted file mode 100644
index d2fe39424875..000000000000
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.doze;
-
-import android.annotation.IntDef;
-
-import com.android.systemui.log.RichEvent;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * An event related to dozing. {@link DozeLog} stores and prints these events for debugging
- * and triaging purposes.
- */
-public class DozeEvent extends RichEvent {
- /**
- * Initializes a doze event
- */
- public DozeEvent init(@EventType int type, String reason) {
- super.init(DEBUG, type, reason);
- return this;
- }
-
- /**
- * Event labels for each doze event
- * Index corresponds to the integer associated with each {@link EventType}
- */
- @Override
- public String[] getEventLabels() {
- final String[] events = new String[]{
- "PickupWakeup",
- "PulseStart",
- "PulseFinish",
- "NotificationPulse",
- "Dozing",
- "Fling",
- "EmergencyCall",
- "KeyguardBouncerChanged",
- "ScreenOn",
- "ScreenOff",
- "MissedTick",
- "TimeTickScheduled",
- "KeyguardVisibilityChanged",
- "DozeStateChanged",
- "WakeDisplay",
- "ProximityResult",
- "PulseDropped",
- "PulseDisabledByProx",
- "SensorTriggered"
- };
-
- if (events.length != TOTAL_EVENT_TYPES) {
- throw new IllegalStateException("DozeEvent events.length should match TOTAL_EVENT_TYPES"
- + " events.length=" + events.length
- + " TOTAL_EVENT_LENGTH=" + TOTAL_EVENT_TYPES);
- }
- return events;
- }
-
- /**
- * Converts the reason (integer) to a user-readable string
- */
- public static String reasonToString(@Reason int pulseReason) {
- switch (pulseReason) {
- case PULSE_REASON_INTENT: return "intent";
- case PULSE_REASON_NOTIFICATION: return "notification";
- case PULSE_REASON_SENSOR_SIGMOTION: return "sigmotion";
- case REASON_SENSOR_PICKUP: return "pickup";
- case REASON_SENSOR_DOUBLE_TAP: return "doubletap";
- case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
- case PULSE_REASON_DOCKING: return "docking";
- case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "wakelockscreen";
- case REASON_SENSOR_WAKE_UP: return "wakeup";
- case REASON_SENSOR_TAP: return "tap";
- default: throw new IllegalArgumentException("invalid reason: " + pulseReason);
- }
- }
-
- @IntDef({PICKUP_WAKEUP, PULSE_START, PULSE_FINISH, NOTIFICATION_PULSE, DOZING, FLING,
- EMERGENCY_CALL, KEYGUARD_BOUNCER_CHANGED, SCREEN_ON, SCREEN_OFF, MISSED_TICK,
- TIME_TICK_SCHEDULED, KEYGUARD_VISIBILITY_CHANGE, DOZE_STATE_CHANGED, WAKE_DISPLAY,
- PROXIMITY_RESULT, PULSE_DROPPED, PULSE_DISABLED_BY_PROX, SENSOR_TRIGGERED})
- /**
- * Types of DozeEvents
- */
- @Retention(RetentionPolicy.SOURCE)
- public @interface EventType {}
- public static final int PICKUP_WAKEUP = 0;
- public static final int PULSE_START = 1;
- public static final int PULSE_FINISH = 2;
- public static final int NOTIFICATION_PULSE = 3;
- public static final int DOZING = 4;
- public static final int FLING = 5;
- public static final int EMERGENCY_CALL = 6;
- public static final int KEYGUARD_BOUNCER_CHANGED = 7;
- public static final int SCREEN_ON = 8;
- public static final int SCREEN_OFF = 9;
- public static final int MISSED_TICK = 10;
- public static final int TIME_TICK_SCHEDULED = 11;
- public static final int KEYGUARD_VISIBILITY_CHANGE = 12;
- public static final int DOZE_STATE_CHANGED = 13;
- public static final int WAKE_DISPLAY = 14;
- public static final int PROXIMITY_RESULT = 15;
- public static final int PULSE_DROPPED = 16;
- public static final int PULSE_DISABLED_BY_PROX = 17;
- public static final int SENSOR_TRIGGERED = 18;
- public static final int TOTAL_EVENT_TYPES = 19;
-
- public static final int TOTAL_REASONS = 10;
- @IntDef({PULSE_REASON_NONE, PULSE_REASON_INTENT, PULSE_REASON_NOTIFICATION,
- PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP,
- PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP,
- PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, REASON_SENSOR_TAP})
- @Retention(RetentionPolicy.SOURCE)
- public @interface Reason {}
- public static final int PULSE_REASON_NONE = -1;
- public static final int PULSE_REASON_INTENT = 0;
- public static final int PULSE_REASON_NOTIFICATION = 1;
- public static final int PULSE_REASON_SENSOR_SIGMOTION = 2;
- public static final int REASON_SENSOR_PICKUP = 3;
- public static final int REASON_SENSOR_DOUBLE_TAP = 4;
- public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
- public static final int PULSE_REASON_DOCKING = 6;
- public static final int REASON_SENSOR_WAKE_UP = 7;
- public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8;
- public static final int REASON_SENSOR_TAP = 9;
-}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index fe504216b166..8afdf1aeb023 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -16,15 +16,20 @@
package com.android.systemui.doze;
+import android.annotation.IntDef;
import android.util.TimeUtils;
+import androidx.annotation.NonNull;
+
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.DumpController;
-import com.android.systemui.log.SysuiLog;
+import com.android.systemui.Dumpable;
+import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.Date;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -32,13 +37,11 @@ import javax.inject.Singleton;
/**
* Logs doze events for debugging and triaging purposes. Logs are dumped in bugreports or on demand:
* adb shell dumpsys activity service com.android.systemui/.SystemUIService \
- * dependency DumpController DozeLog
+ * dependency DumpController DozeLog,DozeStats
*/
@Singleton
-public class DozeLog extends SysuiLog<DozeEvent> {
- private static final String TAG = "DozeLog";
-
- private DozeEvent mRecycledEvent;
+public class DozeLog implements Dumpable {
+ private final DozeLogger mLogger;
private boolean mPulsing;
private long mSince;
@@ -51,8 +54,11 @@ public class DozeLog extends SysuiLog<DozeEvent> {
private SummaryStats[][] mProxStats; // [reason][near/far]
@Inject
- public DozeLog(KeyguardUpdateMonitor keyguardUpdateMonitor, DumpController dumpController) {
- super(dumpController, TAG, MAX_DOZE_DEBUG_LOGS, MAX_DOZE_LOGS);
+ public DozeLog(
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ DumpController dumpController,
+ DozeLogger logger) {
+ mLogger = logger;
mSince = System.currentTimeMillis();
mPickupPulseNearVibrationStats = new SummaryStats();
mPickupPulseNotNearVibrationStats = new SummaryStats();
@@ -60,8 +66,8 @@ public class DozeLog extends SysuiLog<DozeEvent> {
mScreenOnPulsingStats = new SummaryStats();
mScreenOnNotPulsingStats = new SummaryStats();
mEmergencyCallStats = new SummaryStats();
- mProxStats = new SummaryStats[DozeEvent.TOTAL_REASONS][2];
- for (int i = 0; i < DozeEvent.TOTAL_REASONS; i++) {
+ mProxStats = new SummaryStats[TOTAL_REASONS][2];
+ for (int i = 0; i < TOTAL_REASONS; i++) {
mProxStats[i][0] = new SummaryStats();
mProxStats[i][1] = new SummaryStats();
}
@@ -69,42 +75,42 @@ public class DozeLog extends SysuiLog<DozeEvent> {
if (keyguardUpdateMonitor != null) {
keyguardUpdateMonitor.registerCallback(mKeyguardCallback);
}
+
+ dumpController.registerDumpable("DumpStats", this);
}
/**
* Appends pickup wakeup event to the logs
*/
public void tracePickupWakeUp(boolean withinVibrationThreshold) {
- log(DozeEvent.PICKUP_WAKEUP, "withinVibrationThreshold=" + withinVibrationThreshold);
- if (mEnabled) {
- (withinVibrationThreshold ? mPickupPulseNearVibrationStats
- : mPickupPulseNotNearVibrationStats).append();
- }
+ mLogger.logPickupWakeup(withinVibrationThreshold);
+ (withinVibrationThreshold ? mPickupPulseNearVibrationStats
+ : mPickupPulseNotNearVibrationStats).append();
}
/**
* Appends pulse started event to the logs.
* @param reason why the pulse started
*/
- public void tracePulseStart(@DozeEvent.Reason int reason) {
- log(DozeEvent.PULSE_START, DozeEvent.reasonToString(reason));
- if (mEnabled) mPulsing = true;
+ public void tracePulseStart(@Reason int reason) {
+ mLogger.logPulseStart(reason);
+ mPulsing = true;
}
/**
* Appends pulse finished event to the logs
*/
public void tracePulseFinish() {
- log(DozeEvent.PULSE_FINISH);
- if (mEnabled) mPulsing = false;
+ mLogger.logPulseFinish();
+ mPulsing = false;
}
/**
* Appends pulse event to the logs
*/
public void traceNotificationPulse() {
- log(DozeEvent.NOTIFICATION_PULSE);
- if (mEnabled) mNotificationPulseStats.append();
+ mLogger.logNotificationPulse();
+ mNotificationPulseStats.append();
}
/**
@@ -112,8 +118,8 @@ public class DozeLog extends SysuiLog<DozeEvent> {
* @param dozing true if dozing, else false
*/
public void traceDozing(boolean dozing) {
- log(DozeEvent.DOZING, "dozing=" + dozing);
- if (mEnabled) mPulsing = false;
+ mLogger.logDozing(dozing);
+ mPulsing = false;
}
/**
@@ -121,18 +127,15 @@ public class DozeLog extends SysuiLog<DozeEvent> {
*/
public void traceFling(boolean expand, boolean aboveThreshold, boolean thresholdNeeded,
boolean screenOnFromTouch) {
- log(DozeEvent.FLING, "expand=" + expand
- + " aboveThreshold=" + aboveThreshold
- + " thresholdNeeded=" + thresholdNeeded
- + " screenOnFromTouch=" + screenOnFromTouch);
+ mLogger.logFling(expand, aboveThreshold, thresholdNeeded, screenOnFromTouch);
}
/**
* Appends emergency call event to the logs
*/
public void traceEmergencyCall() {
- log(DozeEvent.EMERGENCY_CALL);
- if (mEnabled) mEmergencyCallStats.append();
+ mLogger.logEmergencyCall();
+ mEmergencyCallStats.append();
}
/**
@@ -140,18 +143,16 @@ public class DozeLog extends SysuiLog<DozeEvent> {
* @param showing true if the keyguard bouncer is showing, else false
*/
public void traceKeyguardBouncerChanged(boolean showing) {
- log(DozeEvent.KEYGUARD_BOUNCER_CHANGED, "showing=" + showing);
+ mLogger.logKeyguardBouncerChanged(showing);
}
/**
* Appends screen-on event to the logs
*/
public void traceScreenOn() {
- log(DozeEvent.SCREEN_ON, "pulsing=" + mPulsing);
- if (mEnabled) {
- (mPulsing ? mScreenOnPulsingStats : mScreenOnNotPulsingStats).append();
- mPulsing = false;
- }
+ mLogger.logScreenOn(mPulsing);
+ (mPulsing ? mScreenOnPulsingStats : mScreenOnNotPulsingStats).append();
+ mPulsing = false;
}
/**
@@ -159,7 +160,7 @@ public class DozeLog extends SysuiLog<DozeEvent> {
* @param why reason the screen is off
*/
public void traceScreenOff(int why) {
- log(DozeEvent.SCREEN_OFF, "why=" + why);
+ mLogger.logScreenOff(why);
}
/**
@@ -167,7 +168,7 @@ public class DozeLog extends SysuiLog<DozeEvent> {
* @param delay of the missed tick
*/
public void traceMissedTick(String delay) {
- log(DozeEvent.MISSED_TICK, "delay=" + delay);
+ mLogger.logMissedTick(delay);
}
/**
@@ -176,9 +177,7 @@ public class DozeLog extends SysuiLog<DozeEvent> {
* @param triggerAt time tick trigger at
*/
public void traceTimeTickScheduled(long when, long triggerAt) {
- log(DozeEvent.TIME_TICK_SCHEDULED,
- "scheduledAt=" + DATE_FORMAT.format(new Date(when))
- + " triggerAt=" + DATE_FORMAT.format(new Date(triggerAt)));
+ mLogger.logTimeTickScheduled(when, triggerAt);
}
/**
@@ -186,8 +185,8 @@ public class DozeLog extends SysuiLog<DozeEvent> {
* @param showing whether the keyguard is now showing
*/
public void traceKeyguard(boolean showing) {
- log(DozeEvent.KEYGUARD_VISIBILITY_CHANGE, "showing=" + showing);
- if (mEnabled && !showing) mPulsing = false;
+ mLogger.logKeyguardVisibilityChange(showing);
+ if (!showing) mPulsing = false;
}
/**
@@ -195,7 +194,7 @@ public class DozeLog extends SysuiLog<DozeEvent> {
* @param state new DozeMachine state
*/
public void traceState(DozeMachine.State state) {
- log(DozeEvent.DOZE_STATE_CHANGED, state.name());
+ mLogger.logDozeStateChanged(state);
}
/**
@@ -203,31 +202,22 @@ public class DozeLog extends SysuiLog<DozeEvent> {
* @param wake if we're waking up or sleeping.
*/
public void traceWakeDisplay(boolean wake) {
- log(DozeEvent.WAKE_DISPLAY, "wake=" + wake);
+ mLogger.logWakeDisplay(wake);
}
/**
* Appends proximity result event to the logs
* @param near true if near, else false
- * @param millis
* @param reason why proximity result was triggered
*/
- public void traceProximityResult(boolean near, long millis, @DozeEvent.Reason int reason) {
- log(DozeEvent.PROXIMITY_RESULT,
- " reason=" + DozeEvent.reasonToString(reason)
- + " near=" + near
- + " millis=" + millis);
- if (mEnabled) mProxStats[reason][near ? 0 : 1].append();
+ public void traceProximityResult(boolean near, long millis, @Reason int reason) {
+ mLogger.logProximityResult(near, millis, reason);
+ mProxStats[reason][near ? 0 : 1].append();
}
- /**
- * Prints doze log timeline and consolidated stats
- * @param pw
- */
- public void dump(PrintWriter pw) {
+ @Override
+ public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
synchronized (DozeLog.class) {
- super.dump(null, pw, null); // prints timeline
-
pw.print(" Doze summary stats (for ");
TimeUtils.formatDuration(System.currentTimeMillis() - mSince, pw);
pw.println("):");
@@ -237,32 +227,19 @@ public class DozeLog extends SysuiLog<DozeEvent> {
mScreenOnPulsingStats.dump(pw, "Screen on (pulsing)");
mScreenOnNotPulsingStats.dump(pw, "Screen on (not pulsing)");
mEmergencyCallStats.dump(pw, "Emergency call");
- for (int i = 0; i < DozeEvent.TOTAL_REASONS; i++) {
- final String reason = DozeEvent.reasonToString(i);
+ for (int i = 0; i < TOTAL_REASONS; i++) {
+ final String reason = reasonToString(i);
mProxStats[i][0].dump(pw, "Proximity near (" + reason + ")");
mProxStats[i][1].dump(pw, "Proximity far (" + reason + ")");
}
}
}
- private void log(@DozeEvent.EventType int eventType) {
- log(eventType, "");
- }
-
- private void log(@DozeEvent.EventType int eventType, String msg) {
- if (mRecycledEvent != null) {
- mRecycledEvent = log(mRecycledEvent.init(eventType, msg));
- } else {
- mRecycledEvent = log(new DozeEvent().init(eventType, msg));
- }
- }
-
/**
* Appends pulse dropped event to logs
*/
public void tracePulseDropped(boolean pulsePending, DozeMachine.State state, boolean blocked) {
- log(DozeEvent.PULSE_DROPPED, "pulsePending=" + pulsePending + " state="
- + state.name() + " blocked=" + blocked);
+ mLogger.logPulseDropped(pulsePending, state, blocked);
}
/**
@@ -270,7 +247,7 @@ public class DozeLog extends SysuiLog<DozeEvent> {
* @param reason why the pulse was dropped
*/
public void tracePulseDropped(String reason) {
- log(DozeEvent.PULSE_DROPPED, "why=" + reason);
+ mLogger.logPulseDropped(reason);
}
/**
@@ -278,15 +255,15 @@ public class DozeLog extends SysuiLog<DozeEvent> {
* @param disabled
*/
public void tracePulseTouchDisabledByProx(boolean disabled) {
- log(DozeEvent.PULSE_DISABLED_BY_PROX, "disabled=" + disabled);
+ mLogger.logPulseTouchDisabledByProx(disabled);
}
/**
* Appends sensor triggered event to logs
* @param reason why the sensor was triggered
*/
- public void traceSensor(@DozeEvent.Reason int reason) {
- log(DozeEvent.SENSOR_TRIGGERED, "type=" + DozeEvent.reasonToString(reason));
+ public void traceSensor(@Reason int reason) {
+ mLogger.logSensorTriggered(reason);
}
private class SummaryStats {
@@ -339,6 +316,42 @@ public class DozeLog extends SysuiLog<DozeEvent> {
}
};
- private static final int MAX_DOZE_DEBUG_LOGS = 400;
- private static final int MAX_DOZE_LOGS = 50;
+ /**
+ * Converts the reason (integer) to a user-readable string
+ */
+ public static String reasonToString(@Reason int pulseReason) {
+ switch (pulseReason) {
+ case PULSE_REASON_INTENT: return "intent";
+ case PULSE_REASON_NOTIFICATION: return "notification";
+ case PULSE_REASON_SENSOR_SIGMOTION: return "sigmotion";
+ case REASON_SENSOR_PICKUP: return "pickup";
+ case REASON_SENSOR_DOUBLE_TAP: return "doubletap";
+ case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
+ case PULSE_REASON_DOCKING: return "docking";
+ case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "wakelockscreen";
+ case REASON_SENSOR_WAKE_UP: return "wakeup";
+ case REASON_SENSOR_TAP: return "tap";
+ default: throw new IllegalArgumentException("invalid reason: " + pulseReason);
+ }
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({PULSE_REASON_NONE, PULSE_REASON_INTENT, PULSE_REASON_NOTIFICATION,
+ PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP,
+ PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP,
+ PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, REASON_SENSOR_TAP})
+ public @interface Reason {}
+ public static final int PULSE_REASON_NONE = -1;
+ public static final int PULSE_REASON_INTENT = 0;
+ public static final int PULSE_REASON_NOTIFICATION = 1;
+ public static final int PULSE_REASON_SENSOR_SIGMOTION = 2;
+ public static final int REASON_SENSOR_PICKUP = 3;
+ public static final int REASON_SENSOR_DOUBLE_TAP = 4;
+ public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
+ public static final int PULSE_REASON_DOCKING = 6;
+ public static final int REASON_SENSOR_WAKE_UP = 7;
+ public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8;
+ public static final int REASON_SENSOR_TAP = 9;
+
+ public static final int TOTAL_REASONS = 10;
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
new file mode 100644
index 000000000000..42decd592071
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.doze
+
+import com.android.systemui.doze.DozeLog.Reason
+import com.android.systemui.doze.DozeLog.reasonToString
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel.DEBUG
+import com.android.systemui.log.LogLevel.ERROR
+import com.android.systemui.log.LogLevel.INFO
+import com.android.systemui.log.dagger.DozeLog
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import javax.inject.Inject
+
+/** Interface for logging messages to the [DozeLog]. */
+class DozeLogger @Inject constructor(
+ @DozeLog private val buffer: LogBuffer
+) {
+ fun logPickupWakeup(isWithinVibrationThreshold: Boolean) {
+ buffer.log(TAG, DEBUG, {
+ bool1 = isWithinVibrationThreshold
+ }, {
+ "PickupWakeup withinVibrationThreshold=$bool1"
+ })
+ }
+
+ fun logPulseStart(@Reason reason: Int) {
+ buffer.log(TAG, INFO, {
+ int1 = reason
+ }, {
+ "Pulse start, reason=${reasonToString(int1)}"
+ })
+ }
+
+ fun logPulseFinish() {
+ buffer.log(TAG, INFO, {}, { "Pulse finish" })
+ }
+
+ fun logNotificationPulse() {
+ buffer.log(TAG, INFO, {}, { "Notification pulse" })
+ }
+
+ fun logDozing(isDozing: Boolean) {
+ buffer.log(TAG, INFO, {
+ bool1 = isDozing
+ }, {
+ "Dozing=$bool1"
+ })
+ }
+
+ fun logFling(
+ expand: Boolean,
+ aboveThreshold: Boolean,
+ thresholdNeeded: Boolean,
+ screenOnFromTouch: Boolean
+ ) {
+ buffer.log(TAG, DEBUG, {
+ bool1 = expand
+ bool2 = aboveThreshold
+ bool3 = thresholdNeeded
+ bool4 = screenOnFromTouch
+ }, {
+ "Fling expand=$bool1 aboveThreshold=$bool2 thresholdNeeded=$bool3 " +
+ "screenOnFromTouch=$bool4"
+ })
+ }
+
+ fun logEmergencyCall() {
+ buffer.log(TAG, INFO, {}, { "Emergency call" })
+ }
+
+ fun logKeyguardBouncerChanged(isShowing: Boolean) {
+ buffer.log(TAG, INFO, {
+ bool1 = isShowing
+ }, {
+ "Keyguard bouncer changed, showing=$bool1"
+ })
+ }
+
+ fun logScreenOn(isPulsing: Boolean) {
+ buffer.log(TAG, INFO, {
+ bool1 = isPulsing
+ }, {
+ "Screen on, pulsing=$bool1"
+ })
+ }
+
+ fun logScreenOff(why: Int) {
+ buffer.log(TAG, INFO, {
+ int1 = why
+ }, {
+ "Screen off, why=$int1"
+ })
+ }
+
+ fun logMissedTick(delay: String) {
+ buffer.log(TAG, ERROR, {
+ str1 = delay
+ }, {
+ "Missed AOD time tick by $str1"
+ })
+ }
+
+ fun logTimeTickScheduled(whenAt: Long, triggerAt: Long) {
+ buffer.log(TAG, DEBUG, {
+ long1 = whenAt
+ long2 = triggerAt
+ }, {
+ "Time tick scheduledAt=${DATE_FORMAT.format(Date(long1))} " +
+ "triggerAt=${DATE_FORMAT.format(Date(long2))}"
+ })
+ }
+
+ fun logKeyguardVisibilityChange(isShowing: Boolean) {
+ buffer.log(TAG, INFO, {
+ bool1 = isShowing
+ }, {
+ "Keyguard visibility change, isShowing=$bool1"
+ })
+ }
+
+ fun logDozeStateChanged(state: DozeMachine.State) {
+ buffer.log(TAG, INFO, {
+ str1 = state.name
+ }, {
+ "Doze state changed to $str1"
+ })
+ }
+
+ fun logWakeDisplay(isAwake: Boolean) {
+ buffer.log(TAG, DEBUG, {
+ bool1 = isAwake
+ }, {
+ "Display wakefulness changed, isAwake=$bool1"
+ })
+ }
+
+ fun logProximityResult(isNear: Boolean, millis: Long, @Reason reason: Int) {
+ buffer.log(TAG, DEBUG, {
+ bool1 = isNear
+ long1 = millis
+ int1 = reason
+ }, {
+ "Proximity result reason=${reasonToString(int1)} near=$bool1 millis=$long1"
+ })
+ }
+
+ fun logPulseDropped(pulsePending: Boolean, state: DozeMachine.State, blocked: Boolean) {
+ buffer.log(TAG, INFO, {
+ bool1 = pulsePending
+ str1 = state.name
+ bool2 = blocked
+ }, {
+ "Pulse dropped, pulsePending=$bool1 state=$str1 blocked=$bool2"
+ })
+ }
+
+ fun logPulseDropped(reason: String) {
+ buffer.log(TAG, INFO, {
+ str1 = reason
+ }, {
+ "Pulse dropped, why=$str1"
+ })
+ }
+
+ fun logPulseTouchDisabledByProx(disabled: Boolean) {
+ buffer.log(TAG, DEBUG, {
+ bool1 = disabled
+ }, {
+ "Pulse touch modified by prox, disabled=$bool1"
+ })
+ }
+
+ fun logSensorTriggered(@Reason reason: Int) {
+ buffer.log(TAG, DEBUG, {
+ int1 = reason
+ }, {
+ "Sensor triggered, type=${reasonToString(int1)}"
+ })
+ }
+}
+
+private const val TAG = "DozeLog"
+
+val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.S", Locale.US)
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 40603ab24c1e..03c25eee4f6f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -169,7 +169,7 @@ public class DozeMachine {
@MainThread
public void requestState(State requestedState) {
Preconditions.checkArgument(requestedState != State.DOZE_REQUEST_PULSE);
- requestState(requestedState, DozeEvent.PULSE_REASON_NONE);
+ requestState(requestedState, DozeLog.PULSE_REASON_NONE);
}
@MainThread
@@ -271,7 +271,7 @@ public class DozeMachine {
if (newState == State.DOZE_REQUEST_PULSE) {
mPulseReason = pulseReason;
} else if (oldState == State.DOZE_PULSE_DONE) {
- mPulseReason = DozeEvent.PULSE_REASON_NONE;
+ mPulseReason = DozeLog.PULSE_REASON_NONE;
}
}
@@ -368,7 +368,7 @@ public class DozeMachine {
nextState = State.DOZE;
}
- transitionTo(nextState, DozeEvent.PULSE_REASON_NONE);
+ transitionTo(nextState, DozeLog.PULSE_REASON_NONE);
break;
default:
break;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index d008e665d171..44e5d3de5ca7 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -97,14 +97,14 @@ public class DozeSensors {
mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
null /* setting */,
dozeParameters.getPulseOnSigMotion(),
- DozeEvent.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
+ DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
false /* touchscreen */, dozeLog),
mPickupSensor = new TriggerSensor(
mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
Settings.Secure.DOZE_PICK_UP_GESTURE,
true /* settingDef */,
config.dozePickupSensorAvailable(),
- DozeEvent.REASON_SENSOR_PICKUP, false /* touchCoords */,
+ DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */,
false /* touchscreen */,
false /* ignoresSetting */,
dozeLog),
@@ -112,7 +112,7 @@ public class DozeSensors {
findSensorWithType(config.doubleTapSensorType()),
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
true /* configured */,
- DozeEvent.REASON_SENSOR_DOUBLE_TAP,
+ DozeLog.REASON_SENSOR_DOUBLE_TAP,
dozeParameters.doubleTapReportsTouchCoordinates(),
true /* touchscreen */,
dozeLog),
@@ -120,7 +120,7 @@ public class DozeSensors {
findSensorWithType(config.tapSensorType()),
Settings.Secure.DOZE_TAP_SCREEN_GESTURE,
true /* configured */,
- DozeEvent.REASON_SENSOR_TAP,
+ DozeLog.REASON_SENSOR_TAP,
false /* reports touch coordinates */,
true /* touchscreen */,
dozeLog),
@@ -129,7 +129,7 @@ public class DozeSensors {
Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
false /* settingDef */,
true /* configured */,
- DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS,
+ DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
true /* reports touch coordinates */,
true /* touchscreen */,
dozeLog),
@@ -137,7 +137,7 @@ public class DozeSensors {
new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
mConfig.wakeScreenGestureAvailable() && alwaysOn,
- DozeEvent.REASON_SENSOR_WAKE_UP,
+ DozeLog.REASON_SENSOR_WAKE_UP,
false /* reports touch coordinates */,
false /* touchscreen */,
dozeLog),
@@ -145,7 +145,7 @@ public class DozeSensors {
new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN),
Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
mConfig.wakeScreenGestureAvailable(),
- DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
+ DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
false /* reports touch coordinates */,
false /* touchscreen */,
mConfig.getWakeLockScreenDebounce(),
@@ -525,7 +525,7 @@ public class DozeSensors {
/**
* Called when a sensor requests a pulse
- * @param pulseReason Requesting sensor, e.g. {@link DozeEvent#REASON_SENSOR_PICKUP}
+ * @param pulseReason Requesting sensor, e.g. {@link DozeLog#REASON_SENSOR_PICKUP}
* @param screenX the location on the screen where the sensor fired or -1
* if the sensor doesn't support reporting screen locations.
* @param screenY the location on the screen where the sensor fired or -1
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 722dc038f853..b9c056df89a1 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -127,7 +127,7 @@ public class DozeTriggers implements DozeMachine.Part {
mDozeLog.tracePulseDropped("pulseOnNotificationsDisabled");
return;
}
- requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */,
+ requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */,
onPulseSuppressedListener);
mDozeLog.traceNotificationPulse();
}
@@ -163,12 +163,12 @@ public class DozeTriggers implements DozeMachine.Part {
@VisibleForTesting
void onSensor(int pulseReason, float screenX, float screenY, float[] rawValues) {
- boolean isDoubleTap = pulseReason == DozeEvent.REASON_SENSOR_DOUBLE_TAP;
- boolean isTap = pulseReason == DozeEvent.REASON_SENSOR_TAP;
- boolean isPickup = pulseReason == DozeEvent.REASON_SENSOR_PICKUP;
- boolean isLongPress = pulseReason == DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS;
- boolean isWakeDisplay = pulseReason == DozeEvent.REASON_SENSOR_WAKE_UP;
- boolean isWakeLockScreen = pulseReason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
+ boolean isDoubleTap = pulseReason == DozeLog.REASON_SENSOR_DOUBLE_TAP;
+ boolean isTap = pulseReason == DozeLog.REASON_SENSOR_TAP;
+ boolean isPickup = pulseReason == DozeLog.REASON_SENSOR_PICKUP;
+ boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS;
+ boolean isWakeDisplay = pulseReason == DozeLog.REASON_SENSOR_WAKE_UP;
+ boolean isWakeLockScreen = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
boolean wakeEvent = rawValues != null && rawValues.length > 0 && rawValues[0] != 0;
if (isWakeDisplay) {
@@ -281,9 +281,9 @@ public class DozeTriggers implements DozeMachine.Part {
// Logs AOD open due to sensor wake up.
mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
.setType(MetricsEvent.TYPE_OPEN)
- .setSubtype(DozeEvent.REASON_SENSOR_WAKE_UP));
+ .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP));
}
- }, true /* alreadyPerformedProxCheck */, DozeEvent.REASON_SENSOR_WAKE_UP);
+ }, true /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP);
} else {
boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
@@ -292,7 +292,7 @@ public class DozeTriggers implements DozeMachine.Part {
// Logs AOD close due to sensor wake up.
mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
.setType(MetricsEvent.TYPE_CLOSE)
- .setSubtype(DozeEvent.REASON_SENSOR_WAKE_UP));
+ .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP));
}
}
}
@@ -361,7 +361,7 @@ public class DozeTriggers implements DozeMachine.Part {
// When already pulsing we're allowed to show the wallpaper directly without
// requesting a new pulse.
if (mMachine.getState() == DozeMachine.State.DOZE_PULSING
- && reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
+ && reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
mMachine.requestState(DozeMachine.State.DOZE_PULSING_BRIGHT);
return;
}
@@ -426,7 +426,7 @@ public class DozeTriggers implements DozeMachine.Part {
public void onReceive(Context context, Intent intent) {
if (PULSE_ACTION.equals(intent.getAction())) {
if (DozeMachine.DEBUG) Log.d(TAG, "Received pulse intent");
- requestPulse(DozeEvent.PULSE_REASON_INTENT, false, /* performedProxCheck */
+ requestPulse(DozeLog.PULSE_REASON_INTENT, false, /* performedProxCheck */
null /* onPulseSupressedListener */);
}
if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index a6aa90916c25..1c056215f1cb 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -100,7 +100,7 @@ public class DozeUi implements DozeMachine.Part {
public void onPulseStarted() {
try {
mMachine.requestState(
- reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
+ reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
? DozeMachine.State.DOZE_PULSING_BRIGHT
: DozeMachine.State.DOZE_PULSING);
} catch (IllegalStateException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 80d776a59235..f33c931479ba 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -40,6 +40,7 @@ import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.ConnectivityManager;
@@ -100,7 +101,6 @@ import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.statusbar.BlurUtils;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
-import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.EmergencyDialerConstants;
@@ -459,12 +459,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mKeyguardManager.isDeviceLocked())
: null;
- boolean showControls = !mKeyguardManager.isDeviceLocked() && isControlsEnabled(mContext);
-
ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, panelViewController,
mBlurUtils, mSysuiColorExtractor, mStatusBarService,
mNotificationShadeWindowController,
- showControls ? mControlsUiController : null);
+ shouldShowControls() ? mControlsUiController : null);
dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
dialog.setKeyguardShowing(mKeyguardShowing);
@@ -538,7 +536,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
@Override
public boolean shouldBeSeparated() {
- return !isControlsEnabled(mContext);
+ return !shouldShowControls();
}
@Override
@@ -1135,7 +1133,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
* A single press action maintains no state, just responds to a press
* and takes an action.
*/
- private static abstract class SinglePressAction implements Action {
+
+ private abstract class SinglePressAction implements Action {
private final int mIconResId;
private final Drawable mIcon;
private final int mMessageResId;
@@ -1174,7 +1173,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
protected int getActionLayoutId(Context context) {
- if (isControlsEnabled(context)) {
+ if (shouldShowControls()) {
return com.android.systemui.R.layout.global_actions_grid_item_v2;
}
return com.android.systemui.R.layout.global_actions_grid_item;
@@ -1640,8 +1639,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT);
panelContainer.addView(mPanelController.getPanelContent(), panelParams);
- mBackgroundDrawable = mPanelController.getBackgroundDrawable();
- mScrimAlpha = 1f;
}
}
@@ -1669,7 +1666,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
if (mBackgroundDrawable == null) {
mBackgroundDrawable = new ScrimDrawable();
- mScrimAlpha = ScrimController.GRADIENT_SCRIM_ALPHA;
+ mScrimAlpha = 0.8f;
}
getWindow().setBackgroundDrawable(mBackgroundDrawable);
}
@@ -1728,7 +1725,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
if (!(mBackgroundDrawable instanceof ScrimDrawable)) {
return;
}
- ((ScrimDrawable) mBackgroundDrawable).setColor(colors.getMainColor(), animate);
+ ((ScrimDrawable) mBackgroundDrawable).setColor(Color.BLACK, animate);
View decorView = getWindow().getDecorView();
if (colors.supportsDarkText()) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
@@ -1900,8 +1897,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return true;
}
- private static boolean isControlsEnabled(Context context) {
- return Settings.Secure.getInt(
- context.getContentResolver(), "systemui.controls_available", 0) == 1;
+ private boolean shouldShowControls() {
+ return isCurrentUserOwner()
+ && !mKeyguardManager.isDeviceLocked()
+ && Settings.Secure.getInt(mContext.getContentResolver(),
+ "systemui.controls_available", 0) == 1;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogMessage.kt b/packages/SystemUI/src/com/android/systemui/log/LogMessage.kt
index d971ac58fb0b..2a0a2aa6fb38 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogMessage.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogMessage.kt
@@ -43,5 +43,10 @@ interface LogMessage {
var int1: Int
var int2: Int
var long1: Long
+ var long2: Long
var double1: Double
+ var bool1: Boolean
+ var bool2: Boolean
+ var bool3: Boolean
+ var bool4: Boolean
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt b/packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt
index 32334bc382e1..d33ac4b4a80b 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt
@@ -30,7 +30,12 @@ data class LogMessageImpl(
override var int1: Int,
override var int2: Int,
override var long1: Long,
- override var double1: Double
+ override var long2: Long,
+ override var double1: Double,
+ override var bool1: Boolean,
+ override var bool2: Boolean,
+ override var bool3: Boolean,
+ override var bool4: Boolean
) : LogMessage {
fun reset(
@@ -49,7 +54,12 @@ data class LogMessageImpl(
int1 = 0
int2 = 0
long1 = 0
+ long2 = 0
double1 = 0.0
+ bool1 = false
+ bool2 = false
+ bool3 = false
+ bool4 = false
}
companion object Factory {
@@ -65,7 +75,12 @@ data class LogMessageImpl(
0,
0,
0,
- 0.0)
+ 0,
+ 0.0,
+ false,
+ false,
+ false,
+ false)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java b/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java
index 4e15668f6a34..9ee3e6765e4a 100644
--- a/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java
@@ -48,7 +48,7 @@ import java.util.Locale;
*/
public class SysuiLog<E extends Event> implements Dumpable {
public static final SimpleDateFormat DATE_FORMAT =
- new SimpleDateFormat("MM-dd HH:mm:ss", Locale.US);
+ new SimpleDateFormat("MM-dd HH:mm:ss.S", Locale.US);
protected final Object mDataLock = new Object();
private final String mId;
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index b1990beb9f57..e119beff3c6f 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -42,7 +42,7 @@ public class LogModule {
@Singleton
@DozeLog
public static LogBuffer provideDozeLogBuffer(
- LogcatEchoTrackerDebug bufferFilter,
+ LogcatEchoTracker bufferFilter,
DumpController dumpController) {
LogBuffer buffer = new LogBuffer("DozeLog", 100, 10, bufferFilter);
buffer.attach(dumpController);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 35b8312ba25c..0fd74547334b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -31,7 +31,6 @@ import android.metrics.LogMaker;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.service.quicksettings.Tile;
import android.util.AttributeSet;
@@ -62,7 +61,6 @@ import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.settings.BrightnessController;
import com.android.systemui.settings.ToggleSliderView;
import com.android.systemui.shared.plugins.PluginManager;
-import com.android.systemui.statusbar.phone.NPVPluginManager;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.statusbar.policy.BrightnessMirrorController.BrightnessMirrorListener;
import com.android.systemui.tuner.TunerService;
@@ -120,7 +118,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
private FrameLayout mPluginFrame;
private final PluginManager mPluginManager;
- private NPVPluginManager mNPVPluginManager;
private final LocalMediaManager.DeviceCallback mDeviceCallback =
new LocalMediaManager.DeviceCallback() {
@@ -201,14 +198,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
findViewById(R.id.brightness_slider), broadcastDispatcher);
mDumpController = dumpController;
mPluginManager = pluginManager;
- if (mPluginManager != null && Settings.System.getInt(
- mContext.getContentResolver(), "npv_plugin_flag", 0) == 2) {
- mPluginFrame = (FrameLayout) LayoutInflater.from(mContext).inflate(
- R.layout.status_bar_expanded_plugin_frame, this, false);
- addView(mPluginFrame);
- mNPVPluginManager = new NPVPluginManager(mPluginFrame, mPluginManager);
- }
-
}
/**
@@ -556,7 +545,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
if (mListening) {
refreshAllTiles();
}
- if (mNPVPluginManager != null) mNPVPluginManager.setListening(listening);
}
public void setListening(boolean listening, boolean expanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 557c64b7dfb9..411980b399bd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -191,7 +191,6 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
mTile.setLabel(tile.getLabel());
mTile.setSubtitle(tile.getSubtitle());
mTile.setContentDescription(tile.getContentDescription());
- mTile.setStateDescription(tile.getStateDescription());
mTile.setState(tile.getState());
}
@@ -346,12 +345,6 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
state.contentDescription = state.label;
}
- if (mTile.getStateDescription() != null) {
- state.stateDescription = mTile.getStateDescription();
- } else {
- state.stateDescription = null;
- }
-
if (state instanceof BooleanState) {
state.expandedAccessibilityClassName = Switch.class.getName();
((BooleanState) state).value = (state.state == Tile.STATE_ACTIVE);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 2b53727f237e..554672d88052 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -16,7 +16,6 @@ package com.android.systemui.qs.tileimpl;
import android.content.Context;
import android.os.Build;
-import android.provider.Settings;
import android.util.Log;
import android.view.ContextThemeWrapper;
@@ -33,7 +32,6 @@ import com.android.systemui.qs.tiles.BluetoothTile;
import com.android.systemui.qs.tiles.CastTile;
import com.android.systemui.qs.tiles.CellularTile;
import com.android.systemui.qs.tiles.ColorInversionTile;
-import com.android.systemui.qs.tiles.ControlsTile;
import com.android.systemui.qs.tiles.DataSaverTile;
import com.android.systemui.qs.tiles.DndTile;
import com.android.systemui.qs.tiles.FlashlightTile;
@@ -60,7 +58,6 @@ public class QSFactoryImpl implements QSFactory {
private final Provider<WifiTile> mWifiTileProvider;
private final Provider<BluetoothTile> mBluetoothTileProvider;
- private final Provider<ControlsTile> mControlsTileProvider;
private final Provider<CellularTile> mCellularTileProvider;
private final Provider<DndTile> mDndTileProvider;
private final Provider<ColorInversionTile> mColorInversionTileProvider;
@@ -85,7 +82,6 @@ public class QSFactoryImpl implements QSFactory {
@Inject
public QSFactoryImpl(Provider<WifiTile> wifiTileProvider,
Provider<BluetoothTile> bluetoothTileProvider,
- Provider<ControlsTile> controlsTileProvider,
Provider<CellularTile> cellularTileProvider,
Provider<DndTile> dndTileProvider,
Provider<ColorInversionTile> colorInversionTileProvider,
@@ -106,7 +102,6 @@ public class QSFactoryImpl implements QSFactory {
Provider<ScreenRecordTile> screenRecordTileProvider) {
mWifiTileProvider = wifiTileProvider;
mBluetoothTileProvider = bluetoothTileProvider;
- mControlsTileProvider = controlsTileProvider;
mCellularTileProvider = cellularTileProvider;
mDndTileProvider = dndTileProvider;
mColorInversionTileProvider = colorInversionTileProvider;
@@ -146,11 +141,6 @@ public class QSFactoryImpl implements QSFactory {
return mWifiTileProvider.get();
case "bt":
return mBluetoothTileProvider.get();
- case "controls":
- if (Settings.System.getInt(mHost.getContext().getContentResolver(),
- "npv_plugin_flag", 0) == 3) {
- return mControlsTileProvider.get();
- } else return null;
case "cell":
return mCellularTileProvider.get();
case "dnd":
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
index fda9e5b1f1ef..8b7f280608a5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
@@ -65,6 +65,7 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
private String mAccessibilityClass;
private boolean mTileState;
private boolean mCollapsedView;
+ private boolean mClicked;
private boolean mShowRippleEffect = true;
private final ImageView mBg;
@@ -233,35 +234,13 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
setLongClickable(state.handlesLongClick);
mIcon.setIcon(state, allowAnimations);
setContentDescription(state.contentDescription);
- final StringBuilder stateDescription = new StringBuilder();
- switch (state.state) {
- case Tile.STATE_UNAVAILABLE:
- stateDescription.append(mContext.getString(R.string.tile_unavailable));
- break;
- case Tile.STATE_INACTIVE:
- if (state instanceof QSTile.BooleanState) {
- stateDescription.append(mContext.getString(R.string.switch_bar_off));
- }
- break;
- case Tile.STATE_ACTIVE:
- if (state instanceof QSTile.BooleanState) {
- stateDescription.append(mContext.getString(R.string.switch_bar_on));
- }
- break;
- default:
- break;
- }
- if (!TextUtils.isEmpty(state.stateDescription)) {
- stateDescription.append(", ");
- stateDescription.append(state.stateDescription);
- }
- setStateDescription(stateDescription.toString());
mAccessibilityClass =
state.state == Tile.STATE_UNAVAILABLE ? null : state.expandedAccessibilityClassName;
if (state instanceof QSTile.BooleanState) {
boolean newState = ((BooleanState) state).value;
if (mTileState != newState) {
+ mClicked = false;
mTileState = newState;
}
}
@@ -318,10 +297,23 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
}
@Override
+ public boolean performClick() {
+ mClicked = true;
+ return super.performClick();
+ }
+
+ @Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
if (!TextUtils.isEmpty(mAccessibilityClass)) {
event.setClassName(mAccessibilityClass);
+ if (Switch.class.getName().equals(mAccessibilityClass)) {
+ boolean b = mClicked ? !mTileState : mTileState;
+ String label = getResources()
+ .getString(b ? R.string.switch_bar_on : R.string.switch_bar_off);
+ event.setContentDescription(label);
+ event.setChecked(b);
+ }
}
}
@@ -333,6 +325,11 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
if (!TextUtils.isEmpty(mAccessibilityClass)) {
info.setClassName(mAccessibilityClass);
if (Switch.class.getName().equals(mAccessibilityClass)) {
+ boolean b = mClicked ? !mTileState : mTileState;
+ String label = getResources()
+ .getString(b ? R.string.switch_bar_on : R.string.switch_bar_off);
+ info.setText(label);
+ info.setChecked(b);
info.setCheckable(true);
if (isLongClickable()) {
info.addAction(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 361b6c1b1260..9282a2e3b312 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -134,27 +134,25 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
state.secondaryLabel = TextUtils.emptyIfNull(
getSecondaryLabel(enabled, connecting, connected, state.isTransient));
- state.contentDescription = state.label;
- state.stateDescription = "";
if (enabled) {
if (connected) {
state.icon = new BluetoothConnectedTileIcon();
if (!TextUtils.isEmpty(mController.getConnectedDeviceName())) {
state.label = mController.getConnectedDeviceName();
}
- state.stateDescription =
+ state.contentDescription =
mContext.getString(R.string.accessibility_bluetooth_name, state.label)
+ ", " + state.secondaryLabel;
} else if (state.isTransient) {
state.icon = ResourceIcon.get(
com.android.internal.R.drawable.ic_bluetooth_transient_animation);
- state.stateDescription = state.secondaryLabel;
+ state.contentDescription = state.secondaryLabel;
} else {
state.icon =
ResourceIcon.get(com.android.internal.R.drawable.ic_qs_bluetooth);
state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_bluetooth);
- state.stateDescription = mContext.getString(R.string.accessibility_not_connected);
+ R.string.accessibility_quick_settings_bluetooth) + ","
+ + mContext.getString(R.string.accessibility_not_connected);
}
state.state = Tile.STATE_ACTIVE;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 58de0575fa75..32b051e35604 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -183,7 +183,6 @@ public class CastTile extends QSTileImpl<BooleanState> {
protected void handleUpdateState(BooleanState state, Object arg) {
state.label = mContext.getString(R.string.quick_settings_cast_title);
state.contentDescription = state.label;
- state.stateDescription = "";
state.value = false;
final List<CastDevice> devices = mController.getCastDevices();
boolean connecting = false;
@@ -193,9 +192,8 @@ public class CastTile extends QSTileImpl<BooleanState> {
if (device.state == CastDevice.STATE_CONNECTED) {
state.value = true;
state.secondaryLabel = getDeviceName(device);
- state.stateDescription = state.stateDescription + ","
- + mContext.getString(
- R.string.accessibility_cast_name, state.label);
+ state.contentDescription = state.contentDescription + ","
+ + mContext.getString(R.string.accessibility_cast_name, state.label);
connecting = false;
break;
} else if (device.state == CastDevice.STATE_CONNECTING) {
@@ -219,8 +217,9 @@ public class CastTile extends QSTileImpl<BooleanState> {
state.state = Tile.STATE_UNAVAILABLE;
String noWifi = mContext.getString(R.string.quick_settings_cast_no_wifi);
state.secondaryLabel = noWifi;
+ state.contentDescription = state.contentDescription + ", " + mContext.getString(
+ R.string.accessibility_quick_settings_not_available, noWifi);
}
- state.stateDescription = state.stateDescription + ", " + state.secondaryLabel;
mDetailAdapter.updateItems(devices);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index d5f86c951407..22470c7f5af5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -194,13 +194,17 @@ public class CellularTile extends QSTileImpl<SignalState> {
state.secondaryLabel = r.getString(R.string.cell_data_off);
}
- state.contentDescription = state.label;
+
+ // TODO(b/77881974): Instead of switching out the description via a string check for
+ // we need to have two strings provided by the MobileIconGroup.
+ final CharSequence contentDescriptionSuffix;
if (state.state == Tile.STATE_INACTIVE) {
- // This information is appended later by converting the Tile.STATE_INACTIVE state.
- state.stateDescription = "";
+ contentDescriptionSuffix = r.getString(R.string.cell_data_off_content_description);
} else {
- state.stateDescription = state.secondaryLabel;
+ contentDescriptionSuffix = state.secondaryLabel;
}
+
+ state.contentDescription = state.label + ", " + contentDescriptionSuffix;
}
private CharSequence appendMobileDataType(CharSequence current, CharSequence dataType) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ControlsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ControlsTile.java
deleted file mode 100644
index 39ae66e7607a..000000000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ControlsTile.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.systemui.qs.tiles;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import com.android.systemui.R;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.NPVPlugin;
-import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.qs.DetailAdapter;
-import com.android.systemui.plugins.qs.QSTile.BooleanState;
-import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.shared.plugins.PluginManager;
-
-import javax.inject.Inject;
-
-
-/**
- * Temporary control test for prototyping
- */
-public class ControlsTile extends QSTileImpl<BooleanState> {
- private ControlsDetailAdapter mDetailAdapter;
- private final ActivityStarter mActivityStarter;
- private PluginManager mPluginManager;
- private NPVPlugin mPlugin;
- private Intent mHomeAppIntent;
-
- @Inject
- public ControlsTile(QSHost host,
- ActivityStarter activityStarter,
- PluginManager pluginManager) {
- super(host);
- mActivityStarter = activityStarter;
- mPluginManager = pluginManager;
- mDetailAdapter = (ControlsDetailAdapter) createDetailAdapter();
-
- mHomeAppIntent = new Intent(Intent.ACTION_VIEW);
- mHomeAppIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mHomeAppIntent.setComponent(new ComponentName("com.google.android.apps.chromecast.app",
- "com.google.android.apps.chromecast.app.DiscoveryActivity"));
- }
-
- @Override
- public DetailAdapter getDetailAdapter() {
- return mDetailAdapter;
- }
-
- @Override
- public BooleanState newTileState() {
- return new BooleanState();
- }
-
- @Override
- public void handleSetListening(boolean listening) {
-
- }
-
- @Override
- public void setDetailListening(boolean listening) {
- if (mPlugin == null) return;
-
- mPlugin.setListening(listening);
- }
-
- @Override
- protected void handleClick() {
- showDetail(true);
- }
-
- @Override
- public Intent getLongClickIntent() {
- return mHomeAppIntent;
- }
-
- @Override
- protected void handleSecondaryClick() {
- showDetail(true);
- }
-
- @Override
- public CharSequence getTileLabel() {
- return "Controls";
- }
-
- @Override
- protected void handleUpdateState(BooleanState state, Object arg) {
- state.icon = ResourceIcon.get(R.drawable.ic_lightbulb_outline_gm2_24px);
- state.label = "Controls";
- }
-
- @Override
- public boolean supportsDetailView() {
- return getDetailAdapter() != null && mQSSettingsPanelOption == QSSettingsPanel.OPEN_CLICK;
- }
-
- @Override
- public int getMetricsCategory() {
- return -1;
- }
-
- @Override
- protected String composeChangeAnnouncement() {
- if (mState.value) {
- return "On";
- } else {
- return "Off";
- }
- }
-
- @Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
- protected DetailAdapter createDetailAdapter() {
- mDetailAdapter = new ControlsDetailAdapter();
- return mDetailAdapter;
- }
-
- private class ControlsDetailAdapter implements DetailAdapter {
- private View mDetailView;
- protected FrameLayout mHomeControlsLayout;
-
- public CharSequence getTitle() {
- return "Controls";
- }
-
- public Boolean getToggleState() {
- return null;
- }
-
- public boolean getToggleEnabled() {
- return false;
- }
-
- public View createDetailView(Context context, View convertView, final ViewGroup parent) {
- if (convertView != null) return convertView;
-
- mHomeControlsLayout = (FrameLayout) LayoutInflater.from(context).inflate(
- R.layout.home_controls, parent, false);
- mHomeControlsLayout.setVisibility(View.VISIBLE);
- parent.addView(mHomeControlsLayout);
-
- mPluginManager.addPluginListener(
- new PluginListener<NPVPlugin>() {
- @Override
- public void onPluginConnected(NPVPlugin plugin,
- Context pluginContext) {
- mPlugin = plugin;
- mPlugin.attachToRoot(mHomeControlsLayout);
- mPlugin.setListening(true);
- }
-
- @Override
- public void onPluginDisconnected(NPVPlugin plugin) {
- mPlugin.setListening(false);
- mHomeControlsLayout.removeAllViews();
-
- }
- }, NPVPlugin.class, false);
- return mHomeControlsLayout;
- }
-
- public Intent getSettingsIntent() {
- return mHomeAppIntent;
- }
-
- public void setToggleState(boolean state) {
-
- }
-
- public int getMetricsCategory() {
- return -1;
- }
-
- public boolean hasHeader() {
- return false;
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 9215da4cda9a..52d1a5b3b991 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -240,8 +240,6 @@ public class DndTile extends QSTileImpl<BooleanState> {
zen != Global.ZEN_MODE_OFF, mController.getConfig(), false));
state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_dnd);
checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
- // Keeping the secondaryLabel in contentDescription instead of stateDescription is easier
- // to understand.
switch (zen) {
case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
state.contentDescription =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 792c36477962..dafdd89ee62c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -102,13 +102,14 @@ public class FlashlightTile extends QSTileImpl<BooleanState> implements
}
state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
state.secondaryLabel = "";
- state.stateDescription = "";
if (!mFlashlightController.isAvailable()) {
state.icon = mIcon;
state.slash.isSlashed = true;
state.secondaryLabel = mContext.getString(
R.string.quick_settings_flashlight_camera_in_use);
- state.stateDescription = state.secondaryLabel;
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_flashlight_unavailable)
+ + ", " + state.secondaryLabel;
state.state = Tile.STATE_UNAVAILABLE;
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index fd6b936d71c0..001e09406e3a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -147,7 +147,6 @@ public class HotspotTile extends QSTileImpl<BooleanState> {
state.secondaryLabel = getSecondaryLabel(
isTileActive, isTransient, isDataSaverEnabled, numConnectedDevices);
- state.stateDescription = state.secondaryLabel;
}
@Nullable
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index e617867eb10e..fbdca3ba1c7b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -105,8 +105,15 @@ public class LocationTile extends QSTileImpl<BooleanState> {
}
state.icon = mIcon;
state.slash.isSlashed = !state.value;
- state.label = mContext.getString(R.string.quick_settings_location_label);
- state.contentDescription = state.label;
+ if (locationEnabled) {
+ state.label = mContext.getString(R.string.quick_settings_location_label);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_location_on);
+ } else {
+ state.label = mContext.getString(R.string.quick_settings_location_label);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_location_off);
+ }
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
state.expandedAccessibilityClassName = Switch.class.getName();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 6e8dcf36bacc..b7ce101cacab 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -195,7 +195,6 @@ public class WifiTile extends QSTileImpl<SignalState> {
state.activityIn = cb.enabled && cb.activityIn;
state.activityOut = cb.enabled && cb.activityOut;
final StringBuffer minimalContentDescription = new StringBuffer();
- final StringBuffer minimalStateDescription = new StringBuffer();
final Resources r = mContext.getResources();
if (isTransient) {
state.icon = ResourceIcon.get(
@@ -220,14 +219,13 @@ public class WifiTile extends QSTileImpl<SignalState> {
mContext.getString(R.string.quick_settings_wifi_label)).append(",");
if (state.value) {
if (wifiConnected) {
- minimalStateDescription.append(cb.wifiSignalContentDescription);
+ minimalContentDescription.append(cb.wifiSignalContentDescription).append(",");
minimalContentDescription.append(removeDoubleQuotes(cb.ssid));
if (!TextUtils.isEmpty(state.secondaryLabel)) {
minimalContentDescription.append(",").append(state.secondaryLabel);
}
}
}
- state.stateDescription = minimalStateDescription.toString();
state.contentDescription = minimalContentDescription.toString();
state.dualLabelContentDescription = r.getString(
R.string.accessibility_quick_settings_open_settings, getTileLabel());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index e54ee51fb9d4..7853dc388bcb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -103,11 +103,14 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements
state.icon = mIcon;
if (state.value) {
state.slash.isSlashed = false;
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_work_mode_on);
} else {
state.slash.isSlashed = true;
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_work_mode_off);
}
state.label = mContext.getString(R.string.quick_settings_work_mode_label);
- state.contentDescription = state.label;
state.expandedAccessibilityClassName = Switch.class.getName();
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index afaa593b3bb9..e7d6eba1dcb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -22,7 +22,6 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
-import com.android.systemui.doze.DozeEvent;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -53,7 +52,7 @@ public class DozeScrimController implements StateListener {
public void onDisplayBlanked() {
if (DEBUG) {
Log.d(TAG, "Pulse in, mDozing=" + mDozing + " mPulseReason="
- + DozeEvent.reasonToString(mPulseReason));
+ + DozeLog.reasonToString(mPulseReason));
}
if (!mDozing) {
return;
@@ -74,8 +73,8 @@ public class DozeScrimController implements StateListener {
// Notifications should time out on their own. Pulses due to notifications should
// instead be managed externally based off the notification's lifetime.
// Dock also controls the time out by self.
- if (mPulseReason != DozeEvent.PULSE_REASON_NOTIFICATION
- && mPulseReason != DozeEvent.PULSE_REASON_DOCKING) {
+ if (mPulseReason != DozeLog.PULSE_REASON_NOTIFICATION
+ && mPulseReason != DozeLog.PULSE_REASON_DOCKING) {
mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
mHandler.postDelayed(mPulseOutExtended,
mDozeParameters.getPulseVisibleDurationExtended());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index 04efc2d7558d..56e5cb08f6d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -31,7 +31,6 @@ import android.view.View;
import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.assist.AssistManager;
-import com.android.systemui.doze.DozeEvent;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.doze.DozeReceiver;
@@ -221,18 +220,18 @@ public final class DozeServiceHost implements DozeHost {
@Override
public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
- if (reason == DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS) {
+ if (reason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS) {
mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
"com.android.systemui:LONG_PRESS");
mAssistManagerLazy.get().startAssist(new Bundle());
return;
}
- if (reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
+ if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
mScrimController.setWakeLockScreenSensorActive(true);
}
- boolean passiveAuthInterrupt = reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
+ boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
&& mWakeLockScreenPerformsAuth;
// Set the state to pulsing, so ScrimController will know what to do once we ask it to
// execute the transition. The pulse callback will then be invoked when the scrims
@@ -332,7 +331,7 @@ public final class DozeServiceHost implements DozeHost {
@Override
public void extendPulse(int reason) {
- if (reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
+ if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
mScrimController.setWakeLockScreenSensorActive(true);
}
if (mDozeScrimController.isPulsing() && mHeadsUpManagerPhone.hasNotifications()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVPluginManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVPluginManager.kt
deleted file mode 100644
index 53601babfd56..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVPluginManager.kt
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone
-
-import android.content.Context
-import android.view.View
-import android.view.ViewGroup.MarginLayoutParams
-import android.widget.FrameLayout
-import com.android.systemui.plugins.NPVPlugin
-import com.android.systemui.plugins.PluginListener
-import com.android.systemui.qs.TouchAnimator
-import com.android.systemui.shared.plugins.PluginManager
-
-/**
- * Manages the NPVPlugin view and state
- *
- * Abstracts NPVPlugin from NPV and helps animate on expansion and respond to changes in Config.
- */
-class NPVPluginManager(
- var parent: FrameLayout,
- val pluginManager: PluginManager
-) : PluginListener<NPVPlugin> {
-
- private var plugin: NPVPlugin? = null
- private var animator = createAnimator()
- private var yOffset = 0f
-
- private fun createAnimator() = TouchAnimator.Builder()
- .addFloat(parent, "alpha", 1f, 0f)
- .addFloat(parent, "scaleY", 1f, 0f)
- .build()
-
- init {
- pluginManager.addPluginListener(NPVPlugin.ACTION, this, NPVPlugin::class.java, false)
- parent.pivotY = 0f
- }
-
- override fun onPluginConnected(plugin: NPVPlugin, pluginContext: Context) {
- parent.removeAllViews()
- plugin.attachToRoot(parent)
- this.plugin = plugin
- parent.visibility = View.VISIBLE
- }
-
- fun changeVisibility(visibility: Int) {
- parent.visibility = if (plugin != null) visibility else View.GONE
- }
-
- fun destroy() {
- plugin?.onDestroy()
- pluginManager.removePluginListener(this)
- }
-
- override fun onPluginDisconnected(plugin: NPVPlugin) {
- if (this.plugin == plugin) {
- this.plugin = null
- parent.removeAllViews()
- parent.visibility = View.GONE
- }
- }
-
- fun setListening(listening: Boolean) {
- plugin?.setListening(listening)
- }
-
- fun setExpansion(expansion: Float, headerTranslation: Float, heightDiff: Float) {
- parent.setTranslationY(expansion * heightDiff + headerTranslation + yOffset)
- if (!expansion.isNaN()) animator.setPosition(expansion)
- }
-
- fun replaceFrameLayout(newParent: FrameLayout) {
- newParent.visibility = parent.visibility
- parent.removeAllViews()
- plugin?.attachToRoot(newParent)
- parent = newParent
- animator = createAnimator()
- }
-
- fun getHeight() =
- if (plugin != null) {
- parent.height + (parent.getLayoutParams() as MarginLayoutParams).topMargin
- } else 0
-
- fun setYOffset(y: Float) {
- yOffset = y
- parent.setTranslationY(yOffset)
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 6112ae88f634..d2186f959aba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -25,10 +25,8 @@ import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.app.Fragment;
import android.app.StatusBarManager;
-import android.content.Context;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -40,8 +38,6 @@ import android.graphics.drawable.Drawable;
import android.hardware.biometrics.BiometricSourceType;
import android.os.PowerManager;
import android.os.SystemClock;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
import android.util.Log;
import android.util.MathUtils;
import android.view.LayoutInflater;
@@ -57,7 +53,6 @@ import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
@@ -73,13 +68,10 @@ import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.HomeControlsPlugin;
-import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.qs.QSFragment;
-import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.GestureRecorder;
@@ -113,7 +105,6 @@ import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.util.InjectionInflationController;
-import com.android.systemui.util.Utils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -173,8 +164,6 @@ public class NotificationPanelViewController extends PanelViewController {
private final ConfigurationController mConfigurationController;
private final FlingAnimationUtils.Builder mFlingAnimationUtilsBuilder;
- private double mQqsSplitFraction;
-
// Cap and total height of Roboto font. Needs to be adjusted when font for the big clock is
// changed.
private static final int CAP_HEIGHT = 1456;
@@ -258,7 +247,6 @@ public class NotificationPanelViewController extends PanelViewController {
private View mQsNavbarScrim;
private NotificationsQuickSettingsContainer mNotificationContainerParent;
private NotificationStackScrollLayout mNotificationStackScroller;
- private FrameLayout mHomeControlsLayout;
private boolean mAnimateNextPositionUpdate;
private int mTrackingPointer;
@@ -446,9 +434,6 @@ public class NotificationPanelViewController extends PanelViewController {
*/
private boolean mDelayShowingKeyguardStatusBar;
- private PluginManager mPluginManager;
- private FrameLayout mPluginFrame;
- private NPVPluginManager mNPVPluginManager;
private int mOldLayoutDirection;
@Inject
@@ -457,7 +442,7 @@ public class NotificationPanelViewController extends PanelViewController {
NotificationWakeUpCoordinator coordinator, PulseExpansionHandler pulseExpansionHandler,
DynamicPrivacyController dynamicPrivacyController,
KeyguardBypassController bypassController, FalsingManager falsingManager,
- PluginManager pluginManager, ShadeController shadeController,
+ ShadeController shadeController,
NotificationLockscreenUserManager notificationLockscreenUserManager,
NotificationEntryManager notificationEntryManager,
KeyguardStateController keyguardStateController,
@@ -523,7 +508,6 @@ public class NotificationPanelViewController extends PanelViewController {
});
mBottomAreaShadeAlphaAnimator.setDuration(160);
mBottomAreaShadeAlphaAnimator.setInterpolator(Interpolators.ALPHA_OUT);
- mPluginManager = pluginManager;
mShadeController = shadeController;
mLockscreenUserManager = notificationLockscreenUserManager;
mEntryManager = notificationEntryManager;
@@ -553,7 +537,6 @@ public class NotificationPanelViewController extends PanelViewController {
mBigClockContainer = mView.findViewById(R.id.big_clock_container);
keyguardClockSwitch.setBigClockContainer(mBigClockContainer);
- mHomeControlsLayout = mView.findViewById(R.id.home_controls_layout);
mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
mNotificationStackScroller = mView.findViewById(R.id.notification_stack_scroller);
mNotificationStackScroller.setOnHeightChangedListener(mOnHeightChangedListener);
@@ -563,12 +546,6 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardBottomArea = mView.findViewById(R.id.keyguard_bottom_area);
mQsNavbarScrim = mView.findViewById(R.id.qs_navbar_scrim);
mLastOrientation = mResources.getConfiguration().orientation;
- mPluginFrame = mView.findViewById(R.id.plugin_frame);
- if (Settings.System.getInt(mView.getContext().getContentResolver(), "npv_plugin_flag", 0)
- == 1) {
- mNPVPluginManager = new NPVPluginManager(mPluginFrame, mPluginManager);
- }
-
initBottomArea();
@@ -592,19 +569,6 @@ public class NotificationPanelViewController extends PanelViewController {
}
});
- mPluginManager.addPluginListener(new PluginListener<HomeControlsPlugin>() {
-
- @Override
- public void onPluginConnected(HomeControlsPlugin plugin, Context pluginContext) {
- plugin.sendParentGroup(mHomeControlsLayout);
- }
-
- @Override
- public void onPluginDisconnected(HomeControlsPlugin plugin) {
-
- }
- }, HomeControlsPlugin.class, false);
-
mView.setRtlChangeListener(layoutDirection -> {
if (layoutDirection != mOldLayoutDirection) {
mAffordanceHelper.onRtlPropertiesChanged();
@@ -637,9 +601,6 @@ public class NotificationPanelViewController extends PanelViewController {
com.android.internal.R.dimen.status_bar_height);
mHeadsUpInset = statusbarHeight + mResources.getDimensionPixelSize(
R.dimen.heads_up_status_bar_padding);
- mQqsSplitFraction = ((float) mResources.getInteger(R.integer.qqs_split_fraction)) / (
- mResources.getInteger(R.integer.qqs_split_fraction) + mResources.getInteger(
- R.integer.qs_split_fraction));
}
/**
@@ -679,18 +640,6 @@ public class NotificationPanelViewController extends PanelViewController {
lp.gravity = panelGravity;
mNotificationStackScroller.setLayoutParams(lp);
}
- int sideMargin = mResources.getDimensionPixelOffset(R.dimen.notification_side_paddings);
- int topMargin = sideMargin;
- lp = (FrameLayout.LayoutParams) mPluginFrame.getLayoutParams();
- if (lp.width != qsWidth || lp.gravity != panelGravity || lp.leftMargin != sideMargin
- || lp.rightMargin != sideMargin || lp.topMargin != topMargin) {
- lp.width = qsWidth;
- lp.gravity = panelGravity;
- lp.leftMargin = sideMargin;
- lp.rightMargin = sideMargin;
- lp.topMargin = topMargin;
- mPluginFrame.setLayoutParams(lp);
- }
}
private void reInflateViews() {
@@ -732,41 +681,6 @@ public class NotificationPanelViewController extends PanelViewController {
if (mOnReinflationListener != null) {
mOnReinflationListener.run();
}
- reinflatePluginContainer();
- }
-
- private void reinflatePluginContainer() {
- int index = mView.indexOfChild(mPluginFrame);
- mView.removeView(mPluginFrame);
- mPluginFrame = (FrameLayout) mInjectionInflationController.injectable(
- LayoutInflater.from(mView.getContext())).inflate(
- R.layout.status_bar_expanded_plugin_frame, mView, false);
- mView.addView(mPluginFrame, index);
-
- Resources res = mView.getResources();
- int qsWidth = res.getDimensionPixelSize(R.dimen.qs_panel_width);
- int panelGravity = mView.getResources().getInteger(
- R.integer.notification_panel_layout_gravity);
- FrameLayout.LayoutParams lp;
- int sideMargin = res.getDimensionPixelOffset(R.dimen.notification_side_paddings);
- int topMargin = res.getDimensionPixelOffset(
- com.android.internal.R.dimen.quick_qs_total_height);
- if (Utils.useQsMediaPlayer(mView.getContext())) {
- topMargin = res.getDimensionPixelOffset(
- com.android.internal.R.dimen.quick_qs_total_height_with_media);
- }
- lp = (FrameLayout.LayoutParams) mPluginFrame.getLayoutParams();
- if (lp.width != qsWidth || lp.gravity != panelGravity || lp.leftMargin != sideMargin
- || lp.rightMargin != sideMargin || lp.topMargin != topMargin) {
- lp.width = qsWidth;
- lp.gravity = panelGravity;
- lp.leftMargin = sideMargin;
- lp.rightMargin = sideMargin;
- lp.topMargin = topMargin;
- mPluginFrame.setLayoutParams(lp);
- }
-
- if (mNPVPluginManager != null) mNPVPluginManager.replaceFrameLayout(mPluginFrame);
}
private void initBottomArea() {
@@ -1266,17 +1180,6 @@ public class NotificationPanelViewController extends PanelViewController {
// earlier so the state is already up to date when dragging down.
setListening(true);
}
- if (isQsSplitEnabled() && !mKeyguardShowing) {
- if (mQsExpandImmediate) {
- mNotificationStackScroller.setVisibility(View.GONE);
- mQsFrame.setVisibility(View.VISIBLE);
- mHomeControlsLayout.setVisibility(View.VISIBLE);
- } else {
- mNotificationStackScroller.setVisibility(View.VISIBLE);
- mQsFrame.setVisibility(View.GONE);
- mHomeControlsLayout.setVisibility(View.GONE);
- }
- }
return false;
}
@@ -1286,17 +1189,6 @@ public class NotificationPanelViewController extends PanelViewController {
|| y <= mQs.getView().getY() + mQs.getView().getHeight());
}
- private boolean isOnQsEndArea(float x) {
- if (!isQsSplitEnabled()) return false;
- if (mView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) {
- return x >= mQsFrame.getX() + mQqsSplitFraction * mQsFrame.getWidth()
- && x <= mQsFrame.getX() + mQsFrame.getWidth();
- } else {
- return x >= mQsFrame.getX()
- && x <= mQsFrame.getX() + (1 - mQqsSplitFraction) * mQsFrame.getWidth();
- }
- }
-
private boolean isOpenQsEvent(MotionEvent event) {
final int pointerCount = event.getPointerCount();
final int action = event.getActionMasked();
@@ -1317,9 +1209,7 @@ public class NotificationPanelViewController extends PanelViewController {
MotionEvent.BUTTON_SECONDARY) || event.isButtonPressed(
MotionEvent.BUTTON_TERTIARY));
- final boolean onHeaderRight = isOnQsEndArea(event.getX());
-
- return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag || onHeaderRight;
+ return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag;
}
private void handleQsDown(MotionEvent event) {
@@ -1659,10 +1549,7 @@ public class NotificationPanelViewController extends PanelViewController {
mBarState != StatusBarState.KEYGUARD && (!mQsExpanded
|| mQsExpansionFromOverscroll));
updateEmptyShadeView();
- if (mNPVPluginManager != null) {
- mNPVPluginManager.changeVisibility(
- (mBarState != StatusBarState.KEYGUARD) ? View.VISIBLE : View.INVISIBLE);
- }
+
mQsNavbarScrim.setVisibility(
mBarState == StatusBarState.SHADE && mQsExpanded && !mStackScrollerOverscrolling
&& mQsScrimEnabled ? View.VISIBLE : View.INVISIBLE);
@@ -1718,9 +1605,6 @@ public class NotificationPanelViewController extends PanelViewController {
float qsExpansionFraction = getQsExpansionFraction();
mQs.setQsExpansion(qsExpansionFraction, getHeaderTranslation());
int heightDiff = mQs.getDesiredHeight() - mQs.getQsMinExpansionHeight();
- if (mNPVPluginManager != null) {
- mNPVPluginManager.setExpansion(qsExpansionFraction, getHeaderTranslation(), heightDiff);
- }
mNotificationStackScroller.setQsExpansionFraction(qsExpansionFraction);
}
@@ -2015,7 +1899,6 @@ public class NotificationPanelViewController extends PanelViewController {
targetHeight =
mQsMinExpansionHeight + t * (mQsMaxExpansionHeight - mQsMinExpansionHeight);
setQsExpansion(targetHeight);
- mHomeControlsLayout.setTranslationY(targetHeight);
}
updateExpandedHeight(expandedHeight);
updateHeader();
@@ -2150,7 +2033,6 @@ public class NotificationPanelViewController extends PanelViewController {
appearAmount = mNotificationStackScroller.calculateAppearFractionBypass();
}
startHeight = -mQs.getQsMinExpansionHeight();
- if (mNPVPluginManager != null) startHeight -= mNPVPluginManager.getHeight();
}
float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount))
+ mExpandOffset;
@@ -2294,7 +2176,6 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardStatusBar.setListening(listening);
if (mQs == null) return;
mQs.setListening(listening);
- if (mNPVPluginManager != null) mNPVPluginManager.setListening(listening);
}
@Override
@@ -3029,11 +2910,6 @@ public class NotificationPanelViewController extends PanelViewController {
mOnReinflationListener = onReinflationListener;
}
- public static boolean isQsSplitEnabled() {
- return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.QS_SPLIT_ENABLED, false);
- }
-
public void setAlpha(float alpha) {
mView.setAlpha(alpha);
}
@@ -3500,9 +3376,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
@Override
- public void onUiModeChanged() {
- reinflatePluginContainer();
- }
+ public void onUiModeChanged() {}
}
private class StatusBarStateListener implements StateListener {
@@ -3517,11 +3391,6 @@ public class NotificationPanelViewController extends PanelViewController {
mBarState = statusBarState;
mKeyguardShowing = keyguardShowing;
- if (mKeyguardShowing && isQsSplitEnabled()) {
- mNotificationStackScroller.setVisibility(View.VISIBLE);
- mQsFrame.setVisibility(View.VISIBLE);
- mHomeControlsLayout.setVisibility(View.GONE);
- }
if (oldState == StatusBarState.KEYGUARD && (goingToFullShade
|| statusBarState == StatusBarState.SHADE_LOCKED)) {
@@ -3544,7 +3413,6 @@ public class NotificationPanelViewController extends PanelViewController {
} else {
mKeyguardStatusBar.setAlpha(1f);
mKeyguardStatusBar.setVisibility(keyguardShowing ? View.VISIBLE : View.INVISIBLE);
- ((PhoneStatusBarView) mBar).maybeShowDivider(keyguardShowing);
if (keyguardShowing && oldState != mBarState) {
if (mQs != null) {
mQs.hideImmediately();
@@ -3622,10 +3490,6 @@ public class NotificationPanelViewController extends PanelViewController {
int oldMaxHeight = mQsMaxExpansionHeight;
if (mQs != null) {
mQsMinExpansionHeight = mKeyguardShowing ? 0 : mQs.getQsMinExpansionHeight();
- if (mNPVPluginManager != null) {
- mNPVPluginManager.setYOffset(mQsMinExpansionHeight);
- mQsMinExpansionHeight += mNPVPluginManager.getHeight();
- }
mQsMaxExpansionHeight = mQs.getDesiredHeight();
mNotificationStackScroller.setMaxTopPadding(
mQsMaxExpansionHeight + mQsNotificationTopPadding);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java
index 3af80387778b..10b68b9a518d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java
@@ -16,8 +16,10 @@
package com.android.systemui.statusbar.phone;
+import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
@@ -180,6 +182,13 @@ public class NotificationShadeWindowController implements Callback, Dumpable,
mLp.setTitle("NotificationShade");
mLp.packageName = mContext.getPackageName();
mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+
+ // We use BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE here, however, there is special logic in
+ // window manager which disables the transient show behavior.
+ // TODO: Clean this up once that behavior moves into the Shell.
+ mLp.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
+ mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
+
mWindowManager.addView(mNotificationShadeView, mLp);
mLpChanged.copyFrom(mLp);
onThemeChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
index 96b4b22d0580..e8bc2f58adb4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
@@ -32,7 +32,7 @@ public final class PhoneStatusBarTransitions extends BarTransitions {
private final PhoneStatusBarView mView;
private final float mIconAlphaWhenOpaque;
- private View mLeftSide, mStatusIcons, mBattery, mClock, mDivider;
+ private View mLeftSide, mStatusIcons, mBattery, mClock;
private Animator mCurrentAnimation;
public PhoneStatusBarTransitions(PhoneStatusBarView view) {
@@ -46,7 +46,6 @@ public final class PhoneStatusBarTransitions extends BarTransitions {
mLeftSide = mView.findViewById(R.id.status_bar_left_side);
mStatusIcons = mView.findViewById(R.id.statusIcons);
mBattery = mView.findViewById(R.id.battery);
- mDivider = mView.findViewById(R.id.divider);
applyModeBackground(-1, getMode(), false /*animate*/);
applyMode(getMode(), false /*animate*/);
}
@@ -89,7 +88,6 @@ public final class PhoneStatusBarTransitions extends BarTransitions {
anims.playTogether(
animateTransitionTo(mLeftSide, newAlpha),
animateTransitionTo(mStatusIcons, newAlpha),
- animateTransitionTo(mDivider, newAlpha),
animateTransitionTo(mBattery, newAlphaBC)
);
if (isLightsOut(mode)) {
@@ -100,8 +98,7 @@ public final class PhoneStatusBarTransitions extends BarTransitions {
} else {
mLeftSide.setAlpha(newAlpha);
mStatusIcons.setAlpha(newAlpha);
- mDivider.setAlpha(newAlpha);
mBattery.setAlpha(newAlphaBC);
}
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index ffbbffc0d8d9..f3b0a79f9518 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -25,7 +25,6 @@ import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
-import android.provider.DeviceConfig;
import android.util.AttributeSet;
import android.util.EventLog;
import android.util.Pair;
@@ -40,8 +39,6 @@ import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-import com.android.systemui.DarkReceiverImpl;
import com.android.systemui.Dependency;
import com.android.systemui.EventLogTags;
import com.android.systemui.R;
@@ -81,9 +78,6 @@ public class PhoneStatusBarView extends PanelBar {
@Nullable
private DisplayCutout mDisplayCutout;
- private DarkReceiverImpl mSplitDivider;
- private View mDividerContainer;
- private QsSplitPropertyListener mPropertyListener;
/**
* Draw this many pixels into the left/right side of the cutout to optimally use the space
*/
@@ -115,10 +109,6 @@ public class PhoneStatusBarView extends PanelBar {
mBattery = findViewById(R.id.battery);
mCutoutSpace = findViewById(R.id.cutout_space_view);
mCenterIconSpace = findViewById(R.id.centered_icon_area);
- mSplitDivider = findViewById(R.id.divider);
- mDividerContainer = findViewById(R.id.divider_container);
- maybeShowDivider(true);
- mPropertyListener = new QsSplitPropertyListener(mDividerContainer);
updateResources();
}
@@ -128,26 +118,16 @@ public class PhoneStatusBarView extends PanelBar {
super.onAttachedToWindow();
// Always have Battery meters in the status bar observe the dark/light modes.
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mBattery);
- Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mSplitDivider);
- maybeShowDivider(true);
if (updateOrientationAndCutout(getResources().getConfiguration().orientation)) {
updateLayoutForCutout();
}
- if (mPropertyListener != null) {
- DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
- mContext.getMainExecutor(), mPropertyListener);
- }
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mBattery);
- Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mSplitDivider);
mDisplayCutout = null;
- if (mPropertyListener != null) {
- DeviceConfig.removeOnPropertiesChangedListener(mPropertyListener);
- }
}
@Override
@@ -216,7 +196,6 @@ public class PhoneStatusBarView extends PanelBar {
public void onPanelPeeked() {
super.onPanelPeeked();
mBar.makeExpandedVisible(false);
- maybeShowDivider(!mBar.mPanelExpanded);
}
@Override
@@ -225,7 +204,6 @@ public class PhoneStatusBarView extends PanelBar {
// Close the status bar in the next frame so we can show the end of the animation.
post(mHideExpandedRunnable);
mIsFullyOpenedPanel = false;
- maybeShowDivider(!mBar.mPanelExpanded);
}
public void removePendingHideExpandedRunnables() {
@@ -239,7 +217,6 @@ public class PhoneStatusBarView extends PanelBar {
mPanel.getView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
mIsFullyOpenedPanel = true;
- maybeShowDivider(!mBar.mPanelExpanded);
}
@Override
@@ -263,28 +240,24 @@ public class PhoneStatusBarView extends PanelBar {
mBar.onTrackingStarted();
mScrimController.onTrackingStarted();
removePendingHideExpandedRunnables();
- maybeShowDivider(!mBar.mPanelExpanded);
}
@Override
public void onClosingFinished() {
super.onClosingFinished();
mBar.onClosingFinished();
- maybeShowDivider(!mBar.mPanelExpanded);
}
@Override
public void onTrackingStopped(boolean expand) {
super.onTrackingStopped(expand);
mBar.onTrackingStopped(expand);
- maybeShowDivider(!mBar.mPanelExpanded);
}
@Override
public void onExpandingFinished() {
super.onExpandingFinished();
mScrimController.onExpandingFinished();
- maybeShowDivider(!mBar.mPanelExpanded);
}
@Override
@@ -416,31 +389,4 @@ public class PhoneStatusBarView extends PanelBar {
protected boolean shouldPanelBeVisible() {
return mHeadsUpVisible || super.shouldPanelBeVisible();
}
-
- void maybeShowDivider(boolean showDivider) {
- int state =
- showDivider && NotificationPanelViewController.isQsSplitEnabled()
- ? View.VISIBLE : View.GONE;
- mDividerContainer.setVisibility(state);
- }
-
- private static class QsSplitPropertyListener implements
- DeviceConfig.OnPropertiesChangedListener {
- private final View mDivider;
-
- QsSplitPropertyListener(View divider) {
- mDivider = divider;
- }
-
- @Override
- public void onPropertiesChanged(DeviceConfig.Properties properties) {
- if (properties.getNamespace().equals(DeviceConfig.NAMESPACE_SYSTEMUI)
- && properties.getKeyset().contains(
- SystemUiDeviceConfigFlags.QS_SPLIT_ENABLED)) {
- boolean splitEnabled = properties.getBoolean(
- SystemUiDeviceConfigFlags.QS_SPLIT_ENABLED, false);
- mDivider.setVisibility(splitEnabled ? VISIBLE : GONE);
- }
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 86a81ce3d1f1..6a046884e835 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -16,6 +16,9 @@
package com.android.systemui.statusbar.phone;
+import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
+import static android.view.ViewRootImpl.sNewInsetsMode;
+import static android.view.WindowInsets.Type.navigationBars;
import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_FADING;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
@@ -789,7 +792,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private Runnable mMakeNavigationBarVisibleRunnable = new Runnable() {
@Override
public void run() {
- mStatusBar.getNavigationBarView().getRootView().setVisibility(View.VISIBLE);
+ if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) {
+ mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
+ .show(navigationBars());
+ } else {
+ mStatusBar.getNavigationBarView().getRootView().setVisibility(View.VISIBLE);
+ }
}
};
@@ -856,7 +864,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
} else {
mContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable);
- mStatusBar.getNavigationBarView().getRootView().setVisibility(View.GONE);
+ if (sNewInsetsMode == NEW_INSETS_MODE_FULL) {
+ mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
+ .hide(navigationBars());
+ } else {
+ mStatusBar.getNavigationBarView().getRootView().setVisibility(View.GONE);
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 3a1feaa2de14..28ba1257524d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -26,10 +26,12 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings.Global;
+import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation;
import android.telephony.CdmaEriInformation;
import android.telephony.CellSignalStrength;
import android.telephony.CellSignalStrengthCdma;
+import android.telephony.DataSpecificRegistrationInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
@@ -321,9 +323,9 @@ public class MobileSignalController extends SignalController<
private int getNumLevels() {
if (mInflateSignalStrengths) {
- return SignalStrength.NUM_SIGNAL_STRENGTH_BINS + 1;
+ return CellSignalStrength.getNumSignalStrengthLevels() + 1;
}
- return SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
+ return CellSignalStrength.getNumSignalStrengthLevels();
}
@Override
@@ -616,10 +618,19 @@ public class MobileSignalController extends SignalController<
notifyListenersIfNecessary();
}
+ private int getNrState(ServiceState serviceState) {
+ NetworkRegistrationInfo nri = serviceState.getNetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+ if (nri != null) {
+ return nri.getNrState();
+ }
+ return NetworkRegistrationInfo.NR_STATE_NONE;
+ }
+
private MobileIconGroup getNr5GIconGroup() {
if (mServiceState == null) return null;
- int nrState = mServiceState.getNrState();
+ int nrState = getNrState(mServiceState);
if (nrState == NetworkRegistrationInfo.NR_STATE_CONNECTED) {
// Check if the NR 5G is using millimeter wave and the icon is config.
if (mServiceState.getNrFrequencyRange() == ServiceState.FREQUENCY_RANGE_MMWAVE) {
@@ -772,12 +783,24 @@ public class MobileSignalController extends SignalController<
if (mDataNetType == TelephonyManager.NETWORK_TYPE_LTE) {
if (isCarrierSpecificDataIcon()) {
mCAPlus = true;
- } else if (mServiceState != null && mServiceState.isUsingCarrierAggregation()) {
+ } else if (mServiceState != null && isUsingCarrierAggregation(mServiceState)) {
mCA = true;
}
}
}
+ private boolean isUsingCarrierAggregation(ServiceState serviceState) {
+ NetworkRegistrationInfo nri = serviceState.getNetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+ if (nri != null) {
+ DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
+ if (dsri != null) {
+ return dsri.isUsingCarrierAggregation();
+ }
+ }
+ return false;
+ }
+
@Override
public void onDataActivity(int direction) {
if (DEBUG) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 6dd113377ce7..46143ca0dd24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -41,9 +41,9 @@ import android.os.Looper;
import android.os.PersistableBundle;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
+import android.telephony.CellSignalStrength;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
@@ -56,7 +56,6 @@ import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.TelephonyIntents;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.DemoMode;
import com.android.systemui.Dumpable;
@@ -605,7 +604,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
@VisibleForTesting
void doUpdateMobileControllers() {
List<SubscriptionInfo> subscriptions = mSubscriptionManager
- .getActiveSubscriptionInfoList(false);
+ .getActiveAndHiddenSubscriptionInfoList();
if (subscriptions == null) {
subscriptions = Collections.emptyList();
}
@@ -1035,7 +1034,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
if (level != null) {
controller.getState().level = level.equals("null") ? -1
: Math.min(Integer.parseInt(level),
- SignalStrength.NUM_SIGNAL_STRENGTH_BINS);
+ CellSignalStrength.getNumSignalStrengthLevels());
controller.getState().connected = controller.getState().level >= 0;
}
if (args.containsKey("inflate")) {
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index 47454cb5aca1..cfa2947eb862 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -129,8 +129,6 @@ public class Utils {
*/
public static boolean useQsMediaPlayer(Context context) {
int flag = Settings.System.getInt(context.getContentResolver(), "qs_media_player", 0);
- flag |= Settings.System.getInt(context.getContentResolver(), "npv_plugin_flag", 0);
-
return flag > 0;
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
index eccf09633f16..ea6cf3329772 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
@@ -249,7 +249,7 @@ public class CarrierTextControllerTest extends SysuiTestCase {
// STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the
// same answer as KeyguardUpdateMonitor. Remove when this is addressed
- when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(
+ when(mSubscriptionManager.getActiveAndHiddenSubscriptionInfoList()).thenReturn(
new ArrayList<>());
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 59eb6c59a2cd..795cbb92fefe 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -22,7 +22,6 @@ import static android.telephony.SubscriptionManager.NAME_SOURCE_DEFAULT;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -483,7 +482,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
List<SubscriptionInfo> list = new ArrayList<>();
list.add(TEST_SUBSCRIPTION);
list.add(TEST_SUBSCRIPTION_2);
- when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list);
+ when(mSubscriptionManager.getActiveAndHiddenSubscriptionInfoList()).thenReturn(list);
mKeyguardUpdateMonitor.mPhoneStateListener.onActiveDataSubscriptionIdChanged(
TEST_SUBSCRIPTION_2.getSubscriptionId());
mTestableLooper.processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index 0723a4ce74a4..f4cf314aa8fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -142,7 +142,7 @@ public class DozeMachineTest extends SysuiTestCase {
public void testPulseDone_goesToDoze() {
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
mMachine.requestState(INITIALIZED);
- mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
mMachine.requestState(DOZE_PULSE_DONE);
@@ -155,7 +155,7 @@ public class DozeMachineTest extends SysuiTestCase {
public void testPulseDone_goesToAoD() {
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
mMachine.requestState(INITIALIZED);
- mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
mMachine.requestState(DOZE_PULSE_DONE);
@@ -168,7 +168,7 @@ public class DozeMachineTest extends SysuiTestCase {
public void testPulseDone_afterDocked_goesToDockedAoD() {
when(mDockManager.isDocked()).thenReturn(true);
mMachine.requestState(INITIALIZED);
- mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
mMachine.requestState(DOZE_PULSE_DONE);
@@ -183,7 +183,7 @@ public class DozeMachineTest extends SysuiTestCase {
when(mDockManager.isDocked()).thenReturn(true);
when(mDockManager.isHidden()).thenReturn(true);
mMachine.requestState(INITIALIZED);
- mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
mMachine.requestState(DOZE_PULSE_DONE);
@@ -227,7 +227,7 @@ public class DozeMachineTest extends SysuiTestCase {
public void testWakeLock_heldInPulseStates() {
mMachine.requestState(INITIALIZED);
- mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
assertTrue(mWakeLockFake.isHeld());
mMachine.requestState(DOZE_PULSING);
@@ -250,7 +250,7 @@ public class DozeMachineTest extends SysuiTestCase {
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE);
- mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
mMachine.requestState(DOZE_PULSE_DONE);
@@ -262,9 +262,9 @@ public class DozeMachineTest extends SysuiTestCase {
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE);
- mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
- mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSE_DONE);
}
@@ -273,7 +273,7 @@ public class DozeMachineTest extends SysuiTestCase {
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE);
- mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSE_DONE);
}
@@ -286,7 +286,7 @@ public class DozeMachineTest extends SysuiTestCase {
return null;
}).when(mPartMock).transitionTo(any(), eq(DOZE_REQUEST_PULSE));
- mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
assertEquals(DOZE_PULSING, mMachine.getState());
}
@@ -295,9 +295,9 @@ public class DozeMachineTest extends SysuiTestCase {
public void testPulseReason_getMatchesRequest() {
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE);
- mMachine.requestPulse(DozeEvent.REASON_SENSOR_DOUBLE_TAP);
+ mMachine.requestPulse(DozeLog.REASON_SENSOR_DOUBLE_TAP);
- assertEquals(DozeEvent.REASON_SENSOR_DOUBLE_TAP, mMachine.getPulseReason());
+ assertEquals(DozeLog.REASON_SENSOR_DOUBLE_TAP, mMachine.getPulseReason());
}
@Test
@@ -309,7 +309,7 @@ public class DozeMachineTest extends SysuiTestCase {
if (newState == DOZE_REQUEST_PULSE
|| newState == DOZE_PULSING
|| newState == DOZE_PULSE_DONE) {
- assertEquals(DozeEvent.PULSE_REASON_NOTIFICATION, mMachine.getPulseReason());
+ assertEquals(DozeLog.PULSE_REASON_NOTIFICATION, mMachine.getPulseReason());
} else {
assertTrue("unexpected state " + newState,
newState == DOZE || newState == DOZE_AOD);
@@ -317,7 +317,7 @@ public class DozeMachineTest extends SysuiTestCase {
return null;
}).when(mPartMock).transitionTo(any(), any());
- mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
mMachine.requestState(DOZE_PULSE_DONE);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index 775acdf58c64..ff03fbae3f3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -115,14 +115,14 @@ public class DozeSensorsTest extends SysuiTestCase {
mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class));
mTestableLooper.processAllMessages();
- verify(mCallback).onSensorPulse(eq(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN),
+ verify(mCallback).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN),
anyFloat(), anyFloat(), eq(null));
mDozeSensors.requestTemporaryDisable();
reset(mCallback);
mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class));
mTestableLooper.processAllMessages();
- verify(mCallback, never()).onSensorPulse(eq(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN),
+ verify(mCallback, never()).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN),
anyFloat(), anyFloat(), eq(null));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index bf1060905f10..debc9d6430e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -165,10 +165,10 @@ public class DozeTriggersTest extends SysuiTestCase {
@Test
public void testProximitySensorNotAvailablel() {
mProximitySensor.setSensorAvailable(false);
- mTriggers.onSensor(DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS, 100, 100, null);
- mTriggers.onSensor(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, 100, 100,
+ mTriggers.onSensor(DozeLog.PULSE_REASON_SENSOR_LONG_PRESS, 100, 100, null);
+ mTriggers.onSensor(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, 100, 100,
new float[]{1});
- mTriggers.onSensor(DozeEvent.REASON_SENSOR_TAP, 100, 100, null);
+ mTriggers.onSensor(DozeLog.REASON_SENSOR_TAP, 100, 100, null);
}
private void waitForSensorManager() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/recents/model/TaskKeyLruCacheTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/recents/model/TaskKeyLruCacheTest.java
deleted file mode 100644
index de6c87c7ff01..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/recents/model/TaskKeyLruCacheTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shared.recents.model;
-
-
-import static junit.framework.TestCase.assertEquals;
-import static junit.framework.TestCase.assertNull;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@SmallTest
-@RunWith(MockitoJUnitRunner.class)
-public class TaskKeyLruCacheTest extends SysuiTestCase {
- private static int sCacheSize = 3;
- private static int sIdTask1 = 1;
- private static int sIdTask2 = 2;
- private static int sIdTask3 = 3;
- private static int sIdUser1 = 1;
-
- TaskKeyLruCache.EvictionCallback mEvictionCallback;
-
- TaskKeyLruCache<Integer> mCache;
- private Task.TaskKey mKey1;
- private Task.TaskKey mKey2;
- private Task.TaskKey mKey3;
-
- @Before
- public void setup() {
- mEvictionCallback = mock(TaskKeyLruCache.EvictionCallback.class);
- mCache = new TaskKeyLruCache<>(sCacheSize, mEvictionCallback);
-
- mKey1 = new Task.TaskKey(sIdTask1, 0, null, null, sIdUser1, System.currentTimeMillis());
- mKey2 = new Task.TaskKey(sIdTask2, 0, null, null, sIdUser1, System.currentTimeMillis());
- mKey3 = new Task.TaskKey(sIdTask3, 0, null, null, sIdUser1, System.currentTimeMillis());
- }
-
- @Test
- public void addSingleItem_get_success() {
- mCache.put(mKey1, 1);
-
- assertEquals(1, (int) mCache.get(mKey1));
- }
-
- @Test
- public void addSingleItem_getUninsertedItem_returnsNull() {
- mCache.put(mKey1, 1);
-
- assertNull(mCache.get(mKey2));
- }
-
- @Test
- public void emptyCache_get_returnsNull() {
- assertNull(mCache.get(mKey1));
- }
-
- @Test
- public void updateItem_get_returnsSecond() {
- mCache.put(mKey1, 1);
- mCache.put(mKey1, 2);
-
- assertEquals(2, (int) mCache.get(mKey1));
- assertEquals(1, mCache.mKeys.size());
- }
-
- @Test
- public void fillCache_put_evictsOldest() {
- mCache.put(mKey1, 1);
- mCache.put(mKey2, 2);
- mCache.put(mKey3, 3);
- Task.TaskKey key4 = new Task.TaskKey(sIdTask3 + 1, 0,
- null, null, sIdUser1, System.currentTimeMillis());
- mCache.put(key4, 4);
-
- assertNull(mCache.get(mKey1));
- assertEquals(3, mCache.mKeys.size());
- assertEquals(mKey2, mCache.mKeys.valueAt(0));
- verify(mEvictionCallback, times(1)).onEntryEvicted(mKey1);
- }
-
- @Test
- public void fillCache_remove_success() {
- mCache.put(mKey1, 1);
- mCache.put(mKey2, 2);
- mCache.put(mKey3, 3);
-
- mCache.remove(mKey2);
-
- assertNull(mCache.get(mKey2));
- assertEquals(2, mCache.mKeys.size());
- verify(mEvictionCallback, times(0)).onEntryEvicted(mKey2);
- }
-
- @Test
- public void put_evictionCallback_notCalled() {
- mCache.put(mKey1, 1);
- verify(mEvictionCallback, times(0)).onEntryEvicted(mKey1);
- }
-
- @Test
- public void evictAll_evictionCallback_called() {
- mCache.put(mKey1, 1);
- mCache.evictAllCache();
- verify(mEvictionCallback, times(1)).onEntryEvicted(mKey1);
- }
-
- @Test
- public void trimAll_evictionCallback_called() {
- mCache.put(mKey1, 1);
- mCache.put(mKey2, 2);
- mCache.trimToSize(-1);
- verify(mEvictionCallback, times(1)).onEntryEvicted(mKey1);
- verify(mEvictionCallback, times(1)).onEntryEvicted(mKey2);
-
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 3c6a69882d44..a6e29181e435 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -36,7 +36,6 @@ import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
-import com.android.systemui.doze.DozeEvent;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -144,13 +143,13 @@ public class DozeServiceHostTest extends SysuiTestCase {
@Override
public void onPulseFinished() {
}
- }, DozeEvent.PULSE_REASON_NOTIFICATION);
+ }, DozeLog.PULSE_REASON_NOTIFICATION);
ArgumentCaptor<DozeHost.PulseCallback> pulseCallbackArgumentCaptor =
ArgumentCaptor.forClass(DozeHost.PulseCallback.class);
verify(mDozeScrimController).pulse(
- pulseCallbackArgumentCaptor.capture(), eq(DozeEvent.PULSE_REASON_NOTIFICATION));
+ pulseCallbackArgumentCaptor.capture(), eq(DozeLog.PULSE_REASON_NOTIFICATION));
verify(mStatusBar).updateScrimController();
reset(mStatusBar);
@@ -162,21 +161,21 @@ public class DozeServiceHostTest extends SysuiTestCase {
@Test
public void testPulseWhileDozing_notifyAuthInterrupt() {
HashSet<Integer> reasonsWantingAuth = new HashSet<>(
- Collections.singletonList(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN));
+ Collections.singletonList(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN));
HashSet<Integer> reasonsSkippingAuth = new HashSet<>(
- Arrays.asList(DozeEvent.PULSE_REASON_INTENT,
- DozeEvent.PULSE_REASON_NOTIFICATION,
- DozeEvent.PULSE_REASON_SENSOR_SIGMOTION,
- DozeEvent.REASON_SENSOR_PICKUP,
- DozeEvent.REASON_SENSOR_DOUBLE_TAP,
- DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS,
- DozeEvent.PULSE_REASON_DOCKING,
- DozeEvent.REASON_SENSOR_WAKE_UP,
- DozeEvent.REASON_SENSOR_TAP));
+ Arrays.asList(DozeLog.PULSE_REASON_INTENT,
+ DozeLog.PULSE_REASON_NOTIFICATION,
+ DozeLog.PULSE_REASON_SENSOR_SIGMOTION,
+ DozeLog.REASON_SENSOR_PICKUP,
+ DozeLog.REASON_SENSOR_DOUBLE_TAP,
+ DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
+ DozeLog.PULSE_REASON_DOCKING,
+ DozeLog.REASON_SENSOR_WAKE_UP,
+ DozeLog.REASON_SENSOR_TAP));
HashSet<Integer> reasonsThatDontPulse = new HashSet<>(
- Arrays.asList(DozeEvent.REASON_SENSOR_PICKUP,
- DozeEvent.REASON_SENSOR_DOUBLE_TAP,
- DozeEvent.REASON_SENSOR_TAP));
+ Arrays.asList(DozeLog.REASON_SENSOR_PICKUP,
+ DozeLog.REASON_SENSOR_DOUBLE_TAP,
+ DozeLog.REASON_SENSOR_TAP));
doAnswer(invocation -> {
DozeHost.PulseCallback callback = invocation.getArgument(0);
@@ -185,7 +184,7 @@ public class DozeServiceHostTest extends SysuiTestCase {
}).when(mDozeScrimController).pulse(any(), anyInt());
mDozeServiceHost.mWakeLockScreenPerformsAuth = true;
- for (int i = 0; i < DozeEvent.TOTAL_REASONS; i++) {
+ for (int i = 0; i < DozeLog.TOTAL_REASONS; i++) {
reset(mKeyguardUpdateMonitor);
mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class), i);
if (reasonsWantingAuth.contains(i)) {
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 1f37ad8b2b1c..5fb71599e2a0 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
@@ -55,7 +55,6 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.KeyguardAffordanceView;
@@ -133,8 +132,6 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Mock
private DynamicPrivacyController mDynamicPrivacyController;
@Mock
- private PluginManager mPluginManager;
- @Mock
private ShadeController mShadeController;
@Mock
private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
@@ -218,7 +215,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mNotificationPanelViewController = new NotificationPanelViewController(mView,
mInjectionInflationController,
coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController,
- mFalsingManager, mPluginManager, mShadeController,
+ mFalsingManager, mShadeController,
mNotificationLockscreenUserManager, mNotificationEntryManager,
mKeyguardStateController, mStatusBarStateController, mDozeLog,
mDozeParameters, mCommandQueue, mVibratorHelper,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index cc3c3ccdc316..294d546e087b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -30,6 +30,7 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -43,6 +44,7 @@ import android.os.Handler;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.telephony.CdmaEriInformation;
+import android.telephony.CellSignalStrength;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
@@ -56,7 +58,6 @@ import android.util.Log;
import androidx.test.InstrumentationRegistry;
-import com.android.internal.telephony.cdma.EriInfo;
import com.android.settingslib.graph.SignalDrawable;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.R;
@@ -95,6 +96,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
protected PhoneStateListener mPhoneStateListener;
protected SignalStrength mSignalStrength;
protected ServiceState mServiceState;
+ protected NetworkRegistrationInfo mFakeRegInfo;
protected ConnectivityManager mMockCm;
protected WifiManager mMockWm;
protected SubscriptionManager mMockSm;
@@ -158,6 +160,14 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
mSignalStrength = mock(SignalStrength.class);
mServiceState = mock(ServiceState.class);
+ mFakeRegInfo = new NetworkRegistrationInfo.Builder()
+ .setTransportType(TRANSPORT_TYPE_WWAN)
+ .setDomain(DOMAIN_PS)
+ .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+ .build();
+ doReturn(mFakeRegInfo).when(mServiceState)
+ .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
+
mEriInformation = new CdmaEriInformation(CdmaEriInformation.ERI_OFF,
CdmaEriInformation.ERI_ICON_MODE_NORMAL);
when(mMockTm.getCdmaEriInformation()).thenReturn(mEriInformation);
@@ -219,7 +229,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
subs.add(subscription);
}
when(mMockSm.getActiveSubscriptionInfoList()).thenReturn(subs);
- when(mMockSm.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(subs);
+ when(mMockSm.getActiveAndHiddenSubscriptionInfoList()).thenReturn(subs);
mNetworkController.doUpdateMobileControllers();
}
@@ -405,7 +415,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
typeIconArg.capture(), dataInArg.capture(), dataOutArg.capture(),
anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean());
IconState iconState = iconArg.getValue();
- int state = SignalDrawable.getState(icon, SignalStrength.NUM_SIGNAL_STRENGTH_BINS,
+ int state = SignalDrawable.getState(icon, CellSignalStrength.getNumSignalStrengthLevels(),
false);
assertEquals("Visibility in, quick settings", visible, iconState.visible);
assertEquals("Signal icon in, quick settings", state, iconState.icon);
@@ -440,7 +450,8 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
IconState iconState = iconArg.getValue();
int state = icon == -1 ? 0
- : SignalDrawable.getState(icon, SignalStrength.NUM_SIGNAL_STRENGTH_BINS, !inet);
+ : SignalDrawable.getState(icon, CellSignalStrength.getNumSignalStrengthLevels(),
+ !inet);
assertEquals("Signal icon in status bar", state, iconState.icon);
assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue());
assertEquals("Visibility in status bar", visible, iconState.visible);
@@ -483,7 +494,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
IconState iconState = iconArg.getValue();
- int numSignalStrengthBins = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
+ int numSignalStrengthBins = CellSignalStrength.getNumSignalStrengthLevels();
if (mMobileSignalController.mInflateSignalStrengths) {
numSignalStrengthBins++;
icon++;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index f6c750db56b7..1eb59396e525 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -187,7 +187,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
TelephonyManager.NETWORK_TYPE_LTE);
updateDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT);
ServiceState ss = Mockito.mock(ServiceState.class);
- doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(ss).getNrState();
+ setNrState(ss, NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED);
mPhoneStateListener.onServiceStateChanged(ss);
verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, TelephonyIcons.ICON_5G,
@@ -202,7 +202,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
TelephonyManager.NETWORK_TYPE_LTE);
updateDataActivity(TelephonyManager.DATA_ACTIVITY_DORMANT);
ServiceState ss = Mockito.mock(ServiceState.class);
- doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(ss).getNrState();
+ setNrState(ss, NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED);
mPhoneStateListener.onServiceStateChanged(ss);
verifyDataIndicators(TelephonyIcons.ICON_5G);
@@ -215,7 +215,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
ServiceState ss = Mockito.mock(ServiceState.class);
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState();
+ setNrState(ss, NetworkRegistrationInfo.NR_STATE_CONNECTED);
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange();
mPhoneStateListener.onServiceStateChanged(ss);
@@ -229,7 +229,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
ServiceState ss = Mockito.mock(ServiceState.class);
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState();
+ setNrState(ss, NetworkRegistrationInfo.NR_STATE_CONNECTED);
doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(ss).getNrFrequencyRange();
mPhoneStateListener.onServiceStateChanged(ss);
@@ -243,7 +243,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
ServiceState ss = Mockito.mock(ServiceState.class);
- doReturn(NetworkRegistrationInfo.NR_STATE_RESTRICTED).when(ss).getNrState();
+ setNrState(ss, NetworkRegistrationInfo.NR_STATE_RESTRICTED);
mPhoneStateListener.onServiceStateChanged(mServiceState);
verifyDataIndicators(TelephonyIcons.ICON_LTE);
@@ -259,7 +259,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
ServiceState ss = Mockito.mock(ServiceState.class);
// While nrIconDisplayGracePeriodMs > 0 & is Nr5G, mIsShowingIconGracefully should be true
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState();
+ setNrState(ss, NetworkRegistrationInfo.NR_STATE_CONNECTED);
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
@@ -278,7 +278,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
assertTrue(mConfig.nrIconDisplayGracePeriodMs == 0);
// While nrIconDisplayGracePeriodMs <= 0, mIsShowingIconGracefully should be false
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+ setNrState(mServiceState, NetworkRegistrationInfo.NR_STATE_CONNECTED);
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
@@ -295,7 +295,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
mPhoneStateListener.onServiceStateChanged(mServiceState);
ServiceState ss = Mockito.mock(ServiceState.class);
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState();
+ setNrState(ss, NetworkRegistrationInfo.NR_STATE_CONNECTED);
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
@@ -305,7 +305,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
// Enabled timer Nr5G switch to None Nr5G, showing 5G icon gracefully
ServiceState ssLte = Mockito.mock(ServiceState.class);
- doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(ssLte).getNrState();
+ setNrState(ssLte, NetworkRegistrationInfo.NR_STATE_NONE);
doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ssLte).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
@@ -321,14 +321,14 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
setupDefaultSignal();
mNetworkController.handleConfigurationChanged();
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+ setNrState(mServiceState, NetworkRegistrationInfo.NR_STATE_CONNECTED);
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
verifyDataIndicators(TelephonyIcons.ICON_5G);
- doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+ setNrState(mServiceState, NetworkRegistrationInfo.NR_STATE_NONE);
doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
@@ -342,7 +342,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds();
setupDefaultSignal();
mNetworkController.handleConfigurationChanged();
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+ setNrState(mServiceState, NetworkRegistrationInfo.NR_STATE_CONNECTED);
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
@@ -352,7 +352,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
// Disabled timer, when out of service, reset timer to display latest state
updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
- doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+ setNrState(mServiceState, NetworkRegistrationInfo.NR_STATE_NONE);
doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_DISCONNECTED,
TelephonyManager.NETWORK_TYPE_UMTS);
@@ -369,7 +369,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
mPhoneStateListener.onServiceStateChanged(mServiceState);
ServiceState ss5G = Mockito.mock(ServiceState.class);
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5G).getNrState();
+ setNrState(ss5G, NetworkRegistrationInfo.NR_STATE_CONNECTED);
doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss5G).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
@@ -379,7 +379,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
// When timeout enabled, 5G/5G+ switching should be updated immediately
ServiceState ss5GPlus = Mockito.mock(ServiceState.class);
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5GPlus).getNrState();
+ setNrState(ss5GPlus, NetworkRegistrationInfo.NR_STATE_CONNECTED);
doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(ss5GPlus).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
@@ -396,22 +396,21 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
mNetworkController.handleConfigurationChanged();
mPhoneStateListener.onServiceStateChanged(mServiceState);
- ServiceState ss5G = Mockito.mock(ServiceState.class);
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5G).getNrState();
- doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss5G).getNrFrequencyRange();
+ ServiceState ss = Mockito.mock(ServiceState.class);
+ setNrState(ss, NetworkRegistrationInfo.NR_STATE_CONNECTED);
+ doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
- mPhoneStateListener.onServiceStateChanged(ss5G);
+ mPhoneStateListener.onServiceStateChanged(ss);
verifyDataIndicators(TelephonyIcons.ICON_5G);
// State from NR_5G to NONE NR_5G with timeout, should show previous 5G icon
- ServiceState ssLte = Mockito.mock(ServiceState.class);
- doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(ssLte).getNrState();
- doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ssLte).getNrFrequencyRange();
+ setNrState(ss, NetworkRegistrationInfo.NR_STATE_NONE);
+ doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ss).getNrFrequencyRange();
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
- mPhoneStateListener.onServiceStateChanged(ssLte);
+ mPhoneStateListener.onServiceStateChanged(ss);
verifyDataIndicators(TelephonyIcons.ICON_5G);
@@ -420,14 +419,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
mNetworkController.handleConfigurationChanged();
// State from NR_5G to NONE NR_STATE_RESTRICTED, showing corresponding icon
- doReturn(NetworkRegistrationInfo.NR_STATE_RESTRICTED).when(mServiceState).getNrState();
- NetworkRegistrationInfo fakeRegInfo = new NetworkRegistrationInfo.Builder()
- .setTransportType(TRANSPORT_TYPE_WWAN)
- .setDomain(DOMAIN_PS)
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
- .build();
- doReturn(fakeRegInfo).when(mServiceState)
- .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
+ setNrState(ss, NetworkRegistrationInfo.NR_STATE_RESTRICTED);
mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_LTE);
@@ -531,4 +523,10 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
true, DEFAULT_QS_SIGNAL_STRENGTH, dataIcon, false,
false);
}
+
+ private void setNrState(ServiceState ss, int nrState) {
+ mFakeRegInfo.setNrState(nrState);
+ doReturn(mFakeRegInfo).when(ss)
+ .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 4406248ec9ea..f52c8c17bfa5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -136,7 +136,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
@Test
public void testSignalStrength() {
for (int testStrength = 0;
- testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) {
+ testStrength < CellSignalStrength.getNumSignalStrengthLevels(); testStrength++) {
setupDefaultSignal();
setLevel(testStrength);
@@ -153,7 +153,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
@Test
public void testCdmaSignalStrength() {
for (int testStrength = 0;
- testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) {
+ testStrength < CellSignalStrength.getNumSignalStrengthLevels(); testStrength++) {
setupDefaultSignal();
setCdma();
setLevel(testStrength);
@@ -167,7 +167,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
@Test
public void testSignalRoaming() {
for (int testStrength = 0;
- testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) {
+ testStrength < CellSignalStrength.getNumSignalStrengthLevels(); testStrength++) {
setupDefaultSignal();
setGsmRoaming(true);
setLevel(testStrength);
@@ -494,7 +494,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
// Carrier network change is true, show special indicator
verifyLastMobileDataIndicators(true /* visible */,
- SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+ SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()),
0 /* typeIcon */);
// Revert back
@@ -525,7 +525,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
// Carrier network change is true, show special indicator, no roaming.
verifyLastMobileDataIndicators(true /* visible */,
- SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+ SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()),
0 /* typeIcon */,
false /* roaming */);
@@ -557,7 +557,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
// Carrier network change is true, show special indicator, no roaming.
verifyLastMobileDataIndicators(true /* visible */,
- SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+ SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()),
0 /* typeIcon */,
false /* roaming */);
@@ -565,7 +565,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
// Roaming should not show.
verifyLastMobileDataIndicators(true /* visible */,
- SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+ SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()),
0 /* typeIcon */,
false /* roaming */);
diff --git a/packages/WAPPushManager/Android.bp b/packages/WAPPushManager/Android.bp
index 083dac944936..cd804b2c8514 100644
--- a/packages/WAPPushManager/Android.bp
+++ b/packages/WAPPushManager/Android.bp
@@ -4,7 +4,6 @@ android_app {
name: "WAPPushManager",
srcs: ["src/**/*.java"],
platform_apis: true,
- libs: ["telephony-common"],
static_libs: ["android-common"],
optimize: {
proguard_flags_files: ["proguard.flags"],
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index e28ef0f920e9..4f18f3547449 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -216,7 +216,7 @@ final class AutofillManagerServiceImpl
updateRemoteAugmentedAutofillService();
final ComponentName componentName = RemoteInlineSuggestionRenderService
- .getServiceComponentName(getContext());
+ .getServiceComponentName(getContext(), mUserId);
if (componentName != null) {
mRemoteInlineSuggestionRenderService = new RemoteInlineSuggestionRenderService(
getContext(), componentName, InlineSuggestionRenderService.SERVICE_INTERFACE,
diff --git a/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java b/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java
index f9e08e683b6c..31dc23f0118d 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java
@@ -20,6 +20,7 @@ import static com.android.server.autofill.Helper.sVerbose;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -86,7 +87,7 @@ final class RemoteInlineSuggestionRenderService extends
}
@Nullable
- private static ServiceInfo getServiceInfo(Context context) {
+ private static ServiceInfo getServiceInfo(Context context, int userId) {
final String packageName =
context.getPackageManager().getServicesSystemSharedLibraryPackageName();
if (packageName == null) {
@@ -96,8 +97,8 @@ final class RemoteInlineSuggestionRenderService extends
final Intent intent = new Intent(InlineSuggestionRenderService.SERVICE_INTERFACE);
intent.setPackage(packageName);
- final ResolveInfo resolveInfo = context.getPackageManager().resolveService(intent,
- PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+ final ResolveInfo resolveInfo = context.getPackageManager().resolveServiceAsUser(intent,
+ PackageManager.GET_SERVICES | PackageManager.GET_META_DATA, userId);
final ServiceInfo serviceInfo = resolveInfo == null ? null : resolveInfo.serviceInfo;
if (resolveInfo == null || serviceInfo == null) {
Slog.w(TAG, "No valid components found.");
@@ -115,8 +116,8 @@ final class RemoteInlineSuggestionRenderService extends
}
@Nullable
- public static ComponentName getServiceComponentName(Context context) {
- final ServiceInfo serviceInfo = getServiceInfo(context);
+ public static ComponentName getServiceComponentName(Context context, @UserIdInt int userId) {
+ final ServiceInfo serviceInfo = getServiceInfo(context, userId);
if (serviceInfo == null) return null;
final ComponentName componentName = new ComponentName(serviceInfo.packageName,
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java b/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java
index 6a1de6378a5e..205b7dda267e 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java
@@ -16,7 +16,6 @@
package com.android.server.backup;
-import static com.android.server.backup.BackupManagerService.DEBUG;
import static com.android.server.backup.BackupManagerService.TAG;
import android.util.Slog;
@@ -33,10 +32,13 @@ final class UserBackupManagerFilePersistedSettings {
private static final String BACKUP_ENABLE_FILE = "backup_enabled";
static boolean readBackupEnableState(int userId) {
- return readBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId));
+ boolean enabled = readBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId));
+ Slog.d(TAG, "user:" + userId + " readBackupEnableState enabled:" + enabled);
+ return enabled;
}
static void writeBackupEnableState(int userId, boolean enable) {
+ Slog.d(TAG, "user:" + userId + " writeBackupEnableState enable:" + enable);
writeBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId), enable);
}
@@ -45,15 +47,17 @@ final class UserBackupManagerFilePersistedSettings {
if (enableFile.exists()) {
try (FileInputStream fin = new FileInputStream(enableFile)) {
int state = fin.read();
+ if (state != 0 && state != 1) {
+ // TODO (b/148587496) handle instead of only logging
+ Slog.e(TAG, "Unexpected enabled state:" + state);
+ }
return state != 0;
} catch (IOException e) {
// can't read the file; fall through to assume disabled
Slog.e(TAG, "Cannot read enable state; assuming disabled");
}
} else {
- if (DEBUG) {
- Slog.i(TAG, "isBackupEnabled() => false due to absent settings file");
- }
+ Slog.i(TAG, "isBackupEnabled() => false due to absent settings file");
}
return false;
}
@@ -64,7 +68,11 @@ final class UserBackupManagerFilePersistedSettings {
try (FileOutputStream fout = new FileOutputStream(stage)) {
fout.write(enable ? 1 : 0);
fout.close();
- stage.renameTo(enableFile);
+ boolean renamed = stage.renameTo(enableFile);
+ if (!renamed) {
+ // TODO (b/148587496) handle instead of only logging
+ Slog.e(TAG, "Write enable failed as could not rename staging file to actual");
+ }
// will be synced immediately by the try-with-resources call to close()
} catch (IOException | RuntimeException e) {
Slog.e(
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 3bc93cc13023..e342dd7977fb 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -649,7 +649,7 @@ public class LocationManagerService extends ILocationManager.Stub {
mEnabled = new SparseArray<>(1);
// initialize last since this lets our reference escape
- mProvider = new MockableLocationProvider(mContext, mLock, this);
+ mProvider = new MockableLocationProvider(mLock, this);
// we can assume all users start with disabled location state since the initial state
// of all providers is disabled. no need to initialize mEnabled further.
@@ -2699,7 +2699,7 @@ public class LocationManagerService extends ILocationManager.Stub {
mProviderManagers.add(manager);
}
- manager.setMockProvider(new MockProvider(mContext, properties));
+ manager.setMockProvider(new MockProvider(properties));
}
}
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index 9b1326bc88d7..043f657b7f2c 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -128,13 +128,15 @@ public class MmsServiceBroker extends SystemService {
@Override
public void sendMessage(int subId, String callingPkg, Uri contentUri, String locationUrl,
- Bundle configOverrides, PendingIntent sentIntent) throws RemoteException {
+ Bundle configOverrides, PendingIntent sentIntent, long messageId)
+ throws RemoteException {
returnPendingIntentWithError(sentIntent);
}
@Override
public void downloadMessage(int subId, String callingPkg, String locationUrl,
- Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent)
+ Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent,
+ long messageId)
throws RemoteException {
returnPendingIntentWithError(downloadedIntent);
}
@@ -329,7 +331,8 @@ public class MmsServiceBroker extends SystemService {
@Override
public void sendMessage(int subId, String callingPkg, Uri contentUri,
- String locationUrl, Bundle configOverrides, PendingIntent sentIntent)
+ String locationUrl, Bundle configOverrides, PendingIntent sentIntent,
+ long messageId)
throws RemoteException {
Slog.d(TAG, "sendMessage() by " + callingPkg);
mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send MMS message");
@@ -343,13 +346,13 @@ public class MmsServiceBroker extends SystemService {
Intent.FLAG_GRANT_READ_URI_PERMISSION,
subId);
getServiceGuarded().sendMessage(subId, callingPkg, contentUri, locationUrl,
- configOverrides, sentIntent);
+ configOverrides, sentIntent, messageId);
}
@Override
public void downloadMessage(int subId, String callingPkg, String locationUrl,
Uri contentUri, Bundle configOverrides,
- PendingIntent downloadedIntent) throws RemoteException {
+ PendingIntent downloadedIntent, long messageId) throws RemoteException {
Slog.d(TAG, "downloadMessage() by " + callingPkg);
mContext.enforceCallingPermission(Manifest.permission.RECEIVE_MMS,
"Download MMS message");
@@ -364,7 +367,7 @@ public class MmsServiceBroker extends SystemService {
subId);
getServiceGuarded().downloadMessage(subId, callingPkg, locationUrl, contentUri,
- configOverrides, downloadedIntent);
+ configOverrides, downloadedIntent, messageId);
}
@Override
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index a04f25b0d20c..e17dde9a766e 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -24,6 +24,7 @@ import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.OP_LEGACY_STORAGE;
+import static android.app.AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.OP_REQUEST_INSTALL_PACKAGES;
import static android.app.AppOpsManager.OP_WRITE_EXTERNAL_STORAGE;
@@ -4320,21 +4321,37 @@ class StorageManagerService extends IStorageManager.Stub
return true;
}
- public void onAppOpsChanged(int code, int uid,
- @Nullable String packageName, int mode) {
- if (code == OP_REQUEST_INSTALL_PACKAGES && mIsFuseEnabled) {
- // When using FUSE, we basically have no other choice but to kill the app
- // after the app op is either granted or rejected.
- final IActivityManager am = ActivityManager.getService();
- try {
- am.killApplication(packageName,
- UserHandle.getAppId(uid),
- UserHandle.USER_ALL, AppOpsManager.opToName(code) + " changed.");
- } catch (RemoteException e) {
- }
+ private void killAppForOpChange(int code, int uid, String packageName) {
+ final IActivityManager am = ActivityManager.getService();
+ try {
+ am.killApplication(packageName,
+ UserHandle.getAppId(uid),
+ UserHandle.USER_ALL, AppOpsManager.opToName(code) + " changed.");
+ } catch (RemoteException e) {
+ }
+ }
- return;
+ public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode) {
+ if (mIsFuseEnabled) {
+ // When using FUSE, we may need to kill the app if the op changes
+ switch(code) {
+ case OP_REQUEST_INSTALL_PACKAGES:
+ // Always kill regardless of op change, to remount apps /storage
+ killAppForOpChange(code, uid, packageName);
+ return;
+ case OP_MANAGE_EXTERNAL_STORAGE:
+ if (mode != MODE_ALLOWED) {
+ // Only kill if op is denied, to lose external_storage gid
+ // Killing when op is granted to pickup the gid automatically, results
+ // in a bad UX, especially since the gid only gives access to unreliable
+ // volumes, USB OTGs that are rarely mounted. The app will get the
+ // external_storage gid on next organic restart.
+ killAppForOpChange(code, uid, packageName);
+ return;
+ }
+ }
}
+
if (mode == MODE_ALLOWED && (code == OP_READ_EXTERNAL_STORAGE
|| code == OP_WRITE_EXTERNAL_STORAGE
|| code == OP_REQUEST_INSTALL_PACKAGES)) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index d7201054dea6..4a65a96e57a1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -438,14 +438,15 @@ final class ActivityManagerConstants extends ContentObserver {
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
ActivityThread.currentApplication().getMainExecutor(),
mOnDeviceConfigChangedListener);
- updateMaxCachedProcesses();
+ loadDeviceConfigConstants();
+ // The following read from Settings.
updateActivityStartsLoggingEnabled();
- updateBackgroundActivityStarts();
- updateForceRestrictedBackgroundCheck();
updateForegroundServiceStartsLoggingEnabled();
- updateBackgroundFgsStartsRestriction();
- updateOomAdjUpdatePolicy();
- updateImperceptibleKillExemptions();
+ }
+
+ private void loadDeviceConfigConstants() {
+ mOnDeviceConfigChangedListener.onPropertiesChanged(
+ DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER));
}
public void setOverrideMaxCachedProcesses(int value) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2b160dddedbb..a2209e848ccd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9763,15 +9763,21 @@ public class ActivityManagerService extends IActivityManager.Stub
* @param crashInfo describing the context of the error
* @return true if the process should exit immediately (WTF is fatal)
*/
+ @Override
public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
- final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
+ final ApplicationErrorReport.ParcelableCrashInfo crashInfo, int immediateCallerPid) {
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
- if (system) {
- // If this is coming from the system, we could very well have low-level
- // system locks held, so we want to do this all asynchronously. And we
- // never want this to become fatal, so there is that too.
+ // If this is coming from the system, we could very well have low-level
+ // system locks held, so we want to do this all asynchronously. And we
+ // never want this to become fatal, so there is that too.
+ //
+ // Note: "callingPid == Process.myPid())" wouldn't be reliable because even if the caller
+ // is within the system server, if it calls Log.wtf() without clearning the calling
+ // identity, callingPid would still be of a remote caller. So we explicltly pass the
+ // process PID from the caller.
+ if (system || (immediateCallerPid == Process.myPid())) {
mHandler.post(new Runnable() {
@Override public void run() {
handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 77e83bdfeb32..531bc5d1c7df 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -88,7 +88,6 @@ import android.hardware.camera2.CameraDevice.CAMERA_AUDIO_RESTRICTION;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -2062,12 +2061,6 @@ public class AppOpsService extends IAppOpsService.Stub {
}
private void updatePermissionRevokedCompat(int uid, int switchCode, int mode) {
- PackageManagerInternal packageManagerInternal = LocalServices.getService(
- PackageManagerInternal.class);
- if (packageManagerInternal.getUidTargetSdkVersion(uid) >= Build.VERSION_CODES.M) {
- return;
- }
-
PackageManager packageManager = mContext.getPackageManager();
String[] packageNames = packageManager.getPackagesForUid(uid);
if (ArrayUtils.isEmpty(packageNames)) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 2c415570d5fa..25c761ab80ec 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -188,14 +188,14 @@ public class NetworkNotificationManager {
int icon = getIcon(transportType, notifyType);
if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) {
title = r.getString(R.string.wifi_no_internet,
- WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()));
+ WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
details = r.getString(R.string.wifi_no_internet_detailed);
} else if (notifyType == NotificationType.PRIVATE_DNS_BROKEN) {
if (transportType == TRANSPORT_CELLULAR) {
title = r.getString(R.string.mobile_no_internet);
} else if (transportType == TRANSPORT_WIFI) {
title = r.getString(R.string.wifi_no_internet,
- WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()));
+ WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
} else {
title = r.getString(R.string.other_networks_no_internet);
}
@@ -203,19 +203,19 @@ public class NetworkNotificationManager {
} else if (notifyType == NotificationType.PARTIAL_CONNECTIVITY
&& transportType == TRANSPORT_WIFI) {
title = r.getString(R.string.network_partial_connectivity,
- WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()));
+ WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
details = r.getString(R.string.network_partial_connectivity_detailed);
} else if (notifyType == NotificationType.LOST_INTERNET &&
transportType == TRANSPORT_WIFI) {
title = r.getString(R.string.wifi_no_internet,
- WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()));
+ WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
details = r.getString(R.string.wifi_no_internet_detailed);
} else if (notifyType == NotificationType.SIGN_IN) {
switch (transportType) {
case TRANSPORT_WIFI:
title = r.getString(R.string.wifi_available_sign_in, 0);
details = r.getString(R.string.network_available_sign_in_detailed,
- WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()));
+ WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
break;
case TRANSPORT_CELLULAR:
title = r.getString(R.string.network_available_sign_in, 0);
@@ -236,7 +236,7 @@ public class NetworkNotificationManager {
break;
}
} else if (notifyType == NotificationType.LOGGED_IN) {
- title = WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID());
+ title = WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID());
details = r.getString(R.string.captive_portal_logged_in_detailed);
} else if (notifyType == NotificationType.NETWORK_SWITCH) {
String fromTransport = getTransportName(transportType);
diff --git a/services/core/java/com/android/server/location/AbstractLocationProvider.java b/services/core/java/com/android/server/location/AbstractLocationProvider.java
index 64bca78f294d..997f21c9b6a3 100644
--- a/services/core/java/com/android/server/location/AbstractLocationProvider.java
+++ b/services/core/java/com/android/server/location/AbstractLocationProvider.java
@@ -177,7 +177,6 @@ public abstract class AbstractLocationProvider {
}
}
- protected final Context mContext;
protected final Executor mExecutor;
// we use a lock-free implementation to update state to ensure atomicity between updating the
@@ -186,13 +185,11 @@ public abstract class AbstractLocationProvider {
// before it was set, and should not miss any updates that occur after it was set).
private final AtomicReference<InternalState> mInternalState;
- protected AbstractLocationProvider(Context context, Executor executor) {
- this(context, executor, Collections.singleton(context.getPackageName()));
+ protected AbstractLocationProvider(Executor executor, Context context) {
+ this(executor, Collections.singleton(context.getPackageName()));
}
- protected AbstractLocationProvider(Context context, Executor executor,
- Set<String> packageNames) {
- mContext = context;
+ protected AbstractLocationProvider(Executor executor, Set<String> packageNames) {
mExecutor = executor;
mInternalState = new AtomicReference<>(
new InternalState(null, State.EMPTY_STATE.withProviderPackageNames(packageNames)));
@@ -202,7 +199,7 @@ public abstract class AbstractLocationProvider {
* Sets the listener and returns the state at the moment the listener was set. The listener can
* expect to receive all state updates from after this point.
*/
- State setListener(@Nullable Listener listener) {
+ protected State setListener(@Nullable Listener listener) {
return mInternalState.updateAndGet(
internalState -> internalState.withListener(listener)).state;
}
@@ -210,14 +207,14 @@ public abstract class AbstractLocationProvider {
/**
* Retrieves the state of the provider.
*/
- State getState() {
+ public State getState() {
return mInternalState.get().state;
}
/**
* Sets the state of the provider to the new state.
*/
- void setState(State newState) {
+ protected void setState(State newState) {
InternalState oldInternalState = mInternalState.getAndUpdate(
internalState -> internalState.withState(newState));
if (newState.equals(oldInternalState.state)) {
@@ -357,7 +354,7 @@ public abstract class AbstractLocationProvider {
/**
* Always invoked on the provider executor.
*/
- protected void onExtraCommand(int uid, int pid, String command, Bundle extras) {}
+ protected abstract void onExtraCommand(int uid, int pid, String command, Bundle extras);
/**
* Requests a provider to enable itself for the given user id.
@@ -370,7 +367,7 @@ public abstract class AbstractLocationProvider {
/**
* Always invoked on the provider executor.
*/
- protected void onRequestSetAllowed(boolean allowed) {}
+ protected abstract void onRequestSetAllowed(boolean allowed);
/**
* Dumps debug or log information. May be invoked from any thread.
diff --git a/services/core/java/com/android/server/location/GnssConfiguration.java b/services/core/java/com/android/server/location/GnssConfiguration.java
index 86a84e312899..b3546dc79572 100644
--- a/services/core/java/com/android/server/location/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/GnssConfiguration.java
@@ -23,7 +23,8 @@ import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
-import android.util.StatsLog;
+
+import com.android.internal.util.FrameworkStatsLog;
import libcore.io.IoUtils;
@@ -283,7 +284,7 @@ class GnssConfiguration {
}
private void logConfigurations() {
- StatsLog.write(StatsLog.GNSS_CONFIGURATION_REPORTED,
+ FrameworkStatsLog.write(FrameworkStatsLog.GNSS_CONFIGURATION_REPORTED,
getSuplHost(),
getSuplPort(0),
getC2KHost(),
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 62fa5ec82aea..bcac4730cb8b 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -63,7 +63,6 @@ import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
import android.util.Log;
-import android.util.StatsLog;
import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
@@ -74,6 +73,7 @@ import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
import com.android.internal.location.ProviderProperties;
import com.android.internal.location.ProviderRequest;
import com.android.internal.location.gnssmetrics.GnssMetrics;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.server.DeviceIdleInternal;
import com.android.server.FgThread;
import com.android.server.LocalServices;
@@ -408,7 +408,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
// Available only on GNSS HAL 2.0 implementations and later.
private GnssVisibilityControl mGnssVisibilityControl;
- // Handler for processing events
+ private final Context mContext;
private Handler mHandler;
private final GnssNetworkConnectivityHandler mNetworkConnectivityHandler;
@@ -625,10 +625,11 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
}
public GnssLocationProvider(Context context) {
- super(context, FgThread.getExecutor());
+ super(FgThread.getExecutor(), context);
ensureInitialized();
+ mContext = context;
mLooper = FgThread.getHandler().getLooper();
// Create a wake lock
@@ -1212,6 +1213,11 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
}
}
+ @Override
+ protected void onRequestSetAllowed(boolean allowed) {
+ // do nothing - the gnss provider is always allowed
+ }
+
private void deleteAidingData(Bundle extras) {
int flags;
@@ -1825,8 +1831,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
}
native_send_ni_response(notificationId, userResponse);
- StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
- StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE,
+ FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NI_EVENT_REPORTED,
+ FrameworkStatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE,
notificationId,
/* niType= */ 0,
/* needNotify= */ false,
@@ -1891,8 +1897,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
notification.textEncoding = textEncoding;
mNIHandler.handleNiNotification(notification);
- StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
- StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST,
+ FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NI_EVENT_REPORTED,
+ FrameworkStatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST,
notification.notificationId,
notification.niType,
notification.needNotify,
diff --git a/services/core/java/com/android/server/location/GnssVisibilityControl.java b/services/core/java/com/android/server/location/GnssVisibilityControl.java
index dd522b95a938..2b5fc7989d8b 100644
--- a/services/core/java/com/android/server/location/GnssVisibilityControl.java
+++ b/services/core/java/com/android/server/location/GnssVisibilityControl.java
@@ -36,11 +36,11 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
-import android.util.StatsLog;
import com.android.internal.R;
import com.android.internal.location.GpsNetInitiatedHandler;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.FrameworkStatsLog;
import java.util.Arrays;
import java.util.List;
@@ -650,7 +650,7 @@ class GnssVisibilityControl {
}
private void logEvent(NfwNotification notification, boolean isPermissionMismatched) {
- StatsLog.write(StatsLog.GNSS_NFW_NOTIFICATION_REPORTED,
+ FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NFW_NOTIFICATION_REPORTED,
notification.mProxyAppPackageName,
notification.mProtocolStack,
notification.mOtherProtocolStackName,
diff --git a/services/core/java/com/android/server/location/LocationProviderProxy.java b/services/core/java/com/android/server/location/LocationProviderProxy.java
index 1dee7a809c7e..19fb6694bbb5 100644
--- a/services/core/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/core/java/com/android/server/location/LocationProviderProxy.java
@@ -134,6 +134,7 @@ public class LocationProviderProxy extends AbstractLocationProvider {
// also used to synchronized any state changes (setEnabled, setProperties, setState, etc)
private final Object mLock = new Object();
+ private final Context mContext;
private final ServiceWatcher mServiceWatcher;
@GuardedBy("mLock")
@@ -143,10 +144,11 @@ public class LocationProviderProxy extends AbstractLocationProvider {
private LocationProviderProxy(Context context, String action, int enableOverlayResId,
int nonOverlayPackageResId) {
- // safe to use direct executor since none of our callbacks call back into any code above
- // this provider - they simply forward to the proxy service
- super(context, DIRECT_EXECUTOR);
+ // safe to use direct executor even though this class has internal locks - all of our
+ // callbacks go to oneway binder transactions which cannot possibly be re-entrant
+ super(DIRECT_EXECUTOR, Collections.emptySet());
+ mContext = context;
mServiceWatcher = new ServiceWatcher(context, FgThread.getHandler(), action, this::onBind,
this::onUnbind, enableOverlayResId, nonOverlayPackageResId);
diff --git a/services/core/java/com/android/server/location/LocationUsageLogger.java b/services/core/java/com/android/server/location/LocationUsageLogger.java
index 755438b1a413..93e19df01cf3 100644
--- a/services/core/java/com/android/server/location/LocationUsageLogger.java
+++ b/services/core/java/com/android/server/location/LocationUsageLogger.java
@@ -24,9 +24,9 @@ import android.location.LocationManager;
import android.location.LocationRequest;
import android.stats.location.LocationStatsEnums;
import android.util.Log;
-import android.util.StatsLog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.FrameworkStatsLog;
import java.time.Instant;
@@ -61,8 +61,8 @@ public class LocationUsageLogger {
boolean isLocationRequestNull = locationRequest == null;
boolean isGeofenceNull = geofence == null;
- StatsLog.write(StatsLog.LOCATION_MANAGER_API_USAGE_REPORTED, usageType,
- apiInUse, packageName,
+ FrameworkStatsLog.write(FrameworkStatsLog.LOCATION_MANAGER_API_USAGE_REPORTED,
+ usageType, apiInUse, packageName,
isLocationRequestNull
? LocationStatsEnums.PROVIDER_UNKNOWN
: bucketizeProvider(locationRequest.getProvider()),
@@ -101,7 +101,8 @@ public class LocationUsageLogger {
return;
}
- StatsLog.write(StatsLog.LOCATION_MANAGER_API_USAGE_REPORTED, usageType, apiInUse,
+ FrameworkStatsLog.write(FrameworkStatsLog.LOCATION_MANAGER_API_USAGE_REPORTED,
+ usageType, apiInUse,
/* package_name= */ null,
bucketizeProvider(providerName),
LocationStatsEnums.QUALITY_UNKNOWN,
diff --git a/services/core/java/com/android/server/location/MockProvider.java b/services/core/java/com/android/server/location/MockProvider.java
index bcec8b12b371..b45b66017062 100644
--- a/services/core/java/com/android/server/location/MockProvider.java
+++ b/services/core/java/com/android/server/location/MockProvider.java
@@ -16,15 +16,18 @@
package com.android.server.location;
+import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
+
import android.annotation.Nullable;
-import android.content.Context;
import android.location.Location;
+import android.os.Bundle;
import com.android.internal.location.ProviderProperties;
import com.android.internal.location.ProviderRequest;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Collections;
/**
* A mock location provider used by LocationManagerService to implement test providers.
@@ -35,10 +38,9 @@ public class MockProvider extends AbstractLocationProvider {
@Nullable private Location mLocation;
- public MockProvider(Context context, ProviderProperties properties) {
- // using a direct executor is only acceptable because this class is so simple it is trivial
- // to verify that it does not acquire any locks or re-enter LMS from callbacks
- super(context, Runnable::run);
+ public MockProvider(ProviderProperties properties) {
+ // using a direct executor is ok because this class has no locks that could deadlock
+ super(DIRECT_EXECUTOR, Collections.emptySet());
setProperties(properties);
}
@@ -59,6 +61,9 @@ public class MockProvider extends AbstractLocationProvider {
public void onSetRequest(ProviderRequest request) {}
@Override
+ protected void onExtraCommand(int uid, int pid, String command, Bundle extras) {}
+
+ @Override
protected void onRequestSetAllowed(boolean allowed) {
setAllowed(allowed);
}
diff --git a/services/core/java/com/android/server/location/MockableLocationProvider.java b/services/core/java/com/android/server/location/MockableLocationProvider.java
index 5b4f008a581b..b0e133061fc6 100644
--- a/services/core/java/com/android/server/location/MockableLocationProvider.java
+++ b/services/core/java/com/android/server/location/MockableLocationProvider.java
@@ -16,8 +16,9 @@
package com.android.server.location;
+import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
+
import android.annotation.Nullable;
-import android.content.Context;
import android.location.Location;
import android.os.Bundle;
@@ -68,10 +69,10 @@ public class MockableLocationProvider extends AbstractLocationProvider {
* The client should expect that it may being to receive callbacks as soon as this constructor
* is invoked.
*/
- public MockableLocationProvider(Context context, Object ownerLock, Listener listener) {
+ public MockableLocationProvider(Object ownerLock, Listener listener) {
// using a direct executor is acceptable because all inbound calls are delegated to the
// actual provider implementations which will use their own executors
- super(context, Runnable::run, Collections.emptySet());
+ super(DIRECT_EXECUTOR, Collections.emptySet());
mOwnerLock = ownerLock;
mRequest = ProviderRequest.EMPTY_REQUEST;
@@ -190,11 +191,6 @@ public class MockableLocationProvider extends AbstractLocationProvider {
}
}
- @Override
- public State getState() {
- return super.getState();
- }
-
/**
* Returns the current location request.
*/
@@ -204,6 +200,7 @@ public class MockableLocationProvider extends AbstractLocationProvider {
}
}
+ @Override
protected void onSetRequest(ProviderRequest request) {
synchronized (mOwnerLock) {
if (request == mRequest) {
@@ -218,6 +215,7 @@ public class MockableLocationProvider extends AbstractLocationProvider {
}
}
+ @Override
protected void onExtraCommand(int uid, int pid, String command, Bundle extras) {
synchronized (mOwnerLock) {
if (mProvider != null) {
@@ -226,6 +224,15 @@ public class MockableLocationProvider extends AbstractLocationProvider {
}
}
+ @Override
+ protected void onRequestSetAllowed(boolean allowed) {
+ synchronized (mOwnerLock) {
+ if (mProvider != null) {
+ mProvider.onRequestSetAllowed(allowed);
+ }
+ }
+ }
+
/**
* Dumps the current provider implementation.
*/
diff --git a/services/core/java/com/android/server/location/PassiveProvider.java b/services/core/java/com/android/server/location/PassiveProvider.java
index ef157a39fa28..54dffff8b1df 100644
--- a/services/core/java/com/android/server/location/PassiveProvider.java
+++ b/services/core/java/com/android/server/location/PassiveProvider.java
@@ -16,9 +16,12 @@
package com.android.server.location;
+import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
+
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
+import android.os.Bundle;
import com.android.internal.location.ProviderProperties;
import com.android.internal.location.ProviderRequest;
@@ -49,9 +52,8 @@ public class PassiveProvider extends AbstractLocationProvider {
private volatile boolean mReportLocation;
public PassiveProvider(Context context) {
- // using a direct executor is only acceptable because this class is so simple it is trivial
- // to verify that it does not acquire any locks or re-enter LMS from callbacks
- super(context, Runnable::run);
+ // using a direct executor is ok because this class has no locks that could deadlock
+ super(DIRECT_EXECUTOR, context);
mReportLocation = false;
@@ -59,15 +61,26 @@ public class PassiveProvider extends AbstractLocationProvider {
setAllowed(true);
}
+ /**
+ * Pass a location into the passive provider.
+ */
+ public void updateLocation(Location location) {
+ if (mReportLocation) {
+ reportLocation(location);
+ }
+ }
+
@Override
public void onSetRequest(ProviderRequest request) {
mReportLocation = request.reportLocation;
}
- public void updateLocation(Location location) {
- if (mReportLocation) {
- reportLocation(location);
- }
+ @Override
+ protected void onExtraCommand(int uid, int pid, String command, Bundle extras) {}
+
+ @Override
+ protected void onRequestSetAllowed(boolean allowed) {
+ // do nothing - the passive provider is always allowed
}
@Override
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 80f6a941bfa0..7104790d0a7c 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -90,10 +90,10 @@ import static android.service.notification.NotificationListenerService.REASON_UN
import static android.service.notification.NotificationListenerService.REASON_USER_STOPPED;
import static android.service.notification.NotificationListenerService.TRIM_FULL;
import static android.service.notification.NotificationListenerService.TRIM_LIGHT;
-import static android.util.StatsLogInternal.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING;
-import static android.util.StatsLogInternal.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static com.android.internal.util.FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING;
+import static com.android.internal.util.FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE;
import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
@@ -219,7 +219,6 @@ import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.StatsLog;
import android.util.Xml;
import android.util.proto.ProtoOutputStream;
import android.view.accessibility.AccessibilityEvent;
@@ -232,6 +231,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -243,6 +243,7 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.function.TriPredicate;
@@ -380,6 +381,8 @@ public class NotificationManagerService extends SystemService {
private static final String SCHEME_TIMEOUT = "timeout";
private static final String EXTRA_KEY = "key";
+ private static final int NOTIFICATION_INSTANCE_ID_MAX = (1 << 13);
+
/**
* Apps that post custom toasts in the background will have those blocked. Apps can
* still post toasts created with
@@ -519,6 +522,7 @@ public class NotificationManagerService extends SystemService {
private final SavePolicyFileRunnable mSavePolicyFile = new SavePolicyFileRunnable();
private NotificationRecordLogger mNotificationRecordLogger;
+ private InstanceIdSequence mNotificationInstanceIdSequence;
private static class Archive {
final int mBufferSize;
@@ -1718,18 +1722,22 @@ public class NotificationManagerService extends SystemService {
}
public NotificationManagerService(Context context) {
- this(context, new NotificationRecordLoggerImpl());
+ this(context,
+ new NotificationRecordLoggerImpl(),
+ new InstanceIdSequence(NOTIFICATION_INSTANCE_ID_MAX));
}
@VisibleForTesting
public NotificationManagerService(Context context,
- NotificationRecordLogger notificationRecordLogger) {
+ NotificationRecordLogger notificationRecordLogger,
+ InstanceIdSequence notificationInstanceIdSequence) {
super(context);
mNotificationRecordLogger = notificationRecordLogger;
+ mNotificationInstanceIdSequence = notificationInstanceIdSequence;
Notification.processWhitelistToken = WHITELIST_TOKEN;
}
- // TODO - replace these methods with a single VisibleForTesting constructor
+ // TODO - replace these methods with new fields in the VisibleForTesting constructor
@VisibleForTesting
void setAudioManager(AudioManager audioMananger) {
mAudioManager = audioMananger;
@@ -5780,14 +5788,14 @@ public class NotificationManagerService extends SystemService {
? intent.resolveActivityInfo(context.getPackageManager(), 0)
: null;
if (info == null) {
- StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
+ FrameworkStatsLog.write(FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING);
Log.w(TAG, "Unable to send as bubble -- couldn't find activity info for intent: "
+ intent);
return false;
}
if (!ActivityInfo.isResizeableMode(info.resizeMode)) {
- StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
+ FrameworkStatsLog.write(FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE);
Log.w(TAG, "Unable to send as bubble -- activity is not resizable for intent: "
+ intent);
@@ -6291,6 +6299,14 @@ public class NotificationManagerService extends SystemService {
NotificationRecord old = mNotificationsByKey.get(key);
final StatusBarNotification n = r.sbn;
final Notification notification = n.getNotification();
+
+ // Make sure the SBN has an instance ID for statsd logging.
+ if (old == null || old.sbn.getInstanceId() == null) {
+ n.setInstanceId(mNotificationInstanceIdSequence.newInstanceId());
+ } else {
+ n.setInstanceId(old.sbn.getInstanceId());
+ }
+
int index = indexOfNotificationLocked(n.getKey());
if (index < 0) {
mNotificationList.add(r);
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
index 03929e883852..9bbc39249e2e 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
@@ -138,5 +138,9 @@ public interface NotificationRecordLogger {
String assistant = r.getAdjustmentIssuer();
return (assistant == null) ? 0 : assistant.hashCode();
}
+
+ int getInstanceId() {
+ return (r.sbn.getInstanceId() == null ? 0 : r.sbn.getInstanceId().getId());
+ }
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
index d637ad5e368b..00b4c2b060ac 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
@@ -35,7 +35,7 @@ public class NotificationRecordLoggerImpl implements NotificationRecordLogger {
/* int32 event_id = 1 */ p.getUiEvent().getId(),
/* int32 uid = 2 */ r.getUid(),
/* string package_name = 3 */ r.sbn.getPackageName(),
- /* int32 instance_id = 4 */ 0, // TODO generate and fill instance ids
+ /* int32 instance_id = 4 */ p.getInstanceId(),
/* int32 notification_id = 5 */ r.sbn.getId(),
/* string notification_tag = 6 */ r.sbn.getTag(),
/* string channel_id = 7 */ r.sbn.getChannelIdLogTag(),
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index c6d2b334bd71..90afefffdf2e 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -96,7 +96,7 @@ public abstract class ApexManager {
* depending on whether this device supports APEX, i.e. {@link ApexProperties#updatable()}
* evaluates to {@code true}.
*/
- static ApexManager getInstance() {
+ public static ApexManager getInstance() {
return sApexManagerSingleton.get();
}
@@ -272,6 +272,21 @@ public abstract class ApexManager {
public abstract String getApexModuleNameForPackageName(String apexPackageName);
/**
+ * Copies the CE apex data directory for the given {@code userId} to a backup location, for use
+ * in case of rollback.
+ *
+ * @return long inode for the snapshot directory if the snapshot was successful, or -1 if not
+ */
+ public abstract long snapshotCeData(int userId, int rollbackId, String apexPackageName);
+
+ /**
+ * Restores the snapshot of the CE apex data directory for the given {@code userId}.
+ *
+ * @return boolean true if the restore was successful
+ */
+ public abstract boolean restoreCeData(int userId, int rollbackId, String apexPackageName);
+
+ /**
* Dumps various state information to the provided {@link PrintWriter} object.
*
* @param pw the {@link PrintWriter} object to send information to.
@@ -662,6 +677,45 @@ public abstract class ApexManager {
}
}
+ @Override
+ public long snapshotCeData(int userId, int rollbackId, String apexPackageName) {
+ populatePackageNameToApexModuleNameIfNeeded();
+ String apexModuleName;
+ synchronized (mLock) {
+ apexModuleName = mPackageNameToApexModuleName.get(apexPackageName);
+ }
+ if (apexModuleName == null) {
+ Slog.e(TAG, "Invalid apex package name: " + apexPackageName);
+ return -1;
+ }
+ try {
+ return mApexService.snapshotCeData(userId, rollbackId, apexModuleName);
+ } catch (Exception e) {
+ Slog.e(TAG, e.getMessage(), e);
+ return -1;
+ }
+ }
+
+ @Override
+ public boolean restoreCeData(int userId, int rollbackId, String apexPackageName) {
+ populatePackageNameToApexModuleNameIfNeeded();
+ String apexModuleName;
+ synchronized (mLock) {
+ apexModuleName = mPackageNameToApexModuleName.get(apexPackageName);
+ }
+ if (apexModuleName == null) {
+ Slog.e(TAG, "Invalid apex package name: " + apexPackageName);
+ return false;
+ }
+ try {
+ mApexService.restoreCeData(userId, rollbackId, apexModuleName);
+ return true;
+ } catch (Exception e) {
+ Slog.e(TAG, e.getMessage(), e);
+ return false;
+ }
+ }
+
/**
* Dump information about the packages contained in a particular cache
* @param packagesCache the cache to print information about.
@@ -865,6 +919,16 @@ public abstract class ApexManager {
}
@Override
+ public long snapshotCeData(int userId, int rollbackId, String apexPackageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean restoreCeData(int userId, int rollbackId, String apexPackageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
void dump(PrintWriter pw, String packageName) {
// No-op
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 431b4dc280f1..38da8ab26962 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -147,7 +147,6 @@ import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static final String TAG = "PackageInstallerSession";
@@ -736,22 +735,33 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
return result;
}
- return mFiles.stream().map(fileInfo -> fileInfo.name).toArray(String[]::new);
+
+ String[] result = new String[mFiles.size()];
+ for (int i = 0, size = mFiles.size(); i < size; ++i) {
+ result[i] = mFiles.get(i).name;
+ }
+ return result;
}
- private static File[] filterFiles(File parent, String[] names, FileFilter filter) {
- return Arrays.stream(names).map(name -> new File(parent, name)).filter(
- file -> filter.accept(file)).toArray(File[]::new);
+ private static ArrayList<File> filterFiles(File parent, String[] names, FileFilter filter) {
+ ArrayList<File> result = new ArrayList<>(names.length);
+ for (String name : names) {
+ File file = new File(parent, name);
+ if (filter.accept(file)) {
+ result.add(file);
+ }
+ }
+ return result;
}
@GuardedBy("mLock")
- private File[] getAddedApksLocked() {
+ private List<File> getAddedApksLocked() {
String[] names = getNamesLocked();
return filterFiles(stageDir, names, sAddedApkFilter);
}
@GuardedBy("mLock")
- private File[] getRemovedFilesLocked() {
+ private List<File> getRemovedFilesLocked() {
String[] names = getNamesLocked();
return filterFiles(stageDir, names, sRemovedFilter);
}
@@ -1070,11 +1080,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private final class FileSystemConnector extends
IPackageInstallerSessionFileSystemConnector.Stub {
- final Set<String> mAddedFiles;
+ final Set<String> mAddedFiles = new ArraySet<>();
FileSystemConnector(List<InstallationFile> addedFiles) {
- mAddedFiles = addedFiles.stream().map(file -> file.getName()).collect(
- Collectors.toSet());
+ for (InstallationFile file : addedFiles) {
+ mAddedFiles.add(file.getName());
+ }
}
@Override
@@ -1741,8 +1752,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@GuardedBy("mLock")
private void validateApexInstallLocked()
throws PackageManagerException {
- final File[] addedFiles = getAddedApksLocked();
- if (ArrayUtils.isEmpty(addedFiles)) {
+ final List<File> addedFiles = getAddedApksLocked();
+ if (addedFiles.isEmpty()) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
}
@@ -1751,7 +1762,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
"Too many files for apex install");
}
- File addedFile = addedFiles[0]; // there is only one file
+ File addedFile = addedFiles.get(0); // there is only one file
// Ensure file name has proper suffix
final String sourceName = addedFile.getName();
@@ -1818,9 +1829,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
&& params.mode == SessionParams.MODE_INHERIT_EXISTING
&& VerityUtils.hasFsverity(pkgInfo.applicationInfo.getBaseCodePath());
- final File[] removedFiles = getRemovedFilesLocked();
+ final List<File> removedFiles = getRemovedFilesLocked();
final List<String> removeSplitList = new ArrayList<>();
- if (!ArrayUtils.isEmpty(removedFiles)) {
+ if (!removedFiles.isEmpty()) {
for (File removedFile : removedFiles) {
final String fileName = removedFile.getName();
final String splitName = fileName.substring(
@@ -1829,8 +1840,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
- final File[] addedFiles = getAddedApksLocked();
- if (ArrayUtils.isEmpty(addedFiles) && removeSplitList.size() == 0) {
+ final List<File> addedFiles = getAddedApksLocked();
+ if (addedFiles.isEmpty() && removeSplitList.size() == 0) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
}
@@ -2449,16 +2460,21 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
return true;
}
- final List<InstallationFile> addedFiles = mFiles.stream().filter(
- file -> sAddedFilter.accept(new File(file.name))).map(
- file -> new InstallationFile(
- file.name, file.lengthBytes, file.metadata)).collect(
- Collectors.toList());
- final List<String> removedFiles = mFiles.stream().filter(
- file -> sRemovedFilter.accept(new File(file.name))).map(
- file -> file.name.substring(
- 0, file.name.length() - REMOVE_MARKER_EXTENSION.length())).collect(
- Collectors.toList());
+ final List<InstallationFile> addedFiles = new ArrayList<>(mFiles.size());
+ for (FileInfo file : mFiles) {
+ if (sAddedFilter.accept(new File(this.stageDir, file.name))) {
+ addedFiles.add(new InstallationFile(
+ file.name, file.lengthBytes, file.metadata));
+ }
+ }
+ final List<String> removedFiles = new ArrayList<>(mFiles.size());
+ for (FileInfo file : mFiles) {
+ if (sRemovedFilter.accept(new File(this.stageDir, file.name))) {
+ String name = file.name.substring(
+ 0, file.name.length() - REMOVE_MARKER_EXTENSION.length());
+ removedFiles.add(name);
+ }
+ }
if (mIncrementalFileStorages != null) {
for (InstallationFile file : addedFiles) {
@@ -3101,8 +3117,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
if (grantedRuntimePermissions.size() > 0) {
- params.grantedRuntimePermissions = grantedRuntimePermissions
- .stream().toArray(String[]::new);
+ params.grantedRuntimePermissions = (String[]) grantedRuntimePermissions.toArray();
}
if (whitelistedRestrictedPermissions.size() > 0) {
@@ -3111,14 +3126,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
int[] childSessionIdsArray;
if (childSessionIds.size() > 0) {
- childSessionIdsArray = childSessionIds.stream().mapToInt(i -> i).toArray();
+ childSessionIdsArray = new int[childSessionIds.size()];
+ for (int i = 0, size = childSessionIds.size(); i < size; ++i) {
+ childSessionIdsArray[i] = childSessionIds.get(i);
+ }
} else {
childSessionIdsArray = EMPTY_CHILD_SESSION_ARRAY;
}
FileInfo[] fileInfosArray = null;
if (!files.isEmpty()) {
- fileInfosArray = files.stream().toArray(FileInfo[]::new);
+ fileInfosArray = (FileInfo[]) files.toArray();
}
InstallSource installSource = InstallSource.create(installInitiatingPackageName,
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index ae28019a5dea..89354537526c 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -344,12 +344,12 @@ public class StagingManager {
}
/**
+ * Perform snapshot and restore as required both for APEXes themselves and for apks in APEX.
* Apks inside apex are not installed using apk-install flow. They are scanned from the system
* directory directly by PackageManager, as such, RollbackManager need to handle their data
* separately here.
*/
- private void snapshotAndRestoreApkInApexUserData(PackageInstallerSession session) {
- // We want to process apks inside apex. So current session needs to contain apex.
+ private void snapshotAndRestoreForApexSession(PackageInstallerSession session) {
if (!sessionContainsApex(session)) {
return;
}
@@ -382,19 +382,37 @@ public class StagingManager {
apexSessions.add(session);
}
- // For each apex, process the apks inside it
+ final UserManagerInternal um = LocalServices.getService(UserManagerInternal.class);
+ final int[] allUsers = um.getUserIds();
+ IRollbackManager rm = IRollbackManager.Stub.asInterface(
+ ServiceManager.getService(Context.ROLLBACK_SERVICE));
+
for (PackageInstallerSession apexSession : apexSessions) {
- List<String> apksInApex = mApexManager.getApksInApex(apexSession.getPackageName());
+ String packageName = apexSession.getPackageName();
+ // Perform any snapshots or restores for the APEX itself
+ snapshotAndRestoreApexUserData(packageName, allUsers, rm);
+
+ // Process the apks inside the APEX
+ List<String> apksInApex = mApexManager.getApksInApex(packageName);
for (String apk: apksInApex) {
- snapshotAndRestoreApkInApexUserData(apk);
+ snapshotAndRestoreApkInApexUserData(apk, allUsers, rm);
}
}
}
- private void snapshotAndRestoreApkInApexUserData(String packageName) {
- IRollbackManager rm = IRollbackManager.Stub.asInterface(
- ServiceManager.getService(Context.ROLLBACK_SERVICE));
+ private void snapshotAndRestoreApexUserData(
+ String packageName, int[] allUsers, IRollbackManager rm) {
+ try {
+ // appId, ceDataInode, and seInfo are not needed for APEXes
+ rm.snapshotAndRestoreUserData(packageName, allUsers, 0, 0,
+ null, 0 /*token*/);
+ } catch (RemoteException re) {
+ Slog.e(TAG, "Error snapshotting/restoring user data: " + re);
+ }
+ }
+ private void snapshotAndRestoreApkInApexUserData(
+ String packageName, int[] allUsers, IRollbackManager rm) {
PackageManagerInternal mPmi = LocalServices.getService(PackageManagerInternal.class);
AndroidPackage pkg = mPmi.getPackage(packageName);
if (pkg == null) {
@@ -403,13 +421,11 @@ public class StagingManager {
return;
}
final String seInfo = pkg.getSeInfo();
- final UserManagerInternal um = LocalServices.getService(UserManagerInternal.class);
- final int[] allUsers = um.getUserIds();
int appId = -1;
long ceDataInode = -1;
final PackageSetting ps = (PackageSetting) mPmi.getPackageSetting(packageName);
- if (ps != null && rm != null) {
+ if (ps != null) {
appId = ps.appId;
ceDataInode = ps.getCeDataInode(UserHandle.USER_SYSTEM);
// NOTE: We ignore the user specified in the InstallParam because we know this is
@@ -498,7 +514,7 @@ public class StagingManager {
abortCheckpoint();
return;
}
- snapshotAndRestoreApkInApexUserData(session);
+ snapshotAndRestoreForApexSession(session);
Slog.i(TAG, "APEX packages in session " + session.sessionId
+ " were successfully activated. Proceeding with APK packages, if any");
}
diff --git a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
index e6e6e23bf714..e77839c4e5b5 100644
--- a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
+++ b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
@@ -26,6 +26,7 @@ import android.util.SparseLongArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.pm.ApexManager;
import com.android.server.pm.Installer;
import com.android.server.pm.Installer.InstallerException;
@@ -42,9 +43,17 @@ public class AppDataRollbackHelper {
private static final String TAG = "RollbackManager";
private final Installer mInstaller;
+ private final ApexManager mApexManager;
public AppDataRollbackHelper(Installer installer) {
mInstaller = installer;
+ mApexManager = ApexManager.getInstance();
+ }
+
+ @VisibleForTesting
+ AppDataRollbackHelper(Installer installer, ApexManager apexManager) {
+ mInstaller = installer;
+ mApexManager = apexManager;
}
/**
@@ -55,7 +64,7 @@ public class AppDataRollbackHelper {
@GuardedBy("rollback.mLock")
// TODO(b/136241838): Move into Rollback and synchronize there.
public void snapshotAppData(
- int snapshotId, PackageRollbackInfo packageRollbackInfo, int[] userIds) {
+ int rollbackId, PackageRollbackInfo packageRollbackInfo, int[] userIds) {
for (int user : userIds) {
final int storageFlags;
if (isUserCredentialLocked(user)) {
@@ -68,16 +77,7 @@ public class AppDataRollbackHelper {
storageFlags = Installer.FLAG_STORAGE_CE | Installer.FLAG_STORAGE_DE;
}
- try {
- long ceSnapshotInode = mInstaller.snapshotAppData(
- packageRollbackInfo.getPackageName(), user, snapshotId, storageFlags);
- if ((storageFlags & Installer.FLAG_STORAGE_CE) != 0) {
- packageRollbackInfo.putCeSnapshotInode(user, ceSnapshotInode);
- }
- } catch (InstallerException ie) {
- Slog.e(TAG, "Unable to create app data snapshot for: "
- + packageRollbackInfo.getPackageName() + ", userId: " + user, ie);
- }
+ doSnapshot(packageRollbackInfo, user, rollbackId, storageFlags);
}
}
@@ -119,26 +119,82 @@ public class AppDataRollbackHelper {
}
}
- try {
+ doRestoreOrWipe(packageRollbackInfo, userId, rollbackId, appId, seInfo, storageFlags);
+
+ return changedRollback;
+ }
+
+ private boolean doSnapshot(
+ PackageRollbackInfo packageRollbackInfo, int userId, int rollbackId, int flags) {
+ if (packageRollbackInfo.isApex()) {
+ // For APEX, only snapshot CE here
+ if ((flags & Installer.FLAG_STORAGE_CE) != 0) {
+ long ceSnapshotInode = mApexManager.snapshotCeData(
+ userId, rollbackId, packageRollbackInfo.getPackageName());
+ if (ceSnapshotInode > 0) {
+ packageRollbackInfo.putCeSnapshotInode(userId, ceSnapshotInode);
+ } else {
+ return false;
+ }
+ }
+ } else {
+ // APK
+ try {
+ long ceSnapshotInode = mInstaller.snapshotAppData(
+ packageRollbackInfo.getPackageName(), userId, rollbackId, flags);
+ if ((flags & Installer.FLAG_STORAGE_CE) != 0) {
+ packageRollbackInfo.putCeSnapshotInode(userId, ceSnapshotInode);
+ }
+ } catch (InstallerException ie) {
+ Slog.e(TAG, "Unable to create app data snapshot for: "
+ + packageRollbackInfo.getPackageName() + ", userId: " + userId, ie);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean doRestoreOrWipe(PackageRollbackInfo packageRollbackInfo, int userId,
+ int rollbackId, int appId, String seInfo, int flags) {
+ if (packageRollbackInfo.isApex()) {
switch (packageRollbackInfo.getRollbackDataPolicy()) {
case PackageManager.RollbackDataPolicy.WIPE:
- mInstaller.clearAppData(null, packageRollbackInfo.getPackageName(),
- userId, storageFlags, 0);
+ // TODO: Implement WIPE for apex CE data
break;
case PackageManager.RollbackDataPolicy.RESTORE:
- mInstaller.restoreAppDataSnapshot(packageRollbackInfo.getPackageName(), appId,
- seInfo, userId, rollbackId, storageFlags);
+ // For APEX, only restore of CE may be done here.
+ if ((flags & Installer.FLAG_STORAGE_CE) != 0) {
+ mApexManager.restoreCeData(
+ userId, rollbackId, packageRollbackInfo.getPackageName());
+ }
break;
default:
break;
}
- } catch (InstallerException ie) {
- Slog.e(TAG, "Unable to restore/wipe app data: "
- + packageRollbackInfo.getPackageName() + " policy="
- + packageRollbackInfo.getRollbackDataPolicy(), ie);
- }
+ } else {
+ // APK
+ try {
+ switch (packageRollbackInfo.getRollbackDataPolicy()) {
+ case PackageManager.RollbackDataPolicy.WIPE:
+ mInstaller.clearAppData(null, packageRollbackInfo.getPackageName(),
+ userId, flags, 0);
+ break;
+ case PackageManager.RollbackDataPolicy.RESTORE:
- return changedRollback;
+ mInstaller.restoreAppDataSnapshot(packageRollbackInfo.getPackageName(),
+ appId, seInfo, userId, rollbackId, flags);
+ break;
+ default:
+ break;
+ }
+ } catch (InstallerException ie) {
+ Slog.e(TAG, "Unable to restore/wipe app data: "
+ + packageRollbackInfo.getPackageName() + " policy="
+ + packageRollbackInfo.getRollbackDataPolicy(), ie);
+ return false;
+ }
+ }
+ return true;
}
/**
@@ -204,40 +260,15 @@ public class AppDataRollbackHelper {
if (hasPendingBackup) {
int idx = pendingBackupUsers.indexOf(userId);
- try {
- long ceSnapshotInode = mInstaller.snapshotAppData(info.getPackageName(),
- userId, rollback.info.getRollbackId(),
- Installer.FLAG_STORAGE_CE);
- info.putCeSnapshotInode(userId, ceSnapshotInode);
+ if (doSnapshot(
+ info, userId, rollback.info.getRollbackId(), Installer.FLAG_STORAGE_CE)) {
pendingBackupUsers.remove(idx);
- } catch (InstallerException ie) {
- Slog.e(TAG,
- "Unable to create app data snapshot for: "
- + info.getPackageName() + ", userId: " + userId, ie);
}
}
- if (hasPendingRestore) {
- try {
- switch (info.getRollbackDataPolicy()) {
- case PackageManager.RollbackDataPolicy.WIPE:
- mInstaller.clearAppData(null, info.getPackageName(), userId,
- Installer.FLAG_STORAGE_CE, 0);
- break;
- case PackageManager.RollbackDataPolicy.RESTORE:
- mInstaller.restoreAppDataSnapshot(info.getPackageName(), ri.appId,
- ri.seInfo, userId, rollback.info.getRollbackId(),
- Installer.FLAG_STORAGE_CE);
- break;
- default:
- break;
- }
- info.removeRestoreInfo(ri);
- } catch (InstallerException ie) {
- Slog.e(TAG, "Unable to restore/wipe app data for: "
- + info.getPackageName() + " policy="
- + info.getRollbackDataPolicy(), ie);
- }
+ if (hasPendingRestore && doRestoreOrWipe(info, userId, rollback.info.getRollbackId(),
+ ri.appId, ri.seInfo, Installer.FLAG_STORAGE_CE)) {
+ info.removeRestoreInfo(ri);
}
}
return foundBackupOrRestore;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c50048eeab64..6e479b2b53e0 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1244,6 +1244,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
return mDisplayRotation;
}
+ void setInsetProvider(@InternalInsetsType int type, WindowState win,
+ @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider){
+ setInsetProvider(type, win, frameProvider, null /* imeFrameProvider */);
+ }
+
/**
* Marks a window as providing insets for the rest of the windows in the system.
*
@@ -1251,10 +1256,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
* @param win The window.
* @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
* the window should be taken.
+ * @param imeFrameProvider Function to compute the frame when dispatching insets to the IME, or
+ * {@code null} if the normal frame should be taken.
*/
void setInsetProvider(@InternalInsetsType int type, WindowState win,
- @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider) {
- mInsetsStateController.getSourceProvider(type).setWindow(win, frameProvider);
+ @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider,
+ @Nullable TriConsumer<DisplayFrames, WindowState, Rect> imeFrameProvider) {
+ mInsetsStateController.getSourceProvider(type).setWindow(win, frameProvider,
+ imeFrameProvider);
}
InsetsStateController getInsetsStateController() {
@@ -3283,7 +3292,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
computeImeTarget(true /* updateImeTarget */);
mInsetsStateController.getSourceProvider(ITYPE_IME).setWindow(win,
- null /* frameProvider */);
+ null /* frameProvider */, null /* imeFrameProvider */);
}
/**
@@ -3407,6 +3416,57 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
&& mInputMethodTarget.mActivityRecord.matchParentBounds());
}
+ /**
+ * Get IME target that should host IME when this display that is reparented to another
+ * WindowState.
+ * IME is never displayed in a child display.
+ * Use {@link WindowState#getImeControlTarget()} when IME target window
+ * which originally called
+ * {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} is known.
+ *
+ * @return {@link WindowState} of host that controls IME.
+ * {@code null} when {@param dc} is not a virtual display.
+ * @see DisplayContent#reparent
+ */
+ @Nullable
+ WindowState getImeControlTarget() {
+ WindowState imeTarget = mInputMethodTarget;
+ if (imeTarget != null) {
+ return imeTarget.getImeControlTarget();
+ }
+
+ return getInsetsStateController().getImeSourceProvider().getControlTarget().getWindow();
+ }
+
+ /**
+ * Finds the window which can host IME if IME target cannot host it.
+ * e.g. IME target cannot host IME when it's display has a parent display OR when display
+ * doesn't support IME/system decorations.
+ *
+ * @param target current IME target.
+ * @return {@link WindowState} that can host IME.
+ * @see DisplayContent#getImeControlTarget()
+ */
+ WindowState getImeHostOrFallback(WindowState target) {
+ if (target != null && target.getDisplayContent().canShowIme()) {
+ return target;
+ }
+
+ // host is in non-default display that doesn't support system decor, default to
+ // default display's StatusBar to control IME.
+ // TODO: (b/148234093)find a better host OR control IME animation/visibility directly
+ // because it won't work when statusbar isn't available.
+ return mWmService.getDefaultDisplayContentLocked().getDisplayPolicy().getStatusBar();
+ }
+
+ boolean canShowIme() {
+ if (isUntrustedVirtualDisplay()) {
+ return false;
+ }
+ return mWmService.mDisplayWindowSettings.shouldShowImeLocked(this)
+ || mWmService.mForceDesktopModeOnExternalDisplays;
+ }
+
private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) {
if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) {
return;
@@ -3416,10 +3476,22 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
mInputMethodTargetWaitingAnim = targetWaitingAnim;
assignWindowLayers(false /* setLayoutNeeded */);
mInputMethodControlTarget = computeImeControlTarget();
- mInsetsStateController.onImeTargetChanged(mInputMethodControlTarget);
+ mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget);
updateImeParent();
}
+ /**
+ * IME control target is the window that controls the IME visibility and animation.
+ * This window is same as the window on which startInput is called.
+ * @param target the window that receives IME control.
+ *
+ * @see #getImeControlTarget()
+ */
+ void updateImeControlTarget(WindowState target) {
+ mInputMethodControlTarget = target;
+ mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget);
+ }
+
private void updateImeParent() {
// Force attaching IME to the display when magnifying, or it would be magnified with
// target app together.
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index c6ccd4af06c5..4baf913c2a37 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1026,7 +1026,12 @@ public class DisplayPolicy {
- getNavigationBarHeight(displayFrames.mRotation,
mDisplayContent.getConfiguration().uiMode);
}
- });
+ },
+
+ // For IME we use regular frame.
+ (displayFrames, windowState, inOutFrame) ->
+ inOutFrame.set(windowState.getFrameLw()));
+
mDisplayContent.setInsetProvider(ITYPE_BOTTOM_GESTURES, win,
(displayFrames, windowState, inOutFrame) -> {
inOutFrame.top -= mBottomGestureAdditionalInset;
@@ -3068,7 +3073,9 @@ public class DisplayPolicy {
}
final InsetsControlTarget controlTarget =
swipeTarget.getControllableInsetProvider().getControlTarget();
- if (controlTarget == null) {
+
+ // No transient mode on lockscreen (in notification shade window).
+ if (controlTarget == null || controlTarget == getNotificationShade()) {
return;
}
if (controlTarget.canShowTransient()) {
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index fb97ecf8bbc4..3ff1b95dc716 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -16,9 +16,13 @@
package com.android.server.wm;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_IME;
+
import android.view.InsetsSource;
import android.view.WindowInsets;
+import com.android.server.protolog.common.ProtoLog;
+
/**
* 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}.
@@ -35,40 +39,40 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
}
/**
- * Called when a layout pass has occurred.
- */
- void onPostLayout() {
- super.onPostLayout();
-
- if (mImeTargetFromIme != null
- && isImeTargetFromDisplayContentAndImeSame()
- && mWin != null
- && mWin.isDrawnLw()
- && !mWin.mGivenInsetsPending) {
- mIsImeLayoutDrawn = true;
- }
- }
-
- /**
- * Called when Insets have been dispatched to client.
+ * Called when Insets have been dispatched to client. This gets called just after onPostLayout.
*/
void onPostInsetsDispatched() {
- if (mIsImeLayoutDrawn && mShowImeRunner != null) {
- // Show IME if InputMethodService requested to be shown and it's layout has finished.
- mShowImeRunner.run();
- }
+ checkShowImePostLayout();
}
/**
* Called from {@link WindowManagerInternal#showImePostLayout} when {@link InputMethodService}
* requests to show IME on {@param imeTarget}.
+ *
* @param imeTarget imeTarget on which IME request is coming from.
*/
void scheduleShowImePostLayout(WindowState imeTarget) {
+ boolean targetChanged = mImeTargetFromIme != imeTarget
+ && mImeTargetFromIme != null && imeTarget != null && mShowImeRunner != null
+ && mImeTargetFromIme.mActivityRecord == imeTarget.mActivityRecord;
mImeTargetFromIme = imeTarget;
+ if (targetChanged) {
+ // target changed, check if new target can show IME.
+ ProtoLog.d(WM_DEBUG_IME, "IME target changed within ActivityRecord");
+ checkShowImePostLayout();
+ // if IME cannot be shown at this time, it is scheduled to be shown.
+ // once window that called IMM.showSoftInput() and DisplayContent's ImeTarget match,
+ // it will be shown.
+ return;
+ }
+
+ ProtoLog.d(WM_DEBUG_IME, "Schedule IME show for %s", mImeTargetFromIme.getName());
mShowImeRunner = () -> {
+ ProtoLog.d(WM_DEBUG_IME, "Run showImeRunner");
// Target should still be the same.
if (isImeTargetFromDisplayContentAndImeSame()) {
+ ProtoLog.d(WM_DEBUG_IME, "call showInsets(ime) on %s",
+ mDisplayContent.mInputMethodControlTarget.getWindow().getName());
mDisplayContent.mInputMethodControlTarget.showInsets(
WindowInsets.Type.ime(), true /* fromIme */);
}
@@ -76,10 +80,27 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
};
}
+ private void checkShowImePostLayout() {
+ // check if IME is drawn
+ if (mIsImeLayoutDrawn
+ || (mImeTargetFromIme != null
+ && isImeTargetFromDisplayContentAndImeSame()
+ && mWin != null
+ && mWin.isDrawnLw()
+ && !mWin.mGivenInsetsPending)) {
+ mIsImeLayoutDrawn = true;
+ // show IME if InputMethodService requested it to be shown.
+ if (mShowImeRunner != null) {
+ mShowImeRunner.run();
+ }
+ }
+ }
+
/**
* Abort any pending request to show IME post layout.
*/
void abortShowImePostLayout() {
+ ProtoLog.d(WM_DEBUG_IME, "abortShowImePostLayout");
mImeTargetFromIme = null;
mIsImeLayoutDrawn = false;
mShowImeRunner = null;
@@ -96,12 +117,14 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
// TODO(b/139861270): Remove the child & sublayer check once IMMS is aware of
// actual IME target.
final WindowState dcTarget = mDisplayContent.mInputMethodTarget;
- if (dcTarget == null) {
+ if (dcTarget == null || mImeTargetFromIme == null) {
return false;
}
+ ProtoLog.d(WM_DEBUG_IME, "dcTarget: %s mImeTargetFromIme: %s",
+ dcTarget.getName(), mImeTargetFromIme.getName());
+
return (!dcTarget.isClosing() && mImeTargetFromIme == dcTarget)
|| (mImeTargetFromIme != null && dcTarget.getParentWindow() == mImeTargetFromIme
- && dcTarget.mSubLayer > mImeTargetFromIme.mSubLayer);
+ && dcTarget.mSubLayer > mImeTargetFromIme.mSubLayer);
}
-
}
diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java
index 154cde140810..20e8f2ba485a 100644
--- a/services/core/java/com/android/server/wm/InsetsControlTarget.java
+++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java
@@ -26,6 +26,13 @@ interface InsetsControlTarget {
void notifyInsetsControlChanged();
/**
+ * @return {@link WindowState} of this target, if any.
+ */
+ default WindowState getWindow() {
+ return null;
+ }
+
+ /**
* Instructs the control target to show inset sources.
*
* @param types to specify which types of insets source window should be shown.
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index fa764e3dfc18..2d4211aa16d8 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -187,6 +187,10 @@ class InsetsPolicy {
if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) {
return mTransientControlTarget;
}
+ if (focusedWin == mPolicy.getNotificationShade()) {
+ // Notification shade has control anyways, no reason to force anything.
+ return focusedWin;
+ }
if (areSystemBarsForciblyVisible() || isKeyguardOrStatusBarForciblyVisible()) {
return null;
}
@@ -197,6 +201,10 @@ class InsetsPolicy {
if (mShowingTransientTypes.indexOf(ITYPE_NAVIGATION_BAR) != -1) {
return mTransientControlTarget;
}
+ if (focusedWin == mPolicy.getNotificationShade()) {
+ // Notification shade has control anyways, no reason to force anything.
+ return focusedWin;
+ }
if (areSystemBarsForciblyVisible() || isNavBarForciblyVisible()) {
return null;
}
@@ -204,9 +212,6 @@ class InsetsPolicy {
}
private boolean isKeyguardOrStatusBarForciblyVisible() {
- if (mPolicy.isKeyguardShowing()) {
- return true;
- }
final WindowState statusBar = mPolicy.getStatusBar();
if (statusBar != null) {
// TODO(b/118118435): Pretend to the app that it's still able to control it?
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 2bb58ddc5b38..db434800c979 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -34,6 +34,7 @@ import android.util.proto.ProtoOutputStream;
import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
+import android.view.InsetsState.InternalInsetsType;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
@@ -61,6 +62,8 @@ class InsetsSourceProvider {
private @Nullable ControlAdapter mAdapter;
private TriConsumer<DisplayFrames, WindowState, Rect> mFrameProvider;
+ private TriConsumer<DisplayFrames, WindowState, Rect> mImeFrameProvider;
+ private final Rect mImeOverrideFrame = new Rect();
/** The visibility override from the current controlling window. */
private boolean mClientVisible;
@@ -111,9 +114,12 @@ class InsetsSourceProvider {
* @param win The window that links to this source.
* @param frameProvider Based on display frame state and the window, calculates the resulting
* frame that should be reported to clients.
+ * @param imeFrameProvider Based on display frame state and the window, calculates the resulting
+ * frame that should be reported to IME.
*/
void setWindow(@Nullable WindowState win,
- @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider) {
+ @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider,
+ @Nullable TriConsumer<DisplayFrames, WindowState, Rect> imeFrameProvider) {
if (mWin != null) {
if (mControllable) {
mWin.setControllableInsetProvider(null);
@@ -126,6 +132,7 @@ class InsetsSourceProvider {
}
mWin = win;
mFrameProvider = frameProvider;
+ mImeFrameProvider = imeFrameProvider;
if (win == null) {
setServerVisible(false);
mSource.setFrame(new Rect());
@@ -162,6 +169,12 @@ class InsetsSourceProvider {
}
mSource.setFrame(mTmpRect);
+ if (mImeFrameProvider != null) {
+ mImeOverrideFrame.set(mWin.getFrameLw());
+ mImeFrameProvider.accept(mWin.getDisplayContent().mDisplayFrames, mWin,
+ mImeOverrideFrame);
+ }
+
if (mWin.mGivenVisibleInsets.left != 0 || mWin.mGivenVisibleInsets.top != 0
|| mWin.mGivenVisibleInsets.right != 0 || mWin.mGivenVisibleInsets.bottom != 0) {
mTmpRect.set(mWin.getFrameLw());
@@ -209,6 +222,12 @@ class InsetsSourceProvider {
// to control the window for now.
return;
}
+ if (target != null && target.getWindow() != null) {
+ // ime control target could be a different window.
+ // Refer WindowState#getImeControlTarget().
+ target = target.getWindow().getImeControlTarget();
+ }
+
if (mWin == null) {
mControlTarget = target;
return;
@@ -303,6 +322,21 @@ class InsetsSourceProvider {
return sNewInsetsMode == NEW_INSETS_MODE_NONE || mClientVisible;
}
+ /**
+ * @return Whether this provider uses a different frame to dispatch to the IME.
+ */
+ boolean overridesImeFrame() {
+ return mImeFrameProvider != null;
+ }
+
+ /**
+ * @return Rect to dispatch to the IME as frame. Only valid if {@link #overridesImeFrame()}
+ * returns {@code true}.
+ */
+ Rect getImeOverrideFrame() {
+ return mImeOverrideFrame;
+ }
+
private class ControlAdapter implements AnimationAdapter {
private SurfaceControl mCapturedLeash;
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index b2234d17984e..568966ae8d2e 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -88,6 +88,20 @@ class InsetsStateController {
state.removeSource(ITYPE_IME);
state.removeSource(ITYPE_STATUS_BAR);
}
+
+ // IME needs different frames for certain cases (e.g. navigation bar in gesture nav).
+ if (type == ITYPE_IME) {
+ for (int i = mProviders.size() - 1; i >= 0; i--) {
+ InsetsSourceProvider otherProvider = mProviders.valueAt(i);
+ if (otherProvider.overridesImeFrame()) {
+ InsetsSource override =
+ new InsetsSource(state.getSource(otherProvider.getSource().getType()));
+ override.setFrame(otherProvider.getImeOverrideFrame());
+ state.addSource(override);
+ }
+ }
+ }
+
return state;
}
@@ -167,7 +181,7 @@ class InsetsStateController {
return mTypeFakeControlTargetMap.get(type) == target;
}
- void onImeTargetChanged(@Nullable InsetsControlTarget imeTarget) {
+ void onImeControlTargetChanged(@Nullable InsetsControlTarget imeTarget) {
onControlChanged(ITYPE_IME, imeTarget);
notifyPendingInsetsControlChanged();
}
diff --git a/services/core/java/com/android/server/wm/ProtoLogGroup.java b/services/core/java/com/android/server/wm/ProtoLogGroup.java
index 5c2830e13b75..51725cecbc74 100644
--- a/services/core/java/com/android/server/wm/ProtoLogGroup.java
+++ b/services/core/java/com/android/server/wm/ProtoLogGroup.java
@@ -59,6 +59,8 @@ public enum ProtoLogGroup implements IProtoLogGroup {
Consts.TAG_WM),
WM_DEBUG_WINDOW_MOVEMENT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
Consts.TAG_WM),
+ WM_DEBUG_IME(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
TEST_GROUP(true, true, false, "WindowManagetProtoLogTest");
private final boolean mEnabled;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2c6c756dda3b..229bd2f4afe1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6991,8 +6991,15 @@ public class WindowManagerService extends IWindowManager.Stub
throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
}
boolean show;
+ final DisplayContent dc = mRoot.getDisplayContent(displayId);
+ if (dc == null) {
+ ProtoLog.w(WM_ERROR,
+ "Attempted to get IME flag of a display that does not exist: %d",
+ displayId);
+ return false;
+ }
synchronized (mGlobalLock) {
- show = shouldShowImeSystemWindowUncheckedLocked(displayId);
+ show = dc.canShowIme();
}
return show;
@@ -7291,6 +7298,10 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.w(TAG_WM, "updateInputMethodTargetWindow: imeToken=" + imeToken
+ " imeTargetWindowToken=" + imeTargetWindowToken);
}
+ final WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
+ if (imeTarget != null) {
+ imeTarget.getDisplayContent().updateImeControlTarget(imeTarget);
+ }
}
@Override
@@ -7405,15 +7416,13 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void showImePostLayout(IBinder imeTargetWindowToken) {
synchronized (mGlobalLock) {
- final WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
+ WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
if (imeTarget == null) {
return;
}
- final int displayId = imeTarget.getDisplayId();
- if (!shouldShowImeSystemWindowUncheckedLocked(displayId)) {
- return;
- }
+ imeTarget = imeTarget.getImeControlTarget();
+ final int displayId = imeTarget.getDisplayId();
mRoot.getDisplayContent(displayId).getInsetsStateController().getImeSourceProvider()
.scheduleShowImePostLayout(imeTarget);
}
@@ -7423,12 +7432,16 @@ public class WindowManagerService extends IWindowManager.Stub
public void hideIme(int displayId) {
synchronized (mGlobalLock) {
final DisplayContent dc = mRoot.getDisplayContent(displayId);
- if (dc != null && dc.mInputMethodTarget != null) {
+ if (dc != null) {
+ WindowState imeTarget = dc.getImeControlTarget();
+ if (imeTarget == null) {
+ return;
+ }
// If there was a pending IME show(), reset it as IME has been
// requested to be hidden.
- dc.getInsetsStateController().getImeSourceProvider().abortShowImePostLayout();
- dc.mInputMethodControlTarget.hideInsets(WindowInsets.Type.ime(),
- true /* fromIme */);
+ imeTarget.getDisplayContent().getInsetsStateController().getImeSourceProvider()
+ .abortShowImePostLayout();
+ imeTarget.hideInsets(WindowInsets.Type.ime(), true /* fromIme */);
}
}
}
@@ -7936,21 +7949,6 @@ public class WindowManagerService extends IWindowManager.Stub
return true;
}
- private boolean shouldShowImeSystemWindowUncheckedLocked(final int displayId) {
- final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
- if (displayContent == null) {
- ProtoLog.w(WM_ERROR,
- "Attempted to get IME flag of a display that does not exist: %d",
- displayId);
- return false;
- }
- if (displayContent.isUntrustedVirtualDisplay()) {
- return false;
- }
- return mDisplayWindowSettings.shouldShowImeLocked(displayContent)
- || mForceDesktopModeOnExternalDisplays;
- }
-
@Override
public void getWindowInsets(WindowManager.LayoutParams attrs,
int displayId, Rect outContentInsets, Rect outStableInsets,
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index aab6b510ef1a..fc04126714d1 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3518,6 +3518,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
@Override
+ public WindowState getWindow() {
+ return this;
+ }
+
+ @Override
public void showInsets(@InsetsType int types, boolean fromIme) {
try {
mClient.showInsets(types, fromIme);
@@ -5334,6 +5339,24 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return false;
}
+ /**
+ * Get IME target that should host IME when this window's display has a parent.
+ * Note: IME is never hosted by a display that has a parent.
+ * When window calling
+ * {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} is unknown,
+ * use {@link DisplayContent#getImeControlTarget()} instead.
+ *
+ * @return {@link WindowState} of host that controls the IME.
+ * When window is doesn't have a parent, it is returned as-is.
+ */
+ WindowState getImeControlTarget() {
+ final DisplayContent dc = getDisplayContent();
+ final WindowState parentWindow = dc.getParentWindow();
+
+ // If target's display has a parent, IME is displayed in the parent display.
+ return dc.getImeHostOrFallback(parentWindow != null ? parentWindow : this);
+ }
+
@Override
void assignLayer(Transaction t, int layer) {
// See comment in assignRelativeLayerForImeTargetChild
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index d7ea2f53c286..ec3ef7807c3a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -9553,9 +9553,19 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
@Override
- public void setDefaultSmsApplication(ComponentName admin, String packageName) {
+ public void setDefaultSmsApplication(ComponentName admin, String packageName, boolean parent) {
Objects.requireNonNull(admin, "ComponentName is null");
- enforceDeviceOwner(admin);
+
+ if (parent) {
+ ActiveAdmin ap = getActiveAdminForCallerLocked(admin,
+ DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER, parent);
+ enforceProfileOwnerOfOrganizationOwnedDevice(ap);
+ mInjector.binderWithCleanCallingIdentity(() -> enforcePackageIsSystemPackage(
+ packageName, getProfileParentId(mInjector.userHandleGetCallingUserId())));
+ } else {
+ enforceDeviceOwner(admin);
+ }
+
mInjector.binderWithCleanCallingIdentity(() ->
SmsApplication.setDefaultApplication(packageName, mContext));
}
@@ -10778,7 +10788,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
// API cannot be used to leak if certain non-system package exists in the person
// profile.
mInjector.binderWithCleanCallingIdentity(() ->
- enforcePackageIsSystemPackage(packageName, hidden, userId));
+ enforcePackageIsSystemPackage(packageName, userId));
}
result = mInjector.binderWithCleanCallingIdentity(() -> mIPackageManager
@@ -10811,7 +10821,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER, parent);
// Ensure the package provided is a system package.
mInjector.binderWithCleanCallingIdentity(() ->
- enforcePackageIsSystemPackage(packageName, false, userId));
+ enforcePackageIsSystemPackage(packageName, userId));
}
return mInjector.binderWithCleanCallingIdentity(
@@ -10819,16 +10829,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
- private void enforcePackageIsSystemPackage(String packageName, boolean hidden, int userId)
+ private void enforcePackageIsSystemPackage(String packageName, int userId)
throws RemoteException {
- int flags = PackageManager.MATCH_SYSTEM_ONLY;
- // If the package is currently hidden then it is considered uninstalled and
- // the MATCH_UNINSTALLED_PACKAGES flag has to be added.
- if (!hidden) {
- flags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
- }
- PackageInfo packageInfo = mIPackageManager.getPackageInfo(packageName, flags, userId);
- if (packageInfo == null || !packageInfo.applicationInfo.isSystemApp()) {
+ if (!isSystemApp(mIPackageManager, packageName, userId)) {
throw new IllegalArgumentException(
"The provided package is not a system package");
}
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 556f6362d872..f99081024494 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -30,6 +30,7 @@ android_test {
"services.usage",
"guava",
"androidx.test.core",
+ "androidx.test.ext.truth",
"androidx.test.runner",
"androidx.test.rules",
"mockito-target-minus-junit4",
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 422c278a3af7..f7a9e5456156 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -2223,17 +2223,13 @@ public class DevicePolicyManagerTest extends DpmTestBase {
String packageName = "com.google.android.test";
- PackageInfo packageInfo = new PackageInfo();
- packageInfo.applicationInfo = new ApplicationInfo();
- packageInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
+ ApplicationInfo applicationInfo = new ApplicationInfo();
+ applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
when(getServices().userManager.getProfileParent(MANAGED_PROFILE_USER_ID))
.thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
- when(getServices().ipackageManager.getPackageInfo(packageName,
- PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM)).thenReturn(
- packageInfo);
- when(getServices().ipackageManager.getPackageInfo(packageName,
- PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_SYSTEM_ONLY,
- UserHandle.USER_SYSTEM)).thenReturn(packageInfo);
+ when(getServices().ipackageManager.getApplicationInfo(packageName,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES, UserHandle.USER_SYSTEM)).thenReturn(
+ applicationInfo);
parentDpm.setApplicationHidden(admin1, packageName, true);
verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName,
diff --git a/services/tests/servicestests/src/com/android/server/location/MockableLocationProviderTest.java b/services/tests/servicestests/src/com/android/server/location/MockableLocationProviderTest.java
new file mode 100644
index 000000000000..6fafe113d90d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/location/MockableLocationProviderTest.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.location;
+
+import static androidx.test.ext.truth.location.LocationSubject.assertThat;
+
+import static com.android.internal.location.ProviderRequest.EMPTY_REQUEST;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.location.Criteria;
+import android.location.Location;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.location.ProviderProperties;
+import com.android.internal.location.ProviderRequest;
+import com.android.server.location.test.FakeProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.LinkedList;
+import java.util.List;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class MockableLocationProviderTest {
+
+ private Object mLock;
+ private ListenerCapture mListener;
+
+ private AbstractLocationProvider mRealProvider;
+ private MockProvider mMockProvider;
+
+ private MockableLocationProvider mProvider;
+
+ @Before
+ public void setUp() {
+ mLock = new Object();
+ mListener = new ListenerCapture();
+
+ mRealProvider = spy(new FakeProvider());
+ mMockProvider = spy(new MockProvider(new ProviderProperties(
+ false,
+ false,
+ false,
+ false,
+ true,
+ true,
+ true,
+ Criteria.POWER_LOW,
+ Criteria.ACCURACY_FINE)));
+
+ mProvider = new MockableLocationProvider(mLock, mListener);
+ mProvider.setRealProvider(mRealProvider);
+ }
+
+ @Test
+ public void testSetProvider() {
+ assertThat(mProvider.getProvider()).isEqualTo(mRealProvider);
+
+ mProvider.setMockProvider(mMockProvider);
+ assertThat(mProvider.getProvider()).isEqualTo(mMockProvider);
+
+ mProvider.setMockProvider(null);
+ assertThat(mProvider.getProvider()).isEqualTo(mRealProvider);
+
+ mProvider.setRealProvider(null);
+ assertThat(mProvider.getProvider()).isNull();
+ }
+
+ @Test
+ public void testSetRequest() {
+ assertThat(mProvider.getCurrentRequest()).isEqualTo(EMPTY_REQUEST);
+ verify(mRealProvider, times(1)).onSetRequest(EMPTY_REQUEST);
+
+ ProviderRequest request = new ProviderRequest.Builder().setInterval(1).build();
+ mProvider.setRequest(request);
+
+ assertThat(mProvider.getCurrentRequest()).isEqualTo(request);
+ verify(mRealProvider, times(1)).onSetRequest(request);
+
+ mProvider.setMockProvider(mMockProvider);
+ assertThat(mProvider.getCurrentRequest()).isEqualTo(request);
+ verify(mRealProvider, times(2)).onSetRequest(EMPTY_REQUEST);
+ verify(mMockProvider, times(1)).onSetRequest(request);
+
+ mProvider.setMockProvider(null);
+ assertThat(mProvider.getCurrentRequest()).isEqualTo(request);
+ verify(mMockProvider, times(1)).onSetRequest(EMPTY_REQUEST);
+ verify(mRealProvider, times(2)).onSetRequest(request);
+
+ mProvider.setRealProvider(null);
+ assertThat(mProvider.getCurrentRequest()).isEqualTo(request);
+ verify(mRealProvider, times(3)).onSetRequest(EMPTY_REQUEST);
+ }
+
+ @Test
+ public void testRequestSetAllowed() {
+ mProvider.requestSetAllowed(true);
+ verify(mRealProvider, times(1)).onRequestSetAllowed(true);
+
+ mProvider.setMockProvider(mMockProvider);
+ mProvider.requestSetAllowed(true);
+ verify(mMockProvider, times(1)).onRequestSetAllowed(true);
+ }
+
+ @Test
+ public void testSendExtraCommand() {
+ mProvider.sendExtraCommand(0, 0, "command", null);
+ verify(mRealProvider, times(1)).onExtraCommand(0, 0, "command", null);
+
+ mProvider.setMockProvider(mMockProvider);
+ mProvider.sendExtraCommand(0, 0, "command", null);
+ verify(mMockProvider, times(1)).onExtraCommand(0, 0, "command", null);
+ }
+
+ @Test
+ public void testSetState() {
+ assertThat(mProvider.getState().allowed).isFalse();
+
+ AbstractLocationProvider.State newState;
+
+ mRealProvider.setAllowed(true);
+ newState = mListener.getNextNewState();
+ assertThat(newState).isNotNull();
+ assertThat(newState.allowed).isTrue();
+
+ mProvider.setMockProvider(mMockProvider);
+ newState = mListener.getNextNewState();
+ assertThat(newState).isNotNull();
+ assertThat(newState.allowed).isFalse();
+
+ mMockProvider.setAllowed(true);
+ newState = mListener.getNextNewState();
+ assertThat(newState).isNotNull();
+ assertThat(newState.allowed).isTrue();
+
+ mRealProvider.setAllowed(false);
+ assertThat(mListener.getNextNewState()).isNull();
+
+ mProvider.setMockProvider(null);
+ newState = mListener.getNextNewState();
+ assertThat(newState).isNotNull();
+ assertThat(newState.allowed).isFalse();
+ }
+
+ @Test
+ public void testReportLocation() {
+ Location realLocation = new Location("real");
+ Location mockLocation = new Location("mock");
+
+ mRealProvider.reportLocation(realLocation);
+ assertThat(mListener.getNextLocation()).isEqualTo(realLocation);
+
+ mProvider.setMockProvider(mMockProvider);
+ mRealProvider.reportLocation(realLocation);
+ mMockProvider.reportLocation(mockLocation);
+ assertThat(mListener.getNextLocation()).isEqualTo(mockLocation);
+ }
+
+ private class ListenerCapture implements AbstractLocationProvider.Listener {
+
+ private final LinkedList<AbstractLocationProvider.State> mNewStates = new LinkedList<>();
+ private final LinkedList<Location> mLocations = new LinkedList<>();
+
+ @Override
+ public void onStateChanged(AbstractLocationProvider.State oldState,
+ AbstractLocationProvider.State newState) {
+ assertThat(Thread.holdsLock(mLock)).isTrue();
+ mNewStates.add(newState);
+ }
+
+ private AbstractLocationProvider.State getNextNewState() {
+ return mNewStates.poll();
+ }
+
+ @Override
+ public void onReportLocation(Location location) {
+ assertThat(Thread.holdsLock(mLock)).isTrue();
+ mLocations.add(location);
+ }
+
+ private Location getNextLocation() {
+ return mLocations.poll();
+ }
+
+ @Override
+ public void onReportLocation(List<Location> locations) {}
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/location/test/FakeProvider.java b/services/tests/servicestests/src/com/android/server/location/test/FakeProvider.java
new file mode 100644
index 000000000000..762080fe5745
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/location/test/FakeProvider.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location.test;
+
+import android.os.Bundle;
+
+import com.android.internal.location.ProviderRequest;
+import com.android.server.location.AbstractLocationProvider;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Collections;
+
+public class FakeProvider extends AbstractLocationProvider {
+
+ public FakeProvider() {
+ super(Runnable::run, Collections.emptySet());
+ }
+
+ @Override
+ protected void onSetRequest(ProviderRequest request) {}
+
+ @Override
+ protected void onExtraCommand(int uid, int pid, String command, Bundle extras) {}
+
+ @Override
+ protected void onRequestSetAllowed(boolean allowed) {}
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {}
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 2469cec5766e..118c540a4131 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -336,9 +336,6 @@ public final class UserManagerTest {
assertThat(userInfo).isNotNull();
final int userId = userInfo.id;
- UserManager userManagerForUser = (UserManager) mContext.createPackageContextAsUser(
- "android", 0, asHandle(userId)).getSystemService(Context.USER_SERVICE);
-
assertThat(mUserManager.hasBadge(userId)).isEqualTo(userTypeDetails.hasBadge());
assertThat(mUserManager.getUserIconBadgeResId(userId))
.isEqualTo(userTypeDetails.getIconBadge());
@@ -346,17 +343,18 @@ public final class UserManagerTest {
.isEqualTo(userTypeDetails.getBadgePlain());
assertThat(mUserManager.getUserBadgeNoBackgroundResId(userId))
.isEqualTo(userTypeDetails.getBadgeNoBackground());
- assertThat(mUserManager.isUserOfType(asHandle(userId), userTypeDetails.getName()))
- .isTrue();
- assertThat(userManagerForUser.isProfile()).isEqualTo(userTypeDetails.isProfile());
- assertThat(userManagerForUser.isUserOfType(asHandle(userId), userTypeDetails.getName()))
- .isTrue();
final int badgeIndex = userInfo.profileBadge;
assertThat(mUserManager.getUserBadgeColor(userId)).isEqualTo(
Resources.getSystem().getColor(userTypeDetails.getBadgeColor(badgeIndex), null));
assertThat(mUserManager.getBadgedLabelForUser("Test", asHandle(userId))).isEqualTo(
Resources.getSystem().getString(userTypeDetails.getBadgeLabel(badgeIndex), "Test"));
+
+ // Test @UserHandleAware methods
+ final UserManager userManagerForUser = UserManager.get(mContext.createPackageContextAsUser(
+ "android", 0, asHandle(userId)));
+ assertThat(userManagerForUser.isUserOfType(userTypeDetails.getName())).isTrue();
+ assertThat(userManagerForUser.isProfile()).isEqualTo(userTypeDetails.isProfile());
}
// Make sure only max managed profiles can be created
diff --git a/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java b/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
index f871203728c0..3ceaac207680 100644
--- a/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
import android.content.pm.VersionedPackage;
import android.content.rollback.PackageRollbackInfo;
@@ -34,12 +35,15 @@ import android.content.rollback.PackageRollbackInfo.RestoreInfo;
import android.util.IntArray;
import android.util.SparseLongArray;
+import com.android.server.pm.ApexManager;
import com.android.server.pm.Installer;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.InOrder;
+import org.mockito.Mock;
import org.mockito.Mockito;
import java.io.File;
@@ -48,10 +52,17 @@ import java.util.ArrayList;
@RunWith(JUnit4.class)
public class AppDataRollbackHelperTest {
+ @Mock private ApexManager mApexManager;
+
+ @Before
+ public void setUp() {
+ initMocks(this);
+ }
+
@Test
public void testSnapshotAppData() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+ AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer, mApexManager));
// All users are unlocked so we should snapshot data for them.
doReturn(true).when(helper).isUserCredentialLocked(eq(10));
@@ -114,7 +125,7 @@ public class AppDataRollbackHelperTest {
@Test
public void testRestoreAppDataSnapshot_pendingBackupForUser() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+ AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer, mApexManager));
PackageRollbackInfo info = createPackageRollbackInfo("com.foo");
IntArray pendingBackups = info.getPendingBackups();
@@ -139,7 +150,7 @@ public class AppDataRollbackHelperTest {
@Test
public void testRestoreAppDataSnapshot_availableBackupForLockedUser() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+ AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer, mApexManager));
doReturn(true).when(helper).isUserCredentialLocked(eq(10));
PackageRollbackInfo info = createPackageRollbackInfo("com.foo");
@@ -163,7 +174,7 @@ public class AppDataRollbackHelperTest {
@Test
public void testRestoreAppDataSnapshot_availableBackupForUnlockedUser() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+ AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer, mApexManager));
doReturn(false).when(helper).isUserCredentialLocked(eq(10));
PackageRollbackInfo info = createPackageRollbackInfo("com.foo");
@@ -184,7 +195,7 @@ public class AppDataRollbackHelperTest {
@Test
public void destroyAppData() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = new AppDataRollbackHelper(installer);
+ AppDataRollbackHelper helper = new AppDataRollbackHelper(installer, mApexManager);
PackageRollbackInfo info = createPackageRollbackInfo("com.foo.bar");
info.putCeSnapshotInode(11, 239L);
@@ -206,7 +217,7 @@ public class AppDataRollbackHelperTest {
@Test
public void commitPendingBackupAndRestoreForUser() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = new AppDataRollbackHelper(installer);
+ AppDataRollbackHelper helper = new AppDataRollbackHelper(installer, mApexManager);
when(installer.snapshotAppData(anyString(), anyInt(), anyInt(), anyInt())).thenReturn(53L);
diff --git a/core/java/com/android/internal/logging/testing/InstanceIdSequenceFake.java b/services/tests/uiservicestests/src/com/android/internal/logging/InstanceIdSequenceFake.java
index 0fd40b9ceb06..1629ef00b65a 100644
--- a/core/java/com/android/internal/logging/testing/InstanceIdSequenceFake.java
+++ b/services/tests/uiservicestests/src/com/android/internal/logging/InstanceIdSequenceFake.java
@@ -14,12 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.logging.testing;
-
-import android.annotation.SuppressLint;
-
-import com.android.internal.logging.InstanceId;
-import com.android.internal.logging.InstanceIdSequence;
+package com.android.internal.logging;
/**
* A fake implementation of InstanceIdSequence that returns 0, 1, 2, ...
@@ -30,27 +25,15 @@ public class InstanceIdSequenceFake extends InstanceIdSequence {
super(instanceIdMax);
}
- /**
- * Extend InstanceId to add a constructor we can call, strictly for testing purposes.
- * Public so that tests can check whether the InstanceIds they see are fake.
- */
- public static class InstanceIdFake extends InstanceId {
- @SuppressLint("VisibleForTests") // This is test infrastructure, which ought to count
- InstanceIdFake(int id) {
- super(id);
- }
- }
-
private int mNextId = 0;
@Override
public InstanceId newInstanceId() {
synchronized (this) {
- ++mNextId;
if (mNextId >= mInstanceIdMax) {
mNextId = 0;
}
- return new InstanceIdFake(mNextId);
+ return newInstanceIdInternal(mNextId++);
}
}
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 651ad40a4781..f029bc80480a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -72,6 +72,8 @@ import android.view.accessibility.IAccessibilityManagerClient;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.logging.InstanceIdSequence;
+import com.android.internal.logging.InstanceIdSequenceFake;
import com.android.internal.util.IntPair;
import com.android.server.UiServiceTestCase;
import com.android.server.lights.LogicalLight;
@@ -99,6 +101,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
@Mock
IAccessibilityManager mAccessibilityService;
NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
+ private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
+ 1 << 30);
private NotificationManagerService mService;
private String mPkg = "com.android.server.notification";
@@ -149,7 +153,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt());
assertTrue(accessibilityManager.isEnabled());
- mService = spy(new NotificationManagerService(getContext(), mNotificationRecordLogger));
+ mService = spy(new NotificationManagerService(getContext(), mNotificationRecordLogger,
+ mNotificationInstanceIdSequence));
mService.setAudioManager(mAudioManager);
mService.setVibrator(mVibrator);
mService.setSystemReady(true);
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 768b4721a1ee..2cf5eaefcc58 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -148,6 +148,8 @@ import androidx.test.InstrumentationRegistry;
import com.android.internal.R;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.internal.logging.InstanceIdSequence;
+import com.android.internal.logging.InstanceIdSequenceFake;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.LocalServices;
@@ -257,7 +259,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Mock
NotificationHistoryManager mHistoryManager;
NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
-
+ private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
+ 1 << 30);
// Use a Testable subclass so we can simulate calls from the system without failing.
private static class TestableNotificationManagerService extends NotificationManagerService {
@@ -267,8 +270,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Nullable
NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback;
- TestableNotificationManagerService(Context context, NotificationRecordLogger logger) {
- super(context, logger);
+ TestableNotificationManagerService(Context context, NotificationRecordLogger logger,
+ InstanceIdSequence notificationInstanceIdSequence) {
+ super(context, logger, notificationInstanceIdSequence);
}
@Override
@@ -355,7 +359,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
- mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger);
+ mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger,
+ mNotificationInstanceIdSequence);
// Use this testable looper.
mTestableLooper = TestableLooper.get(this);
@@ -1135,6 +1140,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
assertEquals(PKG, call.r.sbn.getPackageName());
assertEquals(0, call.r.sbn.getId());
assertEquals(tag, call.r.sbn.getTag());
+ assertNotNull(call.r.sbn.getInstanceId());
+ assertEquals(0, call.r.sbn.getInstanceId().getId());
}
@Test
@@ -1151,14 +1158,19 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, update, 0);
waitForIdle();
assertEquals(2, mNotificationRecordLogger.getCalls().size());
+
assertTrue(mNotificationRecordLogger.get(0).shouldLog());
assertEquals(
NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED,
mNotificationRecordLogger.get(0).getUiEvent());
+ assertEquals(0, mNotificationRecordLogger.get(0).r.sbn.getInstanceId().getId());
+
+ assertTrue(mNotificationRecordLogger.get(1).shouldLog());
assertEquals(
NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_UPDATED,
mNotificationRecordLogger.get(1).getUiEvent());
- assertTrue(mNotificationRecordLogger.get(1).shouldLog());
+ // Instance ID doesn't change on update of an active notification
+ assertEquals(0, mNotificationRecordLogger.get(1).r.sbn.getInstanceId().getId());
}
@Test
@@ -1175,6 +1187,34 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testEnqueueNotificationWithTag_LogsAgainAfterCancel() throws Exception {
+ final String tag = "testEnqueueNotificationWithTag_LogsAgainAfterCancel";
+ Notification notification = new Notification.Builder(mContext,
+ mTestNotificationChannel.getId())
+ .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, notification, 0);
+ waitForIdle();
+ mBinderService.cancelNotificationWithTag(PKG, PKG, tag, 0, 0);
+ waitForIdle();
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, notification, 0);
+ waitForIdle();
+ assertEquals(2, mNotificationRecordLogger.getCalls().size());
+
+ assertTrue(mNotificationRecordLogger.get(0).shouldLog());
+ assertEquals(
+ NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED,
+ mNotificationRecordLogger.get(0).getUiEvent());
+ assertEquals(0, mNotificationRecordLogger.get(0).r.sbn.getInstanceId().getId());
+
+ assertTrue(mNotificationRecordLogger.get(1).shouldLog());
+ assertEquals(
+ NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED,
+ mNotificationRecordLogger.get(1).getUiEvent());
+ // New instance ID because notification was canceled before re-post
+ assertEquals(1, mNotificationRecordLogger.get(1).r.sbn.getInstanceId().getId());
+ }
+
+ @Test
public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
mBinderService.enqueueNotificationWithTag(PKG, PKG,
"testCancelNotificationImmediatelyAfterEnqueue", 0,
@@ -2309,7 +2349,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void testHasCompanionDevice_noService() {
- mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger);
+ mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger,
+ mNotificationInstanceIdSequence);
assertFalse(mService.hasCompanionDevice(mListener));
}
@@ -4679,8 +4720,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
// cross user, with permission, no problem
- TestablePermissions perms = mContext.getTestablePermissions();
- perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED);
+ enableInteractAcrossUsers();
mBinderService.canNotifyAsPackage("src", "target", mContext.getUserId() + 1);
}
@@ -4698,8 +4738,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
// cross user, with permission, no problem
- TestablePermissions perms = mContext.getTestablePermissions();
- perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED);
+ enableInteractAcrossUsers();
mBinderService.getNotificationChannels("src", "target", mContext.getUserId() + 1);
}
@@ -5317,8 +5356,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
// cross user, with permission, no problem
- TestablePermissions perms = mContext.getTestablePermissions();
- perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED);
+ enableInteractAcrossUsers();
mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
mUid + UserHandle.PER_USER_RANGE);
}
@@ -5334,12 +5372,16 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
// cross user, with permission, no problem
- TestablePermissions perms = mContext.getTestablePermissions();
- perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED);
+ enableInteractAcrossUsers();
mBinderService.areBubblesAllowedForPackage(mContext.getPackageName(),
mUid + UserHandle.PER_USER_RANGE);
}
+ private void enableInteractAcrossUsers() {
+ TestablePermissions perms = mContext.getTestablePermissions();
+ perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED);
+ }
+
@Test
public void testNotificationBubbleChanged_false() throws Exception {
// Bubbles are allowed!
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
index 11972fd6a8dc..5c1487f0fdf6 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
@@ -23,7 +23,7 @@ import java.util.List;
* Fake implementation of NotificationRecordLogger, for testing.
*/
class NotificationRecordLoggerFake implements NotificationRecordLogger {
- class CallRecord extends NotificationRecordPair {
+ static class CallRecord extends NotificationRecordPair {
public int position, buzzBeepBlink;
CallRecord(NotificationRecord r, NotificationRecord old, int position,
int buzzBeepBlink) {
@@ -35,7 +35,7 @@ class NotificationRecordLoggerFake implements NotificationRecordLogger {
return shouldLog(buzzBeepBlink);
}
}
- List<CallRecord> mCalls = new ArrayList<CallRecord>();
+ private List<CallRecord> mCalls = new ArrayList<CallRecord>();
List<CallRecord> getCalls() {
return mCalls;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
index e18c8919b645..64a980484539 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
@@ -54,6 +54,8 @@ import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.Pair;
+import com.android.internal.logging.InstanceIdSequence;
+import com.android.internal.logging.InstanceIdSequenceFake;
import com.android.server.LocalServices;
import com.android.server.UiServiceTestCase;
import com.android.server.lights.LightsManager;
@@ -92,12 +94,15 @@ public class RoleObserverTest extends UiServiceTestCase {
@Mock
private RoleManager mRoleManager;
NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
-
+ private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
+ 1 << 30);
private List<UserInfo> mUsers;
private static class TestableNotificationManagerService extends NotificationManagerService {
- TestableNotificationManagerService(Context context, NotificationRecordLogger logger) {
- super(context, logger);
+ TestableNotificationManagerService(Context context,
+ NotificationRecordLogger logger,
+ InstanceIdSequence notificationInstanceIdSequence) {
+ super(context, logger, notificationInstanceIdSequence);
}
@Override
@@ -120,7 +125,8 @@ public class RoleObserverTest extends UiServiceTestCase {
mUsers.add(new UserInfo(10, "second", 0));
when(mUm.getUsers()).thenReturn(mUsers);
- mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger);
+ mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger,
+ mNotificationInstanceIdSequence);
mRoleObserver = mService.new RoleObserver(mRoleManager, mPm, mExecutor);
try {
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index c3bead7162e6..e71225579989 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -119,18 +119,6 @@ public class InsetsPolicyTest extends WindowTestsBase {
assertNull(controls);
}
- @Test
- public void testControlsForDispatch_keyguard() {
- addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade");
- addWindow(TYPE_NAVIGATION_BAR, "navBar");
- mockKeyguardShowing();
-
- final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch();
- // The app must not control the top bar.
- assertNotNull(controls);
- assertEquals(1, controls.length);
- }
-
// TODO: adjust this test if we pretend to the app that it's still able to control it.
@Test
public void testControlsForDispatch_forceStatusBarVisible() {
@@ -159,6 +147,21 @@ public class InsetsPolicyTest extends WindowTestsBase {
}
@Test
+ public void testControlsForDispatch_statusBarForceShowNavigation_butFocusedAnyways() {
+ WindowState notifShade = addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade");
+ notifShade.mAttrs.privateFlags |= PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
+ addWindow(TYPE_NAVIGATION_BAR, "navBar");
+
+ mDisplayContent.getInsetsPolicy().updateBarControlTarget(notifShade);
+ InsetsSourceControl[] controls
+ = mDisplayContent.getInsetsStateController().getControlsForDispatch(notifShade);
+
+ // The app controls the navigation bar.
+ assertNotNull(controls);
+ assertEquals(1, controls.length);
+ }
+
+ @Test
public void testShowTransientBars_bothCanBeTransient_appGetsBothFakeControls() {
addWindow(TYPE_STATUS_BAR, "statusBar")
.getControllableInsetProvider().getSource().setVisible(false);
@@ -260,10 +263,4 @@ public class InsetsPolicyTest extends WindowTestsBase {
mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);
return mDisplayContent.getInsetsStateController().getControlsForDispatch(win);
}
-
- private void mockKeyguardShowing() {
- final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
- spyOn(displayPolicy);
- doReturn(true).when(displayPolicy).isKeyguardShowing();
- }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index d819b1ada659..7ffdd7cdceb6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -57,7 +57,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
statusBar.getFrameLw().set(0, 0, 500, 100);
statusBar.mHasSurface = true;
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
mProvider.onPostLayout();
assertEquals(new Rect(0, 0, 500, 100), mProvider.getSource().getFrame());
assertEquals(Insets.of(0, 100, 0, 0),
@@ -74,7 +74,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
ime.getGivenContentInsetsLw().set(0, 0, 0, 60);
ime.getGivenVisibleInsetsLw().set(0, 0, 0, 75);
ime.mHasSurface = true;
- mProvider.setWindow(ime, null);
+ mProvider.setWindow(ime, null, null);
mProvider.onPostLayout();
assertEquals(new Rect(0, 0, 500, 40), mProvider.getSource().getFrame());
assertEquals(new Rect(0, 0, 500, 25), mProvider.getSource().getVisibleFrame());
@@ -89,7 +89,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
public void testPostLayout_invisible() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
statusBar.getFrameLw().set(0, 0, 500, 100);
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
mProvider.onPostLayout();
assertEquals(Insets.NONE, mProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
false /* ignoreVisibility */));
@@ -102,7 +102,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
mProvider.setWindow(statusBar,
(displayFrames, windowState, rect) -> {
rect.set(10, 10, 20, 20);
- });
+ }, null);
mProvider.onPostLayout();
assertEquals(new Rect(10, 10, 20, 20), mProvider.getSource().getFrame());
}
@@ -112,7 +112,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
statusBar.getFrameLw().set(0, 0, 500, 100);
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
mProvider.updateControlForTarget(target, false /* force */);
assertNotNull(mProvider.getControl(target));
mProvider.updateControlForTarget(null, false /* force */);
@@ -124,7 +124,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
statusBar.getFrameLw().set(0, 0, 500, 100);
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
mProvider.updateControlForFakeTarget(target);
assertNotNull(mProvider.getControl(target));
assertNull(mProvider.getControl(target).getLeash());
@@ -137,7 +137,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
statusBar.getFrameLw().set(0, 0, 500, 100);
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
mProvider.updateControlForTarget(target, false /* force */);
InsetsState state = new InsetsState();
state.getSource(ITYPE_STATUS_BAR).setVisible(false);
@@ -150,7 +150,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
statusBar.getFrameLw().set(0, 0, 500, 100);
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
InsetsState state = new InsetsState();
state.getSource(ITYPE_STATUS_BAR).setVisible(false);
mProvider.onInsetsModified(target, state.getSource(ITYPE_STATUS_BAR));
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index d13baeccb68a..39cdd2cb907e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -21,26 +21,26 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.test.InsetsModeSession;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.SmallTest;
-
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.SmallTest;
+
@SmallTest
@FlakyTest(detail = "Promote to pre-submit once confirmed stable.")
@Presubmit
@@ -65,7 +65,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
public void testStripForDispatch_notOwn() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
+ getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR));
assertNotNull(getController().getInsetsForDispatch(app).getSource(ITYPE_STATUS_BAR));
}
@@ -74,7 +74,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
public void testStripForDispatch_own() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
- .setWindow(statusBar, null);
+ .setWindow(statusBar, null, null);
statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR));
final InsetsState state = getController().getInsetsForDispatch(statusBar);
for (int i = state.getSourcesCount() - 1; i >= 0; i--) {
@@ -88,19 +88,36 @@ public class InsetsStateControllerTest extends WindowTestsBase {
final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
- getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
- getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null);
- getController().getSourceProvider(ITYPE_IME).setWindow(ime, null);
+ getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
+ getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null, null);
+ getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null);
assertEquals(0, getController().getInsetsForDispatch(navBar).getSourcesCount());
}
@Test
+ public void testImeForDispatch() {
+ final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+ final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
+ InsetsSourceProvider statusBarProvider =
+ getController().getSourceProvider(ITYPE_STATUS_BAR);
+ statusBarProvider.setWindow(statusBar, null, ((displayFrames, windowState, rect) ->
+ rect.set(0, 1, 2, 3)));
+ getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null);
+ statusBar.setControllableInsetProvider(statusBarProvider);
+
+ statusBarProvider.onPostLayout();
+
+ final InsetsState state = getController().getInsetsForDispatch(ime);
+ assertEquals(new Rect(0, 1, 2, 3), state.getSource(ITYPE_STATUS_BAR).getFrame());
+ }
+
+ @Test
public void testBarControllingWinChanged() {
final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
- getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null);
+ getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
+ getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null, null);
getController().onBarControlTargetChanged(app, null, app, null);
InsetsSourceControl[] controls = getController().getControlsForDispatch(app);
assertEquals(2, controls.length);
@@ -110,7 +127,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
public void testControlRevoked() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
+ getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
getController().onBarControlTargetChanged(app, null, null, null);
assertNotNull(getController().getControlsForDispatch(app));
getController().onBarControlTargetChanged(null, null, null, null);
@@ -122,7 +139,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
public void testControlRevoked_animation() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
+ getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
getController().onBarControlTargetChanged(app, null, null, null);
assertNotNull(getController().getControlsForDispatch(app));
statusBar.cancelAnimation();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 186ff6b1515b..2c68cc7a19bf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -425,7 +425,7 @@ public class WindowStateTests extends WindowTestsBase {
statusBar.mHasSurface = true;
assertTrue(statusBar.isVisible());
mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
- .setWindow(statusBar, null /* frameProvider */);
+ .setWindow(statusBar, null /* frameProvider */, null /* imeFrameProvider */);
mDisplayContent.getInsetsStateController().onBarControlTargetChanged(
app, null /* fakeTopControlling */, app, null /* fakeNavControlling */);
final InsetsSource source = new InsetsSource(ITYPE_STATUS_BAR);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 20eab5a45ff1..8e362ae4c59a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -110,7 +110,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
beforeCreateDisplay();
context.getDisplay().getDisplayInfo(mDisplayInfo);
- mDisplayContent = createNewDisplay();
+ mDisplayContent = createNewDisplay(true /* supportIme */);
// Set-up some common windows.
mCommonWindows = new HashSet<>();
@@ -349,16 +349,29 @@ class WindowTestsBase extends SystemServiceTestsBase {
return WindowTestUtils.createTaskInStack(mWm, stack, userId);
}
- /** Creates a {@link DisplayContent} and adds it to the system. */
+ /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */
DisplayContent createNewDisplay() {
- return createNewDisplay(mDisplayInfo);
+ return createNewDisplay(true /* supportIme */);
}
/** Creates a {@link DisplayContent} and adds it to the system. */
+ private DisplayContent createNewDisplay(boolean supportIme) {
+ return createNewDisplay(mDisplayInfo, supportIme);
+ }
+
+ /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */
DisplayContent createNewDisplay(DisplayInfo info) {
+ return createNewDisplay(info, true /* supportIme */);
+ }
+
+ /** Creates a {@link DisplayContent} and adds it to the system. */
+ private DisplayContent createNewDisplay(DisplayInfo info, boolean supportIme) {
final DisplayContent display =
new TestDisplayContent.Builder(mWm.mAtmService, info).build();
- return display.mDisplayContent;
+ final DisplayContent dc = display.mDisplayContent;
+ // this display can show IME.
+ dc.mWmService.mDisplayWindowSettings.setShouldShowImeLocked(dc, supportIme);
+ return dc;
}
/**
@@ -372,7 +385,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
DisplayInfo displayInfo = new DisplayInfo();
displayInfo.copyFrom(mDisplayInfo);
displayInfo.state = displayState;
- return createNewDisplay(displayInfo);
+ return createNewDisplay(displayInfo, true /* supportIme */);
}
/** Creates a {@link com.android.server.wm.WindowTestUtils.TestWindowState} */
@@ -389,7 +402,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
displayInfo.copyFrom(mDisplayInfo);
displayInfo.type = Display.TYPE_VIRTUAL;
displayInfo.ownerUid = SYSTEM_UID;
- return createNewDisplay(displayInfo);
+ return createNewDisplay(displayInfo, false /* supportIme */);
}
/** Sets the default minimum task size to 1 so that tests can use small task sizes */
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index 9967bebf20b8..140a95d61100 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -34,9 +34,9 @@ import android.service.usb.UsbIsHeadsetProto;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Slog;
-import android.util.StatsLog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.dump.DualDumpOutputStream;
import com.android.server.usb.descriptors.UsbDescriptor;
@@ -418,10 +418,11 @@ public class UsbHostManager {
parser.getRawDescriptors());
// Stats collection
- StatsLog.write(StatsLog.USB_DEVICE_ATTACHED, newDevice.getVendorId(),
- newDevice.getProductId(), parser.hasAudioInterface(),
- parser.hasHIDInterface(), parser.hasStorageInterface(),
- StatsLog.USB_DEVICE_ATTACHED__STATE__STATE_CONNECTED, 0);
+ FrameworkStatsLog.write(FrameworkStatsLog.USB_DEVICE_ATTACHED,
+ newDevice.getVendorId(), newDevice.getProductId(),
+ parser.hasAudioInterface(), parser.hasHIDInterface(),
+ parser.hasStorageInterface(),
+ FrameworkStatsLog.USB_DEVICE_ATTACHED__STATE__STATE_CONNECTED, 0);
}
}
@@ -454,10 +455,10 @@ public class UsbHostManager {
UsbDescriptorParser parser = new UsbDescriptorParser(deviceAddress,
current.mDescriptors);
// Stats collection
- StatsLog.write(StatsLog.USB_DEVICE_ATTACHED, device.getVendorId(),
- device.getProductId(), parser.hasAudioInterface(),
+ FrameworkStatsLog.write(FrameworkStatsLog.USB_DEVICE_ATTACHED,
+ device.getVendorId(), device.getProductId(), parser.hasAudioInterface(),
parser.hasHIDInterface(), parser.hasStorageInterface(),
- StatsLog.USB_DEVICE_ATTACHED__STATE__STATE_DISCONNECTED,
+ FrameworkStatsLog.USB_DEVICE_ATTACHED__STATE__STATE_DISCONNECTED,
System.currentTimeMillis() - current.mTimestamp);
}
} else {
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index c3e2013eff10..1025bf5d67b0 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -66,11 +66,11 @@ import android.service.usb.UsbServiceProto;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
-import android.util.StatsLog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.dump.DualDumpOutputStream;
import com.android.server.FgThread;
@@ -1040,8 +1040,9 @@ public class UsbPortManager {
if (mConnected.containsKey(portInfo.mUsbPort.getId())) {
//Previous logged a connected. Set it to disconnected.
if (mConnected.get(portInfo.mUsbPort.getId())) {
- StatsLog.write(StatsLog.USB_CONNECTOR_STATE_CHANGED,
- StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_DISCONNECTED,
+ FrameworkStatsLog.write(FrameworkStatsLog.USB_CONNECTOR_STATE_CHANGED,
+ FrameworkStatsLog
+ .USB_CONNECTOR_STATE_CHANGED__STATE__STATE_DISCONNECTED,
portInfo.mUsbPort.getId(), portInfo.mLastConnectDurationMillis);
}
mConnected.remove(portInfo.mUsbPort.getId());
@@ -1051,7 +1052,7 @@ public class UsbPortManager {
//Previous logged a contaminant detected. Set it to not detected.
if ((mContaminantStatus.get(portInfo.mUsbPort.getId())
== UsbPortStatus.CONTAMINANT_DETECTION_DETECTED)) {
- StatsLog.write(StatsLog.USB_CONTAMINANT_REPORTED,
+ FrameworkStatsLog.write(FrameworkStatsLog.USB_CONTAMINANT_REPORTED,
portInfo.mUsbPort.getId(),
convertContaminantDetectionStatusToProto(
UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED));
@@ -1065,10 +1066,10 @@ public class UsbPortManager {
|| (mConnected.get(portInfo.mUsbPort.getId())
!= portInfo.mUsbPortStatus.isConnected())) {
mConnected.put(portInfo.mUsbPort.getId(), portInfo.mUsbPortStatus.isConnected());
- StatsLog.write(StatsLog.USB_CONNECTOR_STATE_CHANGED,
+ FrameworkStatsLog.write(FrameworkStatsLog.USB_CONNECTOR_STATE_CHANGED,
portInfo.mUsbPortStatus.isConnected()
- ? StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_CONNECTED :
- StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_DISCONNECTED,
+ ? FrameworkStatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_CONNECTED :
+ FrameworkStatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_DISCONNECTED,
portInfo.mUsbPort.getId(), portInfo.mLastConnectDurationMillis);
}
@@ -1077,7 +1078,7 @@ public class UsbPortManager {
!= portInfo.mUsbPortStatus.getContaminantDetectionStatus())) {
mContaminantStatus.put(portInfo.mUsbPort.getId(),
portInfo.mUsbPortStatus.getContaminantDetectionStatus());
- StatsLog.write(StatsLog.USB_CONTAMINANT_REPORTED,
+ FrameworkStatsLog.write(FrameworkStatsLog.USB_CONTAMINANT_REPORTED,
portInfo.mUsbPort.getId(),
convertContaminantDetectionStatusToProto(
portInfo.mUsbPortStatus.getContaminantDetectionStatus()));
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
index b230e4bbf8a2..43d5bf323abb 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -292,9 +292,27 @@ public final class UsbDescriptorParser {
// Clean up
descriptor.postParse(stream);
} catch (Exception ex) {
- Log.e(TAG, "Exception parsing USB descriptors.", ex);
+ // Clean up, compute error status
+ descriptor.postParse(stream);
- // Clean up
+ // Report
+ Log.w(TAG, "Exception parsing USB descriptors. type:0x" + descriptor.getType()
+ + " status:" + descriptor.getStatus());
+ if (DEBUG) {
+ // Show full stack trace if debugging
+ Log.e(TAG, "Exception parsing USB descriptors.", ex);
+ }
+ StackTraceElement[] stackElems = ex.getStackTrace();
+ if (stackElems.length > 0) {
+ Log.i(TAG, " class:" + stackElems[0].getClassName()
+ + " @ " + stackElems[0].getLineNumber());
+ }
+ if (stackElems.length > 1) {
+ Log.i(TAG, " class:" + stackElems[1].getClassName()
+ + " @ " + stackElems[1].getLineNumber());
+ }
+
+ // Finish up
descriptor.setStatus(UsbDescriptor.STATUS_PARSE_EXCEPTION);
} finally {
mDescriptors.add(descriptor);
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index 3f0aeb54f132..0c2f1f325793 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -69,8 +69,8 @@ public abstract class CellIdentity implements Parcelable {
protected String mAlphaShort;
/** @hide */
- protected CellIdentity(String tag, int type, String mcc, String mnc, String alphal,
- String alphas) {
+ protected CellIdentity(@Nullable String tag, int type, @Nullable String mcc,
+ @Nullable String mnc, @Nullable String alphal, @Nullable String alphas) {
mTag = tag;
mType = type;
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index 1a6bf33cec71..e220b07d703a 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.telephony.cdma.CdmaCellLocation;
@@ -90,8 +91,8 @@ public final class CellIdentityCdma extends CellIdentity {
*
* @hide
*/
- public CellIdentityCdma(
- int nid, int sid, int bid, int lon, int lat, String alphal, String alphas) {
+ public CellIdentityCdma(int nid, int sid, int bid, int lon, int lat,
+ @Nullable String alphal, @Nullable String alphas) {
super(TAG, CellInfo.TYPE_CDMA, null, null, alphal, alphas);
mNetworkId = inRangeOrUnavailable(nid, 0, NETWORK_ID_MAX);
mSystemId = inRangeOrUnavailable(sid, 0, SYSTEM_ID_MAX);
@@ -108,22 +109,22 @@ public final class CellIdentityCdma extends CellIdentity {
}
/** @hide */
- public CellIdentityCdma(android.hardware.radio.V1_0.CellIdentityCdma cid) {
+ public CellIdentityCdma(@NonNull android.hardware.radio.V1_0.CellIdentityCdma cid) {
this(cid.networkId, cid.systemId, cid.baseStationId, cid.longitude, cid.latitude, "", "");
}
/** @hide */
- public CellIdentityCdma(android.hardware.radio.V1_2.CellIdentityCdma cid) {
+ public CellIdentityCdma(@NonNull android.hardware.radio.V1_2.CellIdentityCdma cid) {
this(cid.base.networkId, cid.base.systemId, cid.base.baseStationId, cid.base.longitude,
cid.base.latitude, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort);
}
- private CellIdentityCdma(CellIdentityCdma cid) {
+ private CellIdentityCdma(@NonNull CellIdentityCdma cid) {
this(cid.mNetworkId, cid.mSystemId, cid.mBasestationId, cid.mLongitude, cid.mLatitude,
cid.mAlphaLong, cid.mAlphaShort);
}
- CellIdentityCdma copy() {
+ @NonNull CellIdentityCdma copy() {
return new CellIdentityCdma(this);
}
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index dc73cbf735b0..9f2537c7ed10 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -23,6 +23,7 @@ import android.os.Parcel;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -78,26 +79,31 @@ public final class CellIdentityGsm extends CellIdentity {
*
* @hide
*/
- public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, String mccStr,
- String mncStr, String alphal, String alphas,
- List<String> additionalPlmns) {
+ public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, @Nullable String mccStr,
+ @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas,
+ @NonNull List<String> additionalPlmns) {
super(TAG, CellInfo.TYPE_GSM, mccStr, mncStr, alphal, alphas);
mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
mArfcn = inRangeOrUnavailable(arfcn, 0, MAX_ARFCN);
mBsic = inRangeOrUnavailable(bsic, 0, MAX_BSIC);
- mAdditionalPlmns = additionalPlmns;
+ mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+ for (String plmn : additionalPlmns) {
+ if (isValidPlmn(plmn)) {
+ mAdditionalPlmns.add(plmn);
+ }
+ }
}
/** @hide */
- public CellIdentityGsm(android.hardware.radio.V1_0.CellIdentityGsm cid) {
+ public CellIdentityGsm(@NonNull android.hardware.radio.V1_0.CellIdentityGsm cid) {
this(cid.lac, cid.cid, cid.arfcn,
cid.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.bsic,
cid.mcc, cid.mnc, "", "", Collections.emptyList());
}
/** @hide */
- public CellIdentityGsm(android.hardware.radio.V1_2.CellIdentityGsm cid) {
+ public CellIdentityGsm(@NonNull android.hardware.radio.V1_2.CellIdentityGsm cid) {
this(cid.base.lac, cid.base.cid, cid.base.arfcn,
cid.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.base.bsic, cid.base.mcc,
cid.base.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
@@ -105,7 +111,7 @@ public final class CellIdentityGsm extends CellIdentity {
}
/** @hide */
- public CellIdentityGsm(android.hardware.radio.V1_5.CellIdentityGsm cid) {
+ public CellIdentityGsm(@NonNull android.hardware.radio.V1_5.CellIdentityGsm cid) {
this(cid.base.base.lac, cid.base.base.cid, cid.base.base.arfcn,
cid.base.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE
: cid.base.base.bsic, cid.base.base.mcc,
@@ -113,12 +119,12 @@ public final class CellIdentityGsm extends CellIdentity {
cid.base.operatorNames.alphaShort, cid.additionalPlmns);
}
- private CellIdentityGsm(CellIdentityGsm cid) {
+ private CellIdentityGsm(@NonNull CellIdentityGsm cid) {
this(cid.mLac, cid.mCid, cid.mArfcn, cid.mBsic, cid.mMccStr,
cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns);
}
- CellIdentityGsm copy() {
+ @NonNull CellIdentityGsm copy() {
return new CellIdentityGsm(this);
}
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index cf8fe6a3c345..a194ae35216c 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -24,6 +24,7 @@ import android.os.Parcel;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -104,34 +105,40 @@ public final class CellIdentityLte extends CellIdentity {
*
* @hide
*/
- public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth, String mccStr,
- String mncStr, String alphal, String alphas, List<String> additionalPlmns,
- ClosedSubscriberGroupInfo csgInfo) {
+ public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth,
+ @Nullable String mccStr, @Nullable String mncStr, @Nullable String alphal,
+ @Nullable String alphas, @NonNull List<String> additionalPlmns,
+ @Nullable ClosedSubscriberGroupInfo csgInfo) {
super(TAG, CellInfo.TYPE_LTE, mccStr, mncStr, alphal, alphas);
mCi = inRangeOrUnavailable(ci, 0, MAX_CI);
mPci = inRangeOrUnavailable(pci, 0, MAX_PCI);
mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
mEarfcn = inRangeOrUnavailable(earfcn, 0, MAX_EARFCN);
mBandwidth = inRangeOrUnavailable(bandwidth, 0, MAX_BANDWIDTH);
- mAdditionalPlmns = additionalPlmns;
+ mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+ for (String plmn : additionalPlmns) {
+ if (isValidPlmn(plmn)) {
+ mAdditionalPlmns.add(plmn);
+ }
+ }
mCsgInfo = csgInfo;
}
/** @hide */
- public CellIdentityLte(android.hardware.radio.V1_0.CellIdentityLte cid) {
+ public CellIdentityLte(@NonNull android.hardware.radio.V1_0.CellIdentityLte cid) {
this(cid.ci, cid.pci, cid.tac, cid.earfcn,
CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "", Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityLte(android.hardware.radio.V1_2.CellIdentityLte cid) {
+ public CellIdentityLte(@NonNull android.hardware.radio.V1_2.CellIdentityLte cid) {
this(cid.base.ci, cid.base.pci, cid.base.tac, cid.base.earfcn, cid.bandwidth,
cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
cid.operatorNames.alphaShort, Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityLte(android.hardware.radio.V1_5.CellIdentityLte cid) {
+ public CellIdentityLte(@NonNull android.hardware.radio.V1_5.CellIdentityLte cid) {
this(cid.base.base.ci, cid.base.base.pci, cid.base.base.tac, cid.base.base.earfcn,
cid.base.bandwidth, cid.base.base.mcc, cid.base.base.mnc,
cid.base.operatorNames.alphaLong, cid.base.operatorNames.alphaShort,
@@ -139,7 +146,7 @@ public final class CellIdentityLte extends CellIdentity {
? new ClosedSubscriberGroupInfo(cid.optionalCsgInfo.csgInfo()) : null);
}
- private CellIdentityLte(CellIdentityLte cid) {
+ private CellIdentityLte(@NonNull CellIdentityLte cid) {
this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mBandwidth, cid.mMccStr,
cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo);
}
@@ -152,7 +159,7 @@ public final class CellIdentityLte extends CellIdentity {
mMccStr, mMncStr, mAlphaLong, mAlphaShort, mAdditionalPlmns, null);
}
- CellIdentityLte copy() {
+ @NonNull CellIdentityLte copy() {
return new CellIdentityLte(this);
}
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index d4f181fc735a..a0ef5aa2feae 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -64,26 +64,32 @@ public final class CellIdentityNr extends CellIdentity {
* @hide
*/
public CellIdentityNr(int pci, int tac, int nrArfcn, @NgranBand List<Integer> bands,
- String mccStr, String mncStr, long nci, String alphal, String alphas,
- List<String> additionalPlmns) {
+ @Nullable String mccStr, @Nullable String mncStr, long nci,
+ @Nullable String alphal, @Nullable String alphas,
+ @NonNull List<String> additionalPlmns) {
super(TAG, CellInfo.TYPE_NR, mccStr, mncStr, alphal, alphas);
mPci = inRangeOrUnavailable(pci, 0, MAX_PCI);
mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
mNrArfcn = inRangeOrUnavailable(nrArfcn, 0, MAX_NRARFCN);
mBands = new ArrayList<>(bands);
mNci = inRangeOrUnavailable(nci, 0, MAX_NCI);
- mAdditionalPlmns = new ArrayList<>(additionalPlmns);
+ mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+ for (String plmn : additionalPlmns) {
+ if (isValidPlmn(plmn)) {
+ mAdditionalPlmns.add(plmn);
+ }
+ }
}
/** @hide */
- public CellIdentityNr(android.hardware.radio.V1_4.CellIdentityNr cid) {
+ public CellIdentityNr(@NonNull android.hardware.radio.V1_4.CellIdentityNr cid) {
this(cid.pci, cid.tac, cid.nrarfcn, Collections.emptyList(), cid.mcc, cid.mnc, cid.nci,
cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
Collections.emptyList());
}
/** @hide */
- public CellIdentityNr(android.hardware.radio.V1_5.CellIdentityNr cid) {
+ public CellIdentityNr(@NonNull android.hardware.radio.V1_5.CellIdentityNr cid) {
this(cid.base.pci, cid.base.tac, cid.base.nrarfcn, cid.bands, cid.base.mcc, cid.base.mnc,
cid.base.nci, cid.base.operatorNames.alphaLong,
cid.base.operatorNames.alphaShort, cid.additionalPlmns);
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 2ff351c17e9a..531487a313d9 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.os.Parcel;
import android.telephony.gsm.GsmCellLocation;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -82,39 +83,44 @@ public final class CellIdentityTdscdma extends CellIdentity {
*
* @hide
*/
- public CellIdentityTdscdma(String mcc, String mnc, int lac, int cid, int cpid, int uarfcn,
- String alphal, String alphas, @NonNull List<String> additionalPlmns,
- ClosedSubscriberGroupInfo csgInfo) {
+ public CellIdentityTdscdma(@Nullable String mcc, @Nullable String mnc, int lac, int cid,
+ int cpid, int uarfcn, @Nullable String alphal, @Nullable String alphas,
+ @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) {
super(TAG, CellInfo.TYPE_TDSCDMA, mcc, mnc, alphal, alphas);
mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
mCpid = inRangeOrUnavailable(cpid, 0, MAX_CPID);
mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN);
- mAdditionalPlmns = additionalPlmns;
+ mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+ for (String plmn : additionalPlmns) {
+ if (isValidPlmn(plmn)) {
+ mAdditionalPlmns.add(plmn);
+ }
+ }
mCsgInfo = csgInfo;
}
- private CellIdentityTdscdma(CellIdentityTdscdma cid) {
+ private CellIdentityTdscdma(@NonNull CellIdentityTdscdma cid) {
this(cid.mMccStr, cid.mMncStr, cid.mLac, cid.mCid,
cid.mCpid, cid.mUarfcn, cid.mAlphaLong,
cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo);
}
/** @hide */
- public CellIdentityTdscdma(android.hardware.radio.V1_0.CellIdentityTdscdma cid) {
+ public CellIdentityTdscdma(@NonNull android.hardware.radio.V1_0.CellIdentityTdscdma cid) {
this(cid.mcc, cid.mnc, cid.lac, cid.cid, cid.cpid, CellInfo.UNAVAILABLE, "", "",
Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityTdscdma(android.hardware.radio.V1_2.CellIdentityTdscdma cid) {
+ public CellIdentityTdscdma(@NonNull android.hardware.radio.V1_2.CellIdentityTdscdma cid) {
this(cid.base.mcc, cid.base.mnc, cid.base.lac, cid.base.cid, cid.base.cpid,
cid.uarfcn, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityTdscdma(android.hardware.radio.V1_5.CellIdentityTdscdma cid) {
+ public CellIdentityTdscdma(@NonNull android.hardware.radio.V1_5.CellIdentityTdscdma cid) {
this(cid.base.base.mcc, cid.base.base.mnc, cid.base.base.lac, cid.base.base.cid,
cid.base.base.cpid, cid.base.uarfcn, cid.base.operatorNames.alphaLong,
cid.base.operatorNames.alphaShort,
@@ -130,7 +136,7 @@ public final class CellIdentityTdscdma extends CellIdentity {
mAdditionalPlmns, null);
}
- CellIdentityTdscdma copy() {
+ @NonNull CellIdentityTdscdma copy() {
return new CellIdentityTdscdma(this);
}
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 9be42a17677b..15e491b66575 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -23,6 +23,7 @@ import android.os.Parcel;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -83,34 +84,38 @@ public final class CellIdentityWcdma extends CellIdentity {
*
* @hide
*/
- public CellIdentityWcdma (int lac, int cid, int psc, int uarfcn,
- String mccStr, String mncStr, String alphal, String alphas,
- @NonNull List<String> additionalPlmns,
- @Nullable ClosedSubscriberGroupInfo csgInfo) {
+ public CellIdentityWcdma(int lac, int cid, int psc, int uarfcn, @Nullable String mccStr,
+ @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas,
+ @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) {
super(TAG, CellInfo.TYPE_WCDMA, mccStr, mncStr, alphal, alphas);
mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
mPsc = inRangeOrUnavailable(psc, 0, MAX_PSC);
mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN);
- mAdditionalPlmns = additionalPlmns;
+ mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+ for (String plmn : additionalPlmns) {
+ if (isValidPlmn(plmn)) {
+ mAdditionalPlmns.add(plmn);
+ }
+ }
mCsgInfo = csgInfo;
}
/** @hide */
- public CellIdentityWcdma(android.hardware.radio.V1_0.CellIdentityWcdma cid) {
+ public CellIdentityWcdma(@NonNull android.hardware.radio.V1_0.CellIdentityWcdma cid) {
this(cid.lac, cid.cid, cid.psc, cid.uarfcn, cid.mcc, cid.mnc, "", "",
Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityWcdma(android.hardware.radio.V1_2.CellIdentityWcdma cid) {
+ public CellIdentityWcdma(@NonNull android.hardware.radio.V1_2.CellIdentityWcdma cid) {
this(cid.base.lac, cid.base.cid, cid.base.psc, cid.base.uarfcn,
cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
cid.operatorNames.alphaShort, Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityWcdma(android.hardware.radio.V1_5.CellIdentityWcdma cid) {
+ public CellIdentityWcdma(@NonNull android.hardware.radio.V1_5.CellIdentityWcdma cid) {
this(cid.base.base.lac, cid.base.base.cid, cid.base.base.psc, cid.base.base.uarfcn,
cid.base.base.mcc, cid.base.base.mnc, cid.base.operatorNames.alphaLong,
cid.base.operatorNames.alphaShort, cid.additionalPlmns,
@@ -118,7 +123,7 @@ public final class CellIdentityWcdma extends CellIdentity {
? new ClosedSubscriberGroupInfo(cid.optionalCsgInfo.csgInfo()) : null);
}
- private CellIdentityWcdma(CellIdentityWcdma cid) {
+ private CellIdentityWcdma(@NonNull CellIdentityWcdma cid) {
this(cid.mLac, cid.mCid, cid.mPsc, cid.mUarfcn, cid.mMccStr,
cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo);
}
@@ -131,7 +136,7 @@ public final class CellIdentityWcdma extends CellIdentity {
mAlphaLong, mAlphaShort, mAdditionalPlmns, null);
}
- CellIdentityWcdma copy() {
+ @NonNull CellIdentityWcdma copy() {
return new CellIdentityWcdma(this);
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 5cd7cf8fae8a..8e83c4c11992 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -2543,7 +2543,7 @@ public final class SmsManager {
MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE);
if (m != null) {
m.sendMultimediaMessage(getSubscriptionId(), contentUri, locationUrl, configOverrides,
- sentIntent);
+ sentIntent, 0L /* messageId */);
}
}
@@ -2581,7 +2581,7 @@ public final class SmsManager {
MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE);
if (m != null) {
m.downloadMultimediaMessage(getSubscriptionId(), locationUrl, contentUri,
- configOverrides, downloadedIntent);
+ configOverrides, downloadedIntent, 0L /* messageId */);
}
}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index 80491cd98bc9..0fdcbc52bffa 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -584,6 +584,25 @@ public class StagedRollbackTest {
assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
}
+ @Test
+ public void testRollbackApexDataDirectories_Phase1() throws Exception {
+ int sessionId = Install.single(TEST_APEX_WITH_APK_V2).setStaged().setEnableRollback()
+ .commit();
+ InstallUtils.waitForSessionReady(sessionId);
+ }
+
+ @Test
+ public void testRollbackApexDataDirectories_Phase2() throws Exception {
+ RollbackInfo available = RollbackUtils.getAvailableRollback(APK_IN_APEX_TESTAPEX_NAME);
+
+ RollbackUtils.rollback(available.getRollbackId(), TEST_APEX_WITH_APK_V2);
+ RollbackInfo committed = RollbackUtils.getCommittedRollbackById(available.getRollbackId());
+
+ // Note: The app is not rolled back until after the rollback is staged
+ // and the device has been rebooted.
+ InstallUtils.waitForSessionReady(committed.getCommittedSessionId());
+ }
+
private static void runShellCommand(String cmd) {
ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation().getUiAutomation()
.executeShellCommand(cmd);
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index 672cbb084dae..ce2f7c50e581 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -16,6 +16,8 @@
package com.android.tests.rollback.host;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import static org.testng.Assert.assertThrows;
@@ -53,6 +55,17 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test";
+ private static final String TEST_SUBDIR = "/subdir/";
+
+ private static final String TEST_FILENAME_1 = "test_file.txt";
+ private static final String TEST_STRING_1 = "hello this is a test";
+ private static final String TEST_FILENAME_2 = "another_file.txt";
+ private static final String TEST_STRING_2 = "this is a different file";
+ private static final String TEST_FILENAME_3 = "also.xyz";
+ private static final String TEST_STRING_3 = "also\n a\n test\n string";
+ private static final String TEST_FILENAME_4 = "one_more.test";
+ private static final String TEST_STRING_4 = "once more unto the test";
+
@Before
public void setUp() throws Exception {
if (!getDevice().isAdbRoot()) {
@@ -77,6 +90,10 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
getDevice().executeShellCommand(
"rm -f /system/apex/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex "
+ "/data/apex/active/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex");
+ getDevice().executeShellCommand(
+ "rm -rf " + apexDataDirDeSys(APK_IN_APEX_TESTAPEX_NAME) + "*");
+ getDevice().executeShellCommand(
+ "rm -rf " + apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + "*");
getDevice().reboot();
}
@@ -245,15 +262,7 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
@Test
public void testRollbackApexWithApk() throws Exception {
getDevice().uninstallPackage("com.android.cts.install.lib.testapp.A");
- CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
- final String fileName = APK_IN_APEX_TESTAPEX_NAME + "_v1.apex";
- final File apex = buildHelper.getTestFile(fileName);
- if (!getDevice().isAdbRoot()) {
- getDevice().enableAdbRoot();
- }
- getDevice().remountSystemWritable();
- assertTrue(getDevice().pushFile(apex, "/system/apex/" + fileName));
- getDevice().reboot();
+ pushTestApex();
runPhase("testRollbackApexWithApk_Phase1");
getDevice().reboot();
runPhase("testRollbackApexWithApk_Phase2");
@@ -267,15 +276,7 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
@Test
public void testRollbackApexWithApkCrashing() throws Exception {
getDevice().uninstallPackage("com.android.cts.install.lib.testapp.A");
- CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
- final String fileName = APK_IN_APEX_TESTAPEX_NAME + "_v1.apex";
- final File apex = buildHelper.getTestFile(fileName);
- if (!getDevice().isAdbRoot()) {
- getDevice().enableAdbRoot();
- }
- getDevice().remountSystemWritable();
- assertTrue(getDevice().pushFile(apex, "/system/apex/" + fileName));
- getDevice().reboot();
+ pushTestApex();
// Install an apex with apk that crashes
runPhase("testRollbackApexWithApkCrashing_Phase1");
@@ -289,6 +290,102 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
runPhase("testRollbackApexWithApkCrashing_Phase3");
}
+ /**
+ * Tests that data in DE_sys apex data directory is restored when apex is rolled back.
+ */
+ @Test
+ public void testRollbackApexDataDirectories_DeSys() throws Exception {
+ pushTestApex();
+
+ // Push files to apex data directory
+ String oldFilePath1 = apexDataDirDeSys(APK_IN_APEX_TESTAPEX_NAME) + "/" + TEST_FILENAME_1;
+ String oldFilePath2 =
+ apexDataDirDeSys(APK_IN_APEX_TESTAPEX_NAME) + TEST_SUBDIR + TEST_FILENAME_2;
+ assertTrue(getDevice().pushString(TEST_STRING_1, oldFilePath1));
+ assertTrue(getDevice().pushString(TEST_STRING_2, oldFilePath2));
+
+ // Install new version of the APEX with rollback enabled
+ runPhase("testRollbackApexDataDirectories_Phase1");
+ getDevice().reboot();
+
+ // Replace files in data directory
+ getDevice().deleteFile(oldFilePath1);
+ getDevice().deleteFile(oldFilePath2);
+ String newFilePath3 = apexDataDirDeSys(APK_IN_APEX_TESTAPEX_NAME) + "/" + TEST_FILENAME_3;
+ String newFilePath4 =
+ apexDataDirDeSys(APK_IN_APEX_TESTAPEX_NAME) + TEST_SUBDIR + TEST_FILENAME_4;
+ assertTrue(getDevice().pushString(TEST_STRING_3, newFilePath3));
+ assertTrue(getDevice().pushString(TEST_STRING_4, newFilePath4));
+
+ // Roll back the APEX
+ runPhase("testRollbackApexDataDirectories_Phase2");
+ getDevice().reboot();
+
+ // Verify that old files have been restored and new files are gone
+ assertEquals(TEST_STRING_1, getDevice().pullFileContents(oldFilePath1));
+ assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2));
+ assertNull(getDevice().pullFile(newFilePath3));
+ assertNull(getDevice().pullFile(newFilePath4));
+ }
+
+ /**
+ * Tests that data in CE apex data directory is restored when apex is rolled back.
+ */
+ @Test
+ public void testRollbackApexDataDirectories_Ce() throws Exception {
+ pushTestApex();
+
+ // Push files to apex data directory
+ String oldFilePath1 = apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + "/" + TEST_FILENAME_1;
+ String oldFilePath2 =
+ apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + TEST_SUBDIR + TEST_FILENAME_2;
+ assertTrue(getDevice().pushString(TEST_STRING_1, oldFilePath1));
+ assertTrue(getDevice().pushString(TEST_STRING_2, oldFilePath2));
+
+ // Install new version of the APEX with rollback enabled
+ runPhase("testRollbackApexDataDirectories_Phase1");
+ getDevice().reboot();
+
+ // Replace files in data directory
+ getDevice().deleteFile(oldFilePath1);
+ getDevice().deleteFile(oldFilePath2);
+ String newFilePath3 = apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + "/" + TEST_FILENAME_3;
+ String newFilePath4 =
+ apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + TEST_SUBDIR + TEST_FILENAME_4;
+ assertTrue(getDevice().pushString(TEST_STRING_3, newFilePath3));
+ assertTrue(getDevice().pushString(TEST_STRING_4, newFilePath4));
+
+ // Roll back the APEX
+ runPhase("testRollbackApexDataDirectories_Phase2");
+ getDevice().reboot();
+
+ // Verify that old files have been restored and new files are gone
+ assertEquals(TEST_STRING_1, getDevice().pullFileContents(oldFilePath1));
+ assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2));
+ assertNull(getDevice().pullFile(newFilePath3));
+ assertNull(getDevice().pullFile(newFilePath4));
+ }
+
+ private void pushTestApex() throws Exception {
+ CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
+ final String fileName = APK_IN_APEX_TESTAPEX_NAME + "_v1.apex";
+ final File apex = buildHelper.getTestFile(fileName);
+ if (!getDevice().isAdbRoot()) {
+ getDevice().enableAdbRoot();
+ }
+ getDevice().remountSystemWritable();
+ assertTrue(getDevice().pushFile(apex, "/system/apex/" + fileName));
+ getDevice().reboot();
+ }
+
+ private static String apexDataDirDeSys(String apexName) {
+ return String.format("/data/misc/apexdata/%s", apexName);
+ }
+
+ private static String apexDataDirCe(String apexName, int userId) {
+ return String.format("/data/misc_ce/%d/apexdata/%s", userId, apexName);
+ }
+
private void crashProcess(String processName, int numberOfCrashes) throws Exception {
String pid = "";
String lastPid = "invalid";
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 31b3a5064932..1f1c0c12cf21 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -123,8 +123,6 @@ interface IWifiManager
boolean isWifiStandardSupported(int standard);
- boolean needs5GHzToAnyApBandConversion();
-
DhcpInfo getDhcpInfo();
boolean isScanAlwaysAvailable();
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index f8d48c5403f7..7c031eaaeaf4 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -889,6 +889,13 @@ public class WifiInfo implements Parcelable {
*/
@Nullable
@SystemApi
+ public static String sanitizeSsid(@Nullable String string) {
+ return removeDoubleQuotes(string);
+ }
+
+ /** @hide */
+ @UnsupportedAppUsage
+ @Nullable
public static String removeDoubleQuotes(@Nullable String string) {
if (string == null) return null;
final int length = string.length();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 9a251062cd9e..76f97164032c 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2802,29 +2802,6 @@ public class WifiManager {
}
/**
- * Check if the device is dual mode capable i.e. supports concurrent STA + Soft AP.
- *
- * If the device is dual mode capable, it may require conversion of the user's Soft AP band
- * selection {@link SoftApConfiguration#mBand} from {@link SoftApConfiguration#BAND_5GHZ} to
- * include also {@link SoftApConfiguration#BAND_2GHZ}, since if the device is connected to a
- * 5GHz DFS channel as a STA, it may be unable to honor a request to start Soft AP on the same
- * DFS channel.
- *
- * @return {@code true} if dual mode STA + AP is supported by this device, {@code false}
- * otherwise.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public boolean isDualModeSupported() {
- try {
- return mService.needs5GHzToAnyApBandConversion();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Return the DHCP-assigned addresses from the last successful DHCP request,
* if any.
* @return the DHCP information
diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java
index b46755349ad7..060c85cac209 100644
--- a/wifi/java/com/android/server/wifi/BaseWifiService.java
+++ b/wifi/java/com/android/server/wifi/BaseWifiService.java
@@ -38,6 +38,7 @@ import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
@@ -268,7 +269,8 @@ public class BaseWifiService extends IWifiManager.Stub {
throw new UnsupportedOperationException();
}
- @Override
+ /** @deprecated use {@link WifiManager#isStaApConcurrencySupported()} */
+ @Deprecated
public boolean needs5GHzToAnyApBandConversion() {
throw new UnsupportedOperationException();
}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 0c2876e340c1..a189d507a32a 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -1928,16 +1928,6 @@ public class WifiManagerTest {
}
/**
- * Test behavior of {@link WifiManager#isDualModeSupported()} ()}
- */
- @Test
- public void testIsDualModeSupported() throws Exception {
- when(mWifiService.needs5GHzToAnyApBandConversion()).thenReturn(true);
- assertTrue(mWifiManager.isDualModeSupported());
- verify(mWifiService).needs5GHzToAnyApBandConversion();
- }
-
- /**
* Test behavior of {@link WifiManager#is5GHzBandSupported()}
*/
@Test