summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java162
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java190
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java5
-rw-r--r--core/api/current.txt129
-rw-r--r--core/api/module-lib-current.txt3
-rw-r--r--core/api/system-current.txt1
-rw-r--r--core/api/test-current.txt10
-rw-r--r--core/java/android/app/GameManager.java2
-rw-r--r--core/java/android/app/Instrumentation.java9
-rw-r--r--core/java/android/app/PictureInPictureParams.java85
-rw-r--r--core/java/android/app/StatusBarManager.java39
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java19
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl2
-rw-r--r--core/java/android/content/Intent.java82
-rw-r--r--core/java/android/content/res/AssetManager.java7
-rw-r--r--core/java/android/net/NetworkPolicyManager.java20
-rw-r--r--core/java/android/view/HandwritingInitiator.java10
-rw-r--r--core/java/android/view/ViewRootImpl.java7
-rw-r--r--core/java/android/view/WindowManagerGlobal.java20
-rw-r--r--core/java/android/view/WindowlessWindowManager.java3
-rw-r--r--core/proto/android/os/appbatterystats.proto47
-rw-r--r--core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java6
-rw-r--r--data/etc/Android.bp8
-rw-r--r--data/etc/com.android.cellbroadcastreceiver.xml29
-rw-r--r--data/etc/com.android.systemui.xml3
-rw-r--r--data/etc/privapp-permissions-platform.xml18
-rw-r--r--graphics/java/android/graphics/Typeface.java2
-rw-r--r--graphics/java/android/graphics/fonts/Font.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java2
-rw-r--r--location/java/android/location/Location.java148
-rwxr-xr-xmedia/java/android/media/IAudioService.aidl6
-rw-r--r--media/java/android/media/ISpatializerHeadTrackerAvailableCallback.aidl27
-rw-r--r--media/java/android/media/Spatializer.java85
-rw-r--r--media/java/android/media/tv/AitInfo.java6
-rw-r--r--media/java/android/media/tv/CommandRequest.java31
-rw-r--r--media/java/android/media/tv/CommandResponse.java19
-rw-r--r--media/java/android/media/tv/SectionRequest.java5
-rw-r--r--media/java/android/media/tv/SectionResponse.java10
-rw-r--r--media/java/android/media/tv/StreamEventResponse.java15
-rw-r--r--media/java/android/media/tv/TableRequest.java7
-rw-r--r--media/java/android/media/tv/TableResponse.java7
-rw-r--r--media/java/android/media/tv/TimelineResponse.java5
-rw-r--r--media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl4
-rw-r--r--media/java/android/media/tv/interactive/ITvInteractiveAppManagerCallback.aidl4
-rwxr-xr-xmedia/java/android/media/tv/interactive/TvInteractiveAppManager.java28
-rwxr-xr-xmedia/java/android/media/tv/interactive/TvInteractiveAppService.java6
-rw-r--r--media/java/android/media/tv/interactive/TvInteractiveAppServiceInfo.aidl (renamed from media/java/android/media/tv/interactive/TvInteractiveAppInfo.aidl)2
-rw-r--r--media/java/android/media/tv/interactive/TvInteractiveAppServiceInfo.java (renamed from media/java/android/media/tv/interactive/TvInteractiveAppInfo.java)22
-rwxr-xr-xmedia/java/android/media/tv/interactive/TvInteractiveAppView.java12
-rw-r--r--packages/ConnectivityT/framework-t/src/android/net/netstats/provider/INetworkStatsProviderCallback.aidl3
-rw-r--r--packages/ConnectivityT/framework-t/src/android/net/netstats/provider/NetworkStatsProvider.java6
-rw-r--r--packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java13
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LeAudioProfile.java7
-rw-r--r--packages/SystemUI/AndroidManifest.xml5
-rw-r--r--packages/SystemUI/res/drawable/ic_circular_unchecked.xml2
-rw-r--r--packages/SystemUI/res/drawable/media_output_status_check.xml2
-rw-r--r--packages/SystemUI/res/drawable/media_output_status_failed.xml2
-rw-r--r--packages/SystemUI/res/layout/media_output_list_item.xml4
-rw-r--r--packages/SystemUI/res/layout/ongoing_privacy_chip.xml2
-rw-r--r--packages/SystemUI/res/values-night/colors.xml10
-rw-r--r--packages/SystemUI/res/values-sw600dp-land/dimens.xml1
-rw-r--r--packages/SystemUI/res/values-sw720dp-land/dimens.xml1
-rw-r--r--packages/SystemUI/res/values/colors.xml8
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/res/values/styles.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt64
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt276
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt261
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java42
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt84
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt41
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt47
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/animation/AnimationUtilTest.kt51
-rw-r--r--services/api/current.txt3
-rw-r--r--services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchPerUserService.java4
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java40
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java25
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java13
-rw-r--r--services/core/java/com/android/server/audio/SpatializerHelper.java43
-rw-r--r--services/core/java/com/android/server/pm/Installer.java28
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerLocal.java52
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java17
-rw-r--r--services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java22
-rw-r--r--services/core/java/com/android/server/wm/ActivityClientController.java9
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java5
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java17
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java17
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java5
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java24
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java2
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java9
-rw-r--r--telephony/java/android/telephony/DataFailCause.java8
-rw-r--r--telephony/java/android/telephony/data/ApnSetting.java4
-rw-r--r--telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java7
127 files changed, 1981 insertions, 1084 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index 18f63b7ad902..23056b5670b9 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -17,6 +17,7 @@
package com.android.server.job;
import static com.android.server.job.JobSchedulerService.MAX_JOB_CONTEXTS_COUNT;
+import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
import android.annotation.IntDef;
@@ -32,9 +33,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.UserInfo;
+import android.os.BatteryStats;
import android.os.Handler;
import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.ArraySet;
@@ -51,19 +54,24 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.IBatteryStats;
import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.util.StatLogger;
import com.android.server.JobSchedulerBackgroundThread;
import com.android.server.LocalServices;
import com.android.server.job.controllers.JobStatus;
import com.android.server.job.controllers.StateController;
+import com.android.server.job.restrictions.JobRestriction;
import com.android.server.pm.UserManagerInternal;
+import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
+import java.util.function.Predicate;
/**
* This class decides, given the various configuration and the system status, which jobs can start
@@ -278,6 +286,11 @@ class JobConcurrencyManager {
String[] mRecycledShouldStopJobReason = new String[MAX_JOB_CONTEXTS_COUNT];
+ /**
+ * Set of JobServiceContexts that we use to run jobs.
+ */
+ final List<JobServiceContext> mActiveServices = new ArrayList<>();
+
private final ArraySet<JobStatus> mRunningJobs = new ArraySet<>();
private final WorkCountTracker mWorkCountTracker = new WorkCountTracker();
@@ -358,6 +371,20 @@ class JobConcurrencyManager {
onInteractiveStateChanged(mPowerManager.isInteractive());
}
+ /**
+ * Called when the boot phase reaches
+ * {@link com.android.server.SystemService#PHASE_THIRD_PARTY_APPS_CAN_START}.
+ */
+ void onThirdPartyAppsCanStart() {
+ final IBatteryStats batteryStats = IBatteryStats.Stub.asInterface(
+ ServiceManager.getService(BatteryStats.SERVICE_NAME));
+ for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
+ mActiveServices.add(
+ new JobServiceContext(mService, this, batteryStats,
+ mService.mJobPackageTracker, mContext.getMainLooper()));
+ }
+ }
+
@GuardedBy("mLock")
void onAppRemovedLocked(String pkgName, int uid) {
final PackageStats packageStats = mActivePkgStats.get(UserHandle.getUserId(uid), pkgName);
@@ -390,6 +417,7 @@ class JobConcurrencyManager {
case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
if (mPowerManager != null && mPowerManager.isDeviceIdleMode()) {
synchronized (mLock) {
+ stopUnexemptedJobsForDoze();
stopLongRunningJobsLocked("deep doze");
}
}
@@ -471,6 +499,11 @@ class JobConcurrencyManager {
}
@GuardedBy("mLock")
+ ArraySet<JobStatus> getRunningJobsLocked() {
+ return mRunningJobs;
+ }
+
+ @GuardedBy("mLock")
boolean isJobRunningLocked(JobStatus job) {
return mRunningJobs.contains(job);
}
@@ -546,7 +579,7 @@ class JobConcurrencyManager {
}
final List<JobStatus> pendingJobs = mService.mPendingJobs;
- final List<JobServiceContext> activeServices = mService.mActiveServices;
+ final List<JobServiceContext> activeServices = mActiveServices;
// To avoid GC churn, we recycle the arrays.
JobStatus[] contextIdToJobMap = mRecycledAssignContextIdToJobMap;
@@ -719,9 +752,44 @@ class JobConcurrencyManager {
}
@GuardedBy("mLock")
+ boolean stopJobOnServiceContextLocked(JobStatus job,
+ @JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
+ if (!mRunningJobs.contains(job)) {
+ return false;
+ }
+
+ for (int i = 0; i < mActiveServices.size(); i++) {
+ JobServiceContext jsc = mActiveServices.get(i);
+ final JobStatus executing = jsc.getRunningJobLocked();
+ if (executing != null && executing.matches(job.getUid(), job.getJobId())) {
+ jsc.cancelExecutingJobLocked(reason, internalReasonCode, debugReason);
+ return true;
+ }
+ }
+ Slog.wtf(TAG, "Couldn't find running job on a context");
+ mRunningJobs.remove(job);
+ return false;
+ }
+
+ @GuardedBy("mLock")
+ private void stopUnexemptedJobsForDoze() {
+ // When becoming idle, make sure no jobs are actively running,
+ // except those using the idle exemption flag.
+ for (int i = 0; i < mActiveServices.size(); i++) {
+ JobServiceContext jsc = mActiveServices.get(i);
+ final JobStatus executing = jsc.getRunningJobLocked();
+ if (executing != null && !executing.canRunInDoze()) {
+ jsc.cancelExecutingJobLocked(JobParameters.STOP_REASON_DEVICE_STATE,
+ JobParameters.INTERNAL_STOP_REASON_DEVICE_IDLE,
+ "cancelled due to doze");
+ }
+ }
+ }
+
+ @GuardedBy("mLock")
private void stopLongRunningJobsLocked(@NonNull String debugReason) {
for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; ++i) {
- final JobServiceContext jsc = mService.mActiveServices.get(i);
+ final JobServiceContext jsc = mActiveServices.get(i);
final JobStatus jobStatus = jsc.getRunningJobLocked();
if (jobStatus != null && !jsc.isWithinExecutionGuaranteeTime()) {
@@ -731,6 +799,41 @@ class JobConcurrencyManager {
}
}
+ @GuardedBy("mLock")
+ void stopNonReadyActiveJobsLocked() {
+ for (int i = 0; i < mActiveServices.size(); i++) {
+ JobServiceContext serviceContext = mActiveServices.get(i);
+ final JobStatus running = serviceContext.getRunningJobLocked();
+ if (running == null) {
+ continue;
+ }
+ if (!running.isReady()) {
+ if (running.getEffectiveStandbyBucket() == RESTRICTED_INDEX
+ && running.getStopReason() == JobParameters.STOP_REASON_APP_STANDBY) {
+ serviceContext.cancelExecutingJobLocked(
+ running.getStopReason(),
+ JobParameters.INTERNAL_STOP_REASON_RESTRICTED_BUCKET,
+ "cancelled due to restricted bucket");
+ } else {
+ serviceContext.cancelExecutingJobLocked(
+ running.getStopReason(),
+ JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED,
+ "cancelled due to unsatisfied constraints");
+ }
+ } else {
+ final JobRestriction restriction = mService.checkIfRestricted(running);
+ if (restriction != null) {
+ final int internalReasonCode = restriction.getInternalReason();
+ serviceContext.cancelExecutingJobLocked(restriction.getReason(),
+ internalReasonCode,
+ "restricted due to "
+ + JobParameters.getInternalReasonCodeDescription(
+ internalReasonCode));
+ }
+ }
+ }
+ }
+
private void noteConcurrency() {
mService.mJobPackageTracker.noteConcurrency(mRunningJobs.size(),
// TODO: log per type instead of only TOP
@@ -1078,6 +1181,24 @@ class JobConcurrencyManager {
}
@GuardedBy("mLock")
+ boolean executeTimeoutCommandLocked(PrintWriter pw, String pkgName, int userId,
+ boolean hasJobId, int jobId) {
+ boolean foundSome = false;
+ for (int i = 0; i < mActiveServices.size(); i++) {
+ final JobServiceContext jc = mActiveServices.get(i);
+ final JobStatus js = jc.getRunningJobLocked();
+ if (jc.timeoutIfExecutingLocked(pkgName, userId, hasJobId, jobId, "shell")) {
+ foundSome = true;
+ pw.print("Timing out: ");
+ js.printUniqueId(pw);
+ pw.print(" ");
+ pw.println(js.getServiceComponent().flattenToShortString());
+ }
+ }
+ return foundSome;
+ }
+
+ @GuardedBy("mLock")
private String printPendingQueueLocked() {
StringBuilder s = new StringBuilder("Pending queue: ");
Iterator<JobStatus> it = mService.mPendingJobs.iterator();
@@ -1200,6 +1321,43 @@ class JobConcurrencyManager {
}
}
+ @GuardedBy("mLock")
+ void dumpActiveJobsLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate,
+ long nowElapsed, long nowUptime) {
+ pw.println("Active jobs:");
+ pw.increaseIndent();
+ for (int i = 0; i < mActiveServices.size(); i++) {
+ JobServiceContext jsc = mActiveServices.get(i);
+ final JobStatus job = jsc.getRunningJobLocked();
+
+ if (job != null && !predicate.test(job)) {
+ continue;
+ }
+
+ pw.print("Slot #"); pw.print(i); pw.print(": ");
+ jsc.dumpLocked(pw, nowElapsed);
+
+ if (job != null) {
+ pw.increaseIndent();
+
+ pw.increaseIndent();
+ job.dump(pw, false, nowElapsed);
+ pw.decreaseIndent();
+
+ pw.print("Evaluated bias: ");
+ pw.println(JobInfo.getBiasString(job.lastEvaluatedBias));
+
+ pw.print("Active at ");
+ TimeUtils.formatDuration(job.madeActive - nowUptime, pw);
+ pw.print(", pending for ");
+ TimeUtils.formatDuration(job.madeActive - job.madePending, pw);
+ pw.decreaseIndent();
+ pw.println();
+ }
+ }
+ pw.decreaseIndent();
+ }
+
public void dumpProtoLocked(ProtoOutputStream proto, long tag, long now, long nowRealtime) {
final long token = proto.start(tag);
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 b9362789c6c6..3d74bc98ad32 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -57,7 +57,6 @@ import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.BatteryManagerInternal;
-import android.os.BatteryStats;
import android.os.BatteryStatsInternal;
import android.os.Binder;
import android.os.Handler;
@@ -67,7 +66,6 @@ import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
@@ -90,7 +88,6 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IBatteryStats;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
@@ -100,7 +97,6 @@ import com.android.server.AppStateTrackerImpl;
import com.android.server.DeviceIdleInternal;
import com.android.server.JobSchedulerBackgroundThread;
import com.android.server.LocalServices;
-import com.android.server.job.JobSchedulerServiceDumpProto.ActiveJob;
import com.android.server.job.JobSchedulerServiceDumpProto.PendingJob;
import com.android.server.job.controllers.BackgroundJobsController;
import com.android.server.job.controllers.BatteryController;
@@ -243,12 +239,6 @@ public class JobSchedulerService extends com.android.server.SystemService
static final int MSG_CHECK_CHANGED_JOB_LIST = 8;
static final int MSG_CHECK_MEDIA_EXEMPTION = 9;
- /**
- * Track Services that have currently active or pending jobs. The index is provided by
- * {@link JobStatus#getServiceToken()}
- */
- final List<JobServiceContext> mActiveServices = new ArrayList<>();
-
/** List of controllers that will notify this service of updates to jobs. */
final List<StateController> mControllers;
/**
@@ -307,7 +297,6 @@ public class JobSchedulerService extends com.android.server.SystemService
PackageManagerInternal mLocalPM;
ActivityManagerInternal mActivityManagerInternal;
- IBatteryStats mBatteryStats;
DeviceIdleInternal mLocalDeviceIdleController;
@VisibleForTesting
AppStateTrackerImpl mAppStateTracker;
@@ -1578,7 +1567,8 @@ public class JobSchedulerService extends com.android.server.SystemService
mJobPackageTracker.noteNonpending(cancelled);
}
// Cancel if running.
- stopJobOnServiceContextLocked(cancelled, reason, internalReasonCode, debugReason);
+ mConcurrencyManager.stopJobOnServiceContextLocked(
+ cancelled, reason, internalReasonCode, debugReason);
// If this is a replacement, bring in the new version of the job
if (incomingJob != null) {
if (DEBUG) Slog.i(TAG, "Tracking replacement job " + incomingJob.toShortString());
@@ -1627,19 +1617,7 @@ public class JobSchedulerService extends com.android.server.SystemService
if (DEBUG) {
Slog.d(TAG, "Doze state changed: " + deviceIdle);
}
- if (deviceIdle) {
- // When becoming idle, make sure no jobs are actively running,
- // except those using the idle exemption flag.
- for (int i=0; i<mActiveServices.size(); i++) {
- JobServiceContext jsc = mActiveServices.get(i);
- final JobStatus executing = jsc.getRunningJobLocked();
- if (executing != null && !executing.canRunInDoze()) {
- jsc.cancelExecutingJobLocked(JobParameters.STOP_REASON_DEVICE_STATE,
- JobParameters.INTERNAL_STOP_REASON_DEVICE_IDLE,
- "cancelled due to doze");
- }
- }
- } else {
+ if (!deviceIdle) {
// When coming out of idle, allow thing to start back up.
if (mReadyToRock) {
if (mLocalDeviceIdleController != null) {
@@ -1682,10 +1660,10 @@ public class JobSchedulerService extends com.android.server.SystemService
// active is true if pending queue contains jobs OR some job is running.
boolean active = mPendingJobs.size() > 0;
if (mPendingJobs.size() <= 0) {
- for (int i=0; i<mActiveServices.size(); i++) {
- final JobServiceContext jsc = mActiveServices.get(i);
- final JobStatus job = jsc.getRunningJobLocked();
- if (job != null && !job.canRunInDoze()) {
+ final ArraySet<JobStatus> runningJobs = mConcurrencyManager.getRunningJobsLocked();
+ for (int i = runningJobs.size() - 1; i >= 0; --i) {
+ final JobStatus job = runningJobs.valueAt(i);
+ if (!job.canRunInDoze()) {
// We will report active if we have a job running and it does not have an
// exception that allows it to run in Doze.
active = true;
@@ -1895,16 +1873,9 @@ public class JobSchedulerService extends com.android.server.SystemService
synchronized (mLock) {
// Let's go!
mReadyToRock = true;
- mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
- BatteryStats.SERVICE_NAME));
mLocalDeviceIdleController =
LocalServices.getService(DeviceIdleInternal.class);
- // Create the "runners".
- for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
- mActiveServices.add(
- new JobServiceContext(this, mConcurrencyManager, mBatteryStats,
- mJobPackageTracker, getContext().getMainLooper()));
- }
+ mConcurrencyManager.onThirdPartyAppsCanStart();
// Attach jobs to their controllers.
mJobs.forEachJob((job) -> {
for (int controller = 0; controller < mControllers.size(); controller++) {
@@ -1961,19 +1932,6 @@ public class JobSchedulerService extends com.android.server.SystemService
return removed;
}
- private boolean stopJobOnServiceContextLocked(JobStatus job,
- @JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
- for (int i = 0; i < mActiveServices.size(); i++) {
- JobServiceContext jsc = mActiveServices.get(i);
- final JobStatus executing = jsc.getRunningJobLocked();
- if (executing != null && executing.matches(job.getUid(), job.getJobId())) {
- jsc.cancelExecutingJobLocked(reason, internalReasonCode, debugReason);
- return true;
- }
- }
- return false;
- }
-
/** Return {@code true} if the specified job is currently executing. */
@GuardedBy("mLock")
public boolean isCurrentlyRunningLocked(JobStatus job) {
@@ -2383,7 +2341,8 @@ public class JobSchedulerService extends com.android.server.SystemService
* - if passes all the restrictions or has {@link JobInfo#BIAS_FOREGROUND_SERVICE} bias
* or higher.
*/
- private JobRestriction checkIfRestricted(JobStatus job) {
+ @GuardedBy("mLock")
+ JobRestriction checkIfRestricted(JobStatus job) {
if (evaluateJobBiasLocked(job) >= JobInfo.BIAS_FOREGROUND_SERVICE) {
// Jobs with BIAS_FOREGROUND_SERVICE or higher should not be restricted
return null;
@@ -2397,38 +2356,9 @@ public class JobSchedulerService extends com.android.server.SystemService
return null;
}
+ @GuardedBy("mLock")
private void stopNonReadyActiveJobsLocked() {
- for (int i=0; i<mActiveServices.size(); i++) {
- JobServiceContext serviceContext = mActiveServices.get(i);
- final JobStatus running = serviceContext.getRunningJobLocked();
- if (running == null) {
- continue;
- }
- if (!running.isReady()) {
- if (running.getEffectiveStandbyBucket() == RESTRICTED_INDEX
- && running.getStopReason() == JobParameters.STOP_REASON_APP_STANDBY) {
- serviceContext.cancelExecutingJobLocked(
- running.getStopReason(),
- JobParameters.INTERNAL_STOP_REASON_RESTRICTED_BUCKET,
- "cancelled due to restricted bucket");
- } else {
- serviceContext.cancelExecutingJobLocked(
- running.getStopReason(),
- JobParameters.INTERNAL_STOP_REASON_CONSTRAINTS_NOT_SATISFIED,
- "cancelled due to unsatisfied constraints");
- }
- } else {
- final JobRestriction restriction = checkIfRestricted(running);
- if (restriction != null) {
- final int internalReasonCode = restriction.getInternalReason();
- serviceContext.cancelExecutingJobLocked(restriction.getReason(),
- internalReasonCode,
- "restricted due to "
- + JobParameters.getInternalReasonCodeDescription(
- internalReasonCode));
- }
- }
- }
+ mConcurrencyManager.stopNonReadyActiveJobsLocked();
}
/**
@@ -2598,7 +2528,7 @@ public class JobSchedulerService extends com.android.server.SystemService
debugReason = "couldn't figure out why the job should stop running";
}
}
- stopJobOnServiceContextLocked(job, job.getStopReason(),
+ mConcurrencyManager.stopJobOnServiceContextLocked(job, job.getStopReason(),
internalStopReason, debugReason);
} else if (mPendingJobs.remove(job)) {
noteJobNonPending(job);
@@ -3516,9 +3446,11 @@ public class JobSchedulerService extends com.android.server.SystemService
final ArrayList<JobInfo> runningJobs;
synchronized (mLock) {
- runningJobs = new ArrayList<>(mActiveServices.size());
- for (JobServiceContext jsc : mActiveServices) {
- final JobStatus job = jsc.getRunningJobLocked();
+ final ArraySet<JobStatus> runningJobStatuses =
+ mConcurrencyManager.getRunningJobsLocked();
+ runningJobs = new ArrayList<>(runningJobStatuses.size());
+ for (int i = runningJobStatuses.size() - 1; i >= 0; --i) {
+ final JobStatus job = runningJobStatuses.valueAt(i);
if (job != null) {
runningJobs.add(job.getJob());
}
@@ -3599,18 +3531,8 @@ public class JobSchedulerService extends com.android.server.SystemService
}
synchronized (mLock) {
- boolean foundSome = false;
- for (int i = 0; i < mActiveServices.size(); i++) {
- final JobServiceContext jc = mActiveServices.get(i);
- final JobStatus js = jc.getRunningJobLocked();
- if (jc.timeoutIfExecutingLocked(pkgName, userId, hasJobId, jobId, "shell")) {
- foundSome = true;
- pw.print("Timing out: ");
- js.printUniqueId(pw);
- pw.print(" ");
- pw.println(js.getServiceComponent().flattenToShortString());
- }
- }
+ final boolean foundSome = mConcurrencyManager.executeTimeoutCommandLocked(pw,
+ pkgName, userId, hasJobId, jobId);
if (!foundSome) {
pw.println("No matching executing jobs found.");
}
@@ -4037,38 +3959,7 @@ public class JobSchedulerService extends com.android.server.SystemService
pw.decreaseIndent();
pw.println();
- pw.println("Active jobs:");
- pw.increaseIndent();
- for (int i=0; i<mActiveServices.size(); i++) {
- JobServiceContext jsc = mActiveServices.get(i);
- final JobStatus job = jsc.getRunningJobLocked();
-
- if (job != null && !predicate.test(job)) {
- continue;
- }
-
- pw.print("Slot #"); pw.print(i); pw.print(": ");
- jsc.dumpLocked(pw, nowElapsed);
-
- if (job != null) {
- pw.increaseIndent();
-
- pw.increaseIndent();
- job.dump(pw, false, nowElapsed);
- pw.decreaseIndent();
-
- pw.print("Evaluated bias: ");
- pw.println(JobInfo.getBiasString(job.lastEvaluatedBias));
-
- pw.print("Active at ");
- TimeUtils.formatDuration(job.madeActive - nowUptime, pw);
- pw.print(", pending for ");
- TimeUtils.formatDuration(job.madeActive - job.madePending, pw);
- pw.decreaseIndent();
- pw.println();
- }
- }
- pw.decreaseIndent();
+ mConcurrencyManager.dumpActiveJobsLocked(pw, predicate, nowElapsed, nowUptime);
pw.println();
boolean recentPrinted = false;
@@ -4228,45 +4119,6 @@ public class JobSchedulerService extends com.android.server.SystemService
proto.end(pjToken);
}
- for (JobServiceContext jsc : mActiveServices) {
- final long ajToken = proto.start(JobSchedulerServiceDumpProto.ACTIVE_JOBS);
- final JobStatus job = jsc.getRunningJobLocked();
-
- if (job == null) {
- final long ijToken = proto.start(ActiveJob.INACTIVE);
-
- proto.write(ActiveJob.InactiveJob.TIME_SINCE_STOPPED_MS,
- nowElapsed - jsc.mStoppedTime);
- if (jsc.mStoppedReason != null) {
- proto.write(ActiveJob.InactiveJob.STOPPED_REASON,
- jsc.mStoppedReason);
- }
-
- proto.end(ijToken);
- } else {
- final long rjToken = proto.start(ActiveJob.RUNNING);
-
- job.writeToShortProto(proto, ActiveJob.RunningJob.INFO);
-
- proto.write(ActiveJob.RunningJob.RUNNING_DURATION_MS,
- nowElapsed - jsc.getExecutionStartTimeElapsed());
- proto.write(ActiveJob.RunningJob.TIME_UNTIL_TIMEOUT_MS,
- jsc.getTimeoutElapsed() - nowElapsed);
-
- job.dump(proto, ActiveJob.RunningJob.DUMP, false, nowElapsed);
-
- proto.write(ActiveJob.RunningJob.EVALUATED_PRIORITY,
- evaluateJobBiasLocked(job));
-
- proto.write(ActiveJob.RunningJob.TIME_SINCE_MADE_ACTIVE_MS,
- nowUptime - job.madeActive);
- proto.write(ActiveJob.RunningJob.PENDING_DURATION_MS,
- job.madeActive - job.madePending);
-
- proto.end(rjToken);
- }
- proto.end(ajToken);
- }
if (filterUid == -1) {
proto.write(JobSchedulerServiceDumpProto.IS_READY_TO_ROCK, mReadyToRock);
proto.write(JobSchedulerServiceDumpProto.REPORTED_ACTIVE, mReportedActive);
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 efcf14f07ee9..30fdb1e9ad4e 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
@@ -441,11 +441,6 @@ public final class JobStatus {
/** The reason a job most recently went from ready to not ready. */
private int mReasonReadyToUnready = JobParameters.STOP_REASON_UNDEFINED;
- /** Provide a handle to the service that this job will be run on. */
- public int getServiceToken() {
- return callingUid;
- }
-
/**
* Core constructor for JobStatus instances. All other ctors funnel down to this one.
*
diff --git a/core/api/current.txt b/core/api/current.txt
index b5493a3fa8c7..02c30e3b1722 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -5630,6 +5630,7 @@ package android.app {
method public boolean onException(Object, Throwable);
method public void onStart();
method public void removeMonitor(android.app.Instrumentation.ActivityMonitor);
+ method public void resetInTouchMode();
method public void runOnMainSync(Runnable);
method public void sendCharacterSync(int);
method public void sendKeyDownUpSync(int);
@@ -6644,6 +6645,15 @@ package android.app {
public final class PictureInPictureParams implements android.os.Parcelable {
method public int describeContents();
+ method @NonNull public java.util.List<android.app.RemoteAction> getActions();
+ method @Nullable public android.util.Rational getAspectRatio();
+ method @Nullable public android.app.RemoteAction getCloseAction();
+ method @Nullable public android.util.Rational getExpandedAspectRatio();
+ method @Nullable public android.graphics.Rect getSourceRectHint();
+ method @Nullable public CharSequence getSubtitle();
+ method @Nullable public CharSequence getTitle();
+ method public boolean isAutoEnterEnabled();
+ method public boolean isSeamlessResizeEnabled();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.PictureInPictureParams> CREATOR;
}
@@ -10115,12 +10125,16 @@ package android.content {
method @Nullable public long[] getLongArrayExtra(String);
method public long getLongExtra(String, long);
method @Nullable public String getPackage();
- method @Nullable public android.os.Parcelable[] getParcelableArrayExtra(String);
- method @Nullable public <T extends android.os.Parcelable> java.util.ArrayList<T> getParcelableArrayListExtra(String);
- method @Nullable public <T extends android.os.Parcelable> T getParcelableExtra(String);
+ method @Deprecated @Nullable public android.os.Parcelable[] getParcelableArrayExtra(String);
+ method @Nullable public <T> T[] getParcelableArrayExtra(@Nullable String, @NonNull Class<T>);
+ method @Deprecated @Nullable public <T extends android.os.Parcelable> java.util.ArrayList<T> getParcelableArrayListExtra(String);
+ method @Nullable public <T> java.util.ArrayList<T> getParcelableArrayListExtra(@Nullable String, @NonNull Class<? extends T>);
+ method @Deprecated @Nullable public <T extends android.os.Parcelable> T getParcelableExtra(String);
+ method @Nullable public <T> T getParcelableExtra(@Nullable String, @NonNull Class<T>);
method @Nullable public String getScheme();
method @Nullable public android.content.Intent getSelector();
- method @Nullable public java.io.Serializable getSerializableExtra(String);
+ method @Deprecated @Nullable public java.io.Serializable getSerializableExtra(String);
+ method @Nullable public <T extends java.io.Serializable> T getSerializableExtra(@Nullable String, @NonNull Class<T>);
method @Nullable public short[] getShortArrayExtra(String);
method public short getShortExtra(String, short);
method @Nullable public android.graphics.Rect getSourceBounds();
@@ -19477,26 +19491,26 @@ package android.location {
method @NonNull public static String convert(@FloatRange double, int);
method @FloatRange public static double convert(@NonNull String);
method public int describeContents();
- method public static void distanceBetween(@FloatRange double, @FloatRange double, @FloatRange double, @FloatRange double, float[]);
- method @FloatRange public float distanceTo(@NonNull android.location.Location);
- method public void dump(@NonNull android.util.Printer, @Nullable String);
- method @FloatRange public float getAccuracy();
+ method public static void distanceBetween(@FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, @FloatRange(from=-90.0, to=90.0) double, @FloatRange(from=-180.0, to=180.0) double, float[]);
+ method @FloatRange(from=0.0) public float distanceTo(@NonNull android.location.Location);
+ method @Deprecated public void dump(@NonNull android.util.Printer, @Nullable String);
+ method @FloatRange(from=0.0) public float getAccuracy();
method @FloatRange public double getAltitude();
- method @FloatRange(from=0.0f, to=360.0f, toInclusive=false) public float getBearing();
- method @FloatRange public float getBearingAccuracyDegrees();
- method @IntRange public long getElapsedRealtimeAgeMillis();
- method @IntRange public long getElapsedRealtimeAgeMillis(@IntRange long);
- method @IntRange public long getElapsedRealtimeMillis();
- method @IntRange public long getElapsedRealtimeNanos();
- method @FloatRange public double getElapsedRealtimeUncertaintyNanos();
+ method @FloatRange(from=0.0, to=360.0, toInclusive=false) public float getBearing();
+ method @FloatRange(from=0.0) public float getBearingAccuracyDegrees();
+ method @IntRange(from=0) public long getElapsedRealtimeAgeMillis();
+ method public long getElapsedRealtimeAgeMillis(@IntRange(from=0) long);
+ method @IntRange(from=0) public long getElapsedRealtimeMillis();
+ method @IntRange(from=0) public long getElapsedRealtimeNanos();
+ method @FloatRange(from=0.0) public double getElapsedRealtimeUncertaintyNanos();
method @Nullable public android.os.Bundle getExtras();
- method @FloatRange public double getLatitude();
- method @FloatRange public double getLongitude();
+ method @FloatRange(from=-90.0, to=90.0) public double getLatitude();
+ method @FloatRange(from=-180.0, to=180.0) public double getLongitude();
method @Nullable public String getProvider();
- method @FloatRange public float getSpeed();
- method @FloatRange public float getSpeedAccuracyMetersPerSecond();
- method @IntRange public long getTime();
- method @FloatRange public float getVerticalAccuracyMeters();
+ method @FloatRange(from=0.0) public float getSpeed();
+ method @FloatRange(from=0.0) public float getSpeedAccuracyMetersPerSecond();
+ method @IntRange(from=0) public long getTime();
+ method @FloatRange(from=0.0) public float getVerticalAccuracyMeters();
method public boolean hasAccuracy();
method public boolean hasAltitude();
method public boolean hasBearing();
@@ -19518,21 +19532,21 @@ package android.location {
method public void removeVerticalAccuracy();
method public void reset();
method public void set(@NonNull android.location.Location);
- method public void setAccuracy(@FloatRange float);
+ method public void setAccuracy(@FloatRange(from=0.0) float);
method public void setAltitude(@FloatRange double);
method public void setBearing(@FloatRange(fromInclusive=false, toInclusive=false) float);
- method public void setBearingAccuracyDegrees(@FloatRange float);
- method public void setElapsedRealtimeNanos(@IntRange long);
- method public void setElapsedRealtimeUncertaintyNanos(@FloatRange double);
+ method public void setBearingAccuracyDegrees(@FloatRange(from=0.0) float);
+ method public void setElapsedRealtimeNanos(@IntRange(from=0) long);
+ method public void setElapsedRealtimeUncertaintyNanos(@FloatRange(from=0.0) double);
method public void setExtras(@Nullable android.os.Bundle);
- method public void setLatitude(@FloatRange double);
- method public void setLongitude(@FloatRange double);
+ method public void setLatitude(@FloatRange(from=-90.0, to=90.0) double);
+ method public void setLongitude(@FloatRange(from=-180.0, to=180.0) double);
method public void setMock(boolean);
method public void setProvider(@Nullable String);
- method public void setSpeed(@FloatRange float);
- method public void setSpeedAccuracyMetersPerSecond(@FloatRange float);
- method public void setTime(@IntRange long);
- method public void setVerticalAccuracyMeters(@FloatRange float);
+ method public void setSpeed(@FloatRange(from=0.0) float);
+ method public void setSpeedAccuracyMetersPerSecond(@FloatRange(from=0.0) float);
+ method public void setTime(@IntRange(from=0) long);
+ method public void setVerticalAccuracyMeters(@FloatRange(from=0.0) float);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.location.Location> CREATOR;
field public static final int FORMAT_DEGREES = 0; // 0x0
@@ -23538,17 +23552,24 @@ package android.media {
}
public class Spatializer {
+ method public void addOnHeadTrackerAvailableListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnHeadTrackerAvailableListener);
method public void addOnSpatializerStateChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnSpatializerStateChangedListener);
method public boolean canBeSpatialized(@NonNull android.media.AudioAttributes, @NonNull android.media.AudioFormat);
method public int getImmersiveAudioLevel();
method public boolean isAvailable();
method public boolean isEnabled();
+ method public boolean isHeadTrackerAvailable();
+ method public void removeOnHeadTrackerAvailableListener(@NonNull android.media.Spatializer.OnHeadTrackerAvailableListener);
method public void removeOnSpatializerStateChangedListener(@NonNull android.media.Spatializer.OnSpatializerStateChangedListener);
field public static final int SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL = 1; // 0x1
field public static final int SPATIALIZER_IMMERSIVE_LEVEL_NONE = 0; // 0x0
field public static final int SPATIALIZER_IMMERSIVE_LEVEL_OTHER = -1; // 0xffffffff
}
+ public static interface Spatializer.OnHeadTrackerAvailableListener {
+ method public void onHeadTrackerAvailableChanged(@NonNull android.media.Spatializer, boolean);
+ }
+
public static interface Spatializer.OnSpatializerStateChangedListener {
method public void onSpatializerAvailableChanged(@NonNull android.media.Spatializer, boolean);
method public void onSpatializerEnabledChanged(@NonNull android.media.Spatializer, boolean);
@@ -25181,17 +25202,23 @@ package android.media.tv {
}
public final class CommandRequest extends android.media.tv.BroadcastInfoRequest implements android.os.Parcelable {
- ctor public CommandRequest(int, int, @NonNull String, @NonNull String, @NonNull String);
+ ctor public CommandRequest(int, int, @NonNull String, @NonNull String, @NonNull String, @NonNull String);
+ method @NonNull public String getArgumentType();
method @NonNull public String getArguments();
method @NonNull public String getName();
- method @NonNull public String getNameSpace();
+ method @NonNull public String getNamespace();
+ field public static final String ARGUMENT_TYPE_JSON = "json";
+ field public static final String ARGUMENT_TYPE_XML = "xml";
field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.CommandRequest> CREATOR;
}
public final class CommandResponse extends android.media.tv.BroadcastInfoResponse implements android.os.Parcelable {
- ctor public CommandResponse(int, int, int, @Nullable String);
+ ctor public CommandResponse(int, int, int, @Nullable String, @NonNull String);
method @Nullable public String getResponse();
+ method @NonNull public String getResponseType();
field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.CommandResponse> CREATOR;
+ field public static final String RESPONSE_TYPE_JSON = "json";
+ field public static final String RESPONSE_TYPE_XML = "xml";
}
public final class DsmccRequest extends android.media.tv.BroadcastInfoRequest implements android.os.Parcelable {
@@ -25256,7 +25283,7 @@ package android.media.tv {
ctor public StreamEventResponse(int, int, int, int, long, @Nullable byte[]);
method @Nullable public byte[] getData();
method public int getEventId();
- method public long getNpt();
+ method public long getNptMillis();
field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.StreamEventResponse> CREATOR;
}
@@ -25286,7 +25313,7 @@ package android.media.tv {
public final class TimelineResponse extends android.media.tv.BroadcastInfoResponse implements android.os.Parcelable {
ctor public TimelineResponse(int, int, int, @Nullable String, int, int, long, long);
- method @Nullable public String getSelector();
+ method @Nullable public android.net.Uri getSelector();
method public long getTicks();
method public int getUnitsPerSecond();
method public int getUnitsPerTick();
@@ -26082,21 +26109,8 @@ package android.media.tv.interactive {
method @NonNull public android.media.tv.interactive.AppLinkInfo.Builder setUriScheme(@NonNull String);
}
- public final class TvInteractiveAppInfo implements android.os.Parcelable {
- ctor public TvInteractiveAppInfo(@NonNull android.content.Context, @NonNull android.content.ComponentName);
- method public int describeContents();
- method @NonNull public String getId();
- method @Nullable public android.content.pm.ServiceInfo getServiceInfo();
- method @NonNull public int getSupportedTypes();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.interactive.TvInteractiveAppInfo> CREATOR;
- field public static final int INTERACTIVE_APP_TYPE_ATSC = 2; // 0x2
- field public static final int INTERACTIVE_APP_TYPE_GINGA = 4; // 0x4
- field public static final int INTERACTIVE_APP_TYPE_HBBTV = 1; // 0x1
- }
-
public final class TvInteractiveAppManager {
- method @NonNull public java.util.List<android.media.tv.interactive.TvInteractiveAppInfo> getTvInteractiveAppServiceList();
+ method @NonNull public java.util.List<android.media.tv.interactive.TvInteractiveAppServiceInfo> getTvInteractiveAppServiceList();
method public void prepare(@NonNull String, int);
method public void registerAppLinkInfo(@NonNull String, @NonNull android.media.tv.interactive.AppLinkInfo);
method public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.tv.interactive.TvInteractiveAppManager.TvInteractiveAppCallback);
@@ -26219,6 +26233,19 @@ package android.media.tv.interactive {
method @CallSuper public void setVideoBounds(@NonNull android.graphics.Rect);
}
+ public final class TvInteractiveAppServiceInfo implements android.os.Parcelable {
+ ctor public TvInteractiveAppServiceInfo(@NonNull android.content.Context, @NonNull android.content.ComponentName);
+ method public int describeContents();
+ method @NonNull public String getId();
+ method @Nullable public android.content.pm.ServiceInfo getServiceInfo();
+ method @NonNull public int getSupportedTypes();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.interactive.TvInteractiveAppServiceInfo> CREATOR;
+ field public static final int INTERACTIVE_APP_TYPE_ATSC = 2; // 0x2
+ field public static final int INTERACTIVE_APP_TYPE_GINGA = 4; // 0x4
+ field public static final int INTERACTIVE_APP_TYPE_HBBTV = 1; // 0x1
+ }
+
public class TvInteractiveAppView extends android.view.ViewGroup {
ctor public TvInteractiveAppView(@NonNull android.content.Context);
ctor public TvInteractiveAppView(@NonNull android.content.Context, @Nullable android.util.AttributeSet);
@@ -43786,6 +43813,7 @@ package android.telephony.data {
method public int getNetworkTypeBitmask();
method public String getOperatorNumeric();
method public String getPassword();
+ method public int getProfileId();
method public int getProtocol();
method @Deprecated public java.net.InetAddress getProxyAddress();
method public String getProxyAddressAsString();
@@ -43793,6 +43821,7 @@ package android.telephony.data {
method public int getRoamingProtocol();
method public String getUser();
method public boolean isEnabled();
+ method public boolean isPersistent();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field public static final int AUTH_TYPE_CHAP = 2; // 0x2
field public static final int AUTH_TYPE_NONE = 0; // 0x0
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 3d5232ba4f35..d2cc0f54d4b7 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -243,7 +243,8 @@ package android.net {
method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public android.telephony.SubscriptionPlan getSubscriptionPlan(@NonNull android.net.NetworkTemplate);
method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public boolean isUidNetworkingBlocked(int, boolean);
method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public boolean isUidRestrictedOnMeteredNetworks(int);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void notifyStatsProviderWarningOrLimitReached();
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void notifyStatsProviderLimitReached();
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void notifyStatsProviderWarningReached();
method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void registerNetworkPolicyCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void unregisterNetworkPolicyCallback(@NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 9f41f05534e5..5df988153752 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1114,6 +1114,7 @@ package android.app.admin {
method public void setSecondaryLockscreenEnabled(@NonNull android.content.ComponentName, boolean);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES) public void setStrings(@NonNull java.util.Set<android.app.admin.DevicePolicyStringResource>);
method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setUserProvisioningState(int, @NonNull android.os.UserHandle);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public boolean shouldAllowBypassingDevicePolicyManagementRoleQualification();
field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED";
field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
field public static final String ACTION_BIND_SECONDARY_LOCKSCREEN_SERVICE = "android.app.action.BIND_SECONDARY_LOCKSCREEN_SERVICE";
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index db95a1feec91..2e8bed32665c 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -356,14 +356,8 @@ package android.app {
}
public final class PictureInPictureParams implements android.os.Parcelable {
- method public java.util.List<android.app.RemoteAction> getActions();
- method public float getAspectRatio();
- method @Nullable public android.app.RemoteAction getCloseAction();
- method public float getExpandedAspectRatio();
- method public android.graphics.Rect getSourceRectHint();
- method @Nullable public CharSequence getSubtitle();
- method @Nullable public CharSequence getTitle();
- method public boolean isSeamlessResizeEnabled();
+ method public float getAspectRatioFloat();
+ method public float getExpandedAspectRatioFloat();
}
public final class PictureInPictureUiState implements android.os.Parcelable {
diff --git a/core/java/android/app/GameManager.java b/core/java/android/app/GameManager.java
index 6f49c9e647a4..a138fa1f6fd5 100644
--- a/core/java/android/app/GameManager.java
+++ b/core/java/android/app/GameManager.java
@@ -191,7 +191,7 @@ public final class GameManager {
*/
@TestApi
@RequiresPermission(Manifest.permission.MANAGE_GAME_MODE)
- public @GameMode boolean isAngleEnabled(@NonNull String packageName) {
+ public boolean isAngleEnabled(@NonNull String packageName) {
try {
return mService.isAngleEnabled(packageName, mContext.getUserId());
} catch (RemoteException e) {
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index e0c69df0aa18..ac979c495cf3 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -393,6 +393,15 @@ public class Instrumentation {
}
/**
+ * Resets the {@link #setInTouchMode touch mode} to the device default.
+ */
+ public void resetInTouchMode() {
+ final boolean defaultInTouchMode = getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_defaultInTouchMode);
+ setInTouchMode(defaultInTouchMode);
+ }
+
+ /**
* Schedule a callback for when the application's main thread goes idle
* (has no more events to process).
*
diff --git a/core/java/android/app/PictureInPictureParams.java b/core/java/android/app/PictureInPictureParams.java
index 2d2788ca91a3..3f1844e2ba8a 100644
--- a/core/java/android/app/PictureInPictureParams.java
+++ b/core/java/android/app/PictureInPictureParams.java
@@ -280,7 +280,7 @@ public final class PictureInPictureParams implements Parcelable {
private Rational mAspectRatio;
/**
- * The expected aspect ratio of the vertically expanded picture-in-picture window.
+ * The expected aspect ratio of the expanded picture-in-picture window.
*/
@Nullable
private Rational mExpandedAspectRatio;
@@ -441,15 +441,21 @@ public final class PictureInPictureParams implements Parcelable {
* @hide
*/
@TestApi
- public float getAspectRatio() {
+ public float getAspectRatioFloat() {
if (mAspectRatio != null) {
return mAspectRatio.floatValue();
}
return 0f;
}
- /** @hide */
- public Rational getAspectRatioRational() {
+ /**
+ * Returns the expected aspect ratio of the picture-in-picture window.
+ *
+ * @return aspect ratio as the desired width / height or {@code null} if not set.
+ * @see PictureInPictureParams.Builder#setAspectRatio(Rational)
+ */
+ @Nullable
+ public Rational getAspectRatio() {
return mAspectRatio;
}
@@ -466,7 +472,7 @@ public final class PictureInPictureParams implements Parcelable {
* @hide
*/
@TestApi
- public float getExpandedAspectRatio() {
+ public float getExpandedAspectRatioFloat() {
if (mExpandedAspectRatio != null) {
return mExpandedAspectRatio.floatValue();
}
@@ -474,6 +480,17 @@ public final class PictureInPictureParams implements Parcelable {
}
/**
+ * Returns the desired aspect ratio of the expanded picture-in-picture window.
+ *
+ * @return aspect ratio as the desired width / height or {@code null} if not set.
+ * @see PictureInPictureParams.Builder#setExpandedAspectRatio(Rational)
+ */
+ @Nullable
+ public Rational getExpandedAspectRatio() {
+ return mExpandedAspectRatio;
+ }
+
+ /**
* @return whether the expanded aspect ratio is set
* @hide
*/
@@ -482,11 +499,17 @@ public final class PictureInPictureParams implements Parcelable {
}
/**
- * @return the set of user actions.
- * @hide
+ * Returns the list of user actions that are associated with the activity when in
+ * picture-in-picture mode.
+ *
+ * @return the user actions in a new list.
+ * @see PictureInPictureParams.Builder#setActions(List)
*/
- @TestApi
+ @NonNull
public List<RemoteAction> getActions() {
+ if (mUserActions == null) {
+ return new ArrayList<>();
+ }
return mUserActions;
}
@@ -499,10 +522,11 @@ public final class PictureInPictureParams implements Parcelable {
}
/**
- * @return the close action.
- * @hide
+ * Returns the action that is to replace the system close action.
+ *
+ * @return the close action or {@code null} if not set.
+ * @see PictureInPictureParams.Builder#setCloseAction(RemoteAction)
*/
- @TestApi
@Nullable
public RemoteAction getCloseAction() {
return mCloseAction;
@@ -528,10 +552,12 @@ public final class PictureInPictureParams implements Parcelable {
}
/**
- * @return the source rect hint
- * @hide
+ * Returns the source rect hint.
+ *
+ * @return the source rect hint also known as launch bounds or {@code null} if not set.
+ * @see PictureInPictureParams.Builder#setSourceRectHint(Rect)
*/
- @TestApi
+ @Nullable
public Rect getSourceRectHint() {
return mSourceRectHint;
}
@@ -545,18 +571,23 @@ public final class PictureInPictureParams implements Parcelable {
}
/**
- * @return whether auto pip is enabled.
- * @hide
+ * Returns whether auto enter picture-in-picture is enabled.
+ *
+ * @return {@code true} if the system will automatically put the activity in
+ * picture-in-picture mode.
+ * @see PictureInPictureParams.Builder#setAutoEnterEnabled(boolean)
*/
public boolean isAutoEnterEnabled() {
return mAutoEnterEnabled == null ? false : mAutoEnterEnabled;
}
/**
- * @return whether seamless resize is enabled.
- * @hide
+ * Returns whether seamless resize is enabled.
+ *
+ * @return true if the system can seamlessly resize the window while activity is in
+ * picture-in-picture mode.
+ * @see PictureInPictureParams.Builder#setSeamlessResizeEnabled(boolean)
*/
- @TestApi
public boolean isSeamlessResizeEnabled() {
return mSeamlessResizeEnabled == null ? true : mSeamlessResizeEnabled;
}
@@ -570,10 +601,11 @@ public final class PictureInPictureParams implements Parcelable {
}
/**
- * @return title of the pip.
- * @hide
+ * Returns the title of the picture-in-picture window that may be displayed to the user.
+ *
+ * @return title of the picture-in-picture window.
+ * @see PictureInPictureParams.Builder#setTitle(CharSequence)
*/
- @TestApi
@Nullable
public CharSequence getTitle() {
return mTitle;
@@ -588,10 +620,11 @@ public final class PictureInPictureParams implements Parcelable {
}
/**
- * @return subtitle of the pip.
- * @hide
+ * Returns the subtitle of the picture-in-picture window that may be displayed to the user.
+ *
+ * @return subtitle of the picture-in-picture window.
+ * @see PictureInPictureParams.Builder#setSubtitle(CharSequence)
*/
- @TestApi
@Nullable
public CharSequence getSubtitle() {
return mSubtitle;
@@ -716,7 +749,7 @@ public final class PictureInPictureParams implements Parcelable {
@Override
public String toString() {
return "PictureInPictureParams("
- + " aspectRatio=" + getAspectRatioRational()
+ + " aspectRatio=" + getAspectRatio()
+ " expandedAspectRatio=" + mExpandedAspectRatio
+ " sourceRectHint=" + getSourceRectHint()
+ " hasSetActions=" + hasSetActions()
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 150888ccb2d8..89854bbab3e8 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -24,9 +24,6 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
-import android.app.compat.CompatChanges;
-import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
@@ -42,7 +39,6 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.UserHandle;
import android.util.Pair;
import android.util.Slog;
import android.view.View;
@@ -524,27 +520,6 @@ public class StatusBarManager {
private final Map<NearbyMediaDevicesProvider, NearbyMediaDevicesProviderWrapper>
nearbyMediaDevicesProviderMap = new HashMap<>();
- /**
- * Media controls based on {@link android.app.Notification.MediaStyle} notifications will have
- * actions based on the media session's {@link android.media.session.PlaybackState}, rather than
- * the notification's actions.
- *
- * These actions will be:
- * - Play/Pause (depending on whether the current state is a playing state)
- * - Previous (if declared), or a custom action if the slot is not reserved with
- * {@code SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV}
- * - Next (if declared), or a custom action if the slot is not reserved with
- * {@code SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT}
- * - Custom action
- * - Custom action
- *
- * @see androidx.media.utils.MediaConstants#SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV
- * @see androidx.media.utils.MediaConstants#SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT
- */
- @ChangeId
- @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
- private static final long MEDIA_CONTROL_SESSION_ACTIONS = 203800354L;
-
@UnsupportedAppUsage
private Context mContext;
private IStatusBarService mService;
@@ -1152,20 +1127,6 @@ public class StatusBarManager {
}
}
- /**
- * Checks whether the given package should use session-based actions for its media controls.
- *
- * @param packageName App posting media controls
- * @param userId Current user ID
- * @return true if the app supports session actions
- *
- * @hide
- */
- public static boolean useMediaSessionActionsForApp(String packageName, int userId) {
- UserHandle handle = UserHandle.getUserHandleForUid(userId);
- return CompatChanges.isChangeEnabled(MEDIA_CONTROL_SESSION_ACTIONS, packageName, handle);
- }
-
/** @hide */
public static String windowStateToString(int state) {
if (state == WINDOW_STATE_HIDING) return "WINDOW_STATE_HIDING";
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 27fe312706ff..7269b0d91d02 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -15765,4 +15765,23 @@ public class DevicePolicyManager {
}
return deviceManagerConfig;
}
+
+ /**
+ * @return {@code true} if bypassing the device policy management role qualification is allowed
+ * with the current state of the device.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS)
+ public boolean shouldAllowBypassingDevicePolicyManagementRoleQualification() {
+ if (mService != null) {
+ try {
+ return mService.shouldAllowBypassingDevicePolicyManagementRoleQualification();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return false;
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 77db14654592..fb1ca41ccc56 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -558,4 +558,6 @@ interface IDevicePolicyManager {
void setStrings(in List<DevicePolicyStringResource> strings);
void resetStrings(in String[] stringIds);
ParcelableResource getString(String stringId);
+
+ boolean shouldAllowBypassingDevicePolicyManagementRoleQualification();
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 478befd9c26d..2c207bc90444 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -8903,8 +8903,12 @@ public class Intent implements Parcelable, Cloneable {
* @return the value of an item previously added with putExtra(),
* or null if no Parcelable value was found.
*
+ * @deprecated Use the type-safer {@link #getParcelableExtra(String, Class)} starting from
+ * Android {@link Build.VERSION_CODES#TIRAMISU}.
+ *
* @see #putExtra(String, Parcelable)
*/
+ @Deprecated
public @Nullable <T extends Parcelable> T getParcelableExtra(String name) {
return mExtras == null ? null : mExtras.<T>getParcelable(name);
}
@@ -8913,12 +8917,31 @@ public class Intent implements Parcelable, Cloneable {
* Retrieve extended data from the intent.
*
* @param name The name of the desired item.
+ * @param clazz The type of the object expected.
+ *
+ * @return the value of an item previously added with putExtra(),
+ * or null if no Parcelable value was found.
+ *
+ * @see #putExtra(String, Parcelable)
+ */
+ public @Nullable <T> T getParcelableExtra(@Nullable String name, @NonNull Class<T> clazz) {
+ return mExtras == null ? null : mExtras.getParcelable(name, clazz);
+ }
+
+ /**
+ * Retrieve extended data from the intent.
+ *
+ * @param name The name of the desired item.
*
* @return the value of an item previously added with putExtra(),
* or null if no Parcelable[] value was found.
*
+ * @deprecated Use the type-safer {@link #getParcelableArrayExtra(String, Class)} starting from
+ * Android {@link Build.VERSION_CODES#TIRAMISU}.
+ *
* @see #putExtra(String, Parcelable[])
*/
+ @Deprecated
public @Nullable Parcelable[] getParcelableArrayExtra(String name) {
return mExtras == null ? null : mExtras.getParcelableArray(name);
}
@@ -8927,13 +8950,34 @@ public class Intent implements Parcelable, Cloneable {
* Retrieve extended data from the intent.
*
* @param name The name of the desired item.
+ * @param clazz The type of the items inside the array. This is only verified when unparceling.
+ *
+ * @return the value of an item previously added with putExtra(),
+ * or null if no Parcelable[] value was found.
+ *
+ * @see #putExtra(String, Parcelable[])
+ */
+ @SuppressLint({"ArrayReturn", "NullableCollection"})
+ public @Nullable <T> T[] getParcelableArrayExtra(@Nullable String name,
+ @NonNull Class<T> clazz) {
+ return mExtras == null ? null : mExtras.getParcelableArray(name, clazz);
+ }
+
+ /**
+ * Retrieve extended data from the intent.
+ *
+ * @param name The name of the desired item.
*
* @return the value of an item previously added with
* putParcelableArrayListExtra(), or null if no
* ArrayList<Parcelable> value was found.
*
+ * @deprecated Use the type-safer {@link #getParcelableArrayListExtra(String, Class)} starting
+ * from Android {@link Build.VERSION_CODES#TIRAMISU}.
+ *
* @see #putParcelableArrayListExtra(String, ArrayList)
*/
+ @Deprecated
public @Nullable <T extends Parcelable> ArrayList<T> getParcelableArrayListExtra(String name) {
return mExtras == null ? null : mExtras.<T>getParcelableArrayList(name);
}
@@ -8942,10 +8986,32 @@ public class Intent implements Parcelable, Cloneable {
* Retrieve extended data from the intent.
*
* @param name The name of the desired item.
+ * @param clazz The type of the items inside the array list. This is only verified when
+ * unparceling.
+ *
+ * @return the value of an item previously added with
+ * putParcelableArrayListExtra(), or null if no
+ * ArrayList<Parcelable> value was found.
+ *
+ * @see #putParcelableArrayListExtra(String, ArrayList)
+ */
+ @SuppressLint({"ConcreteCollection", "NullableCollection"})
+ public @Nullable <T> ArrayList<T> getParcelableArrayListExtra(@Nullable String name,
+ @NonNull Class<? extends T> clazz) {
+ return mExtras == null ? null : mExtras.<T>getParcelableArrayList(name, clazz);
+ }
+
+ /**
+ * Retrieve extended data from the intent.
+ *
+ * @param name The name of the desired item.
*
* @return the value of an item previously added with putExtra(),
* or null if no Serializable value was found.
*
+ * @deprecated Use the type-safer {@link #getSerializableExtra(String, Class)} starting from
+ * Android {@link Build.VERSION_CODES#TIRAMISU}.
+ *
* @see #putExtra(String, Serializable)
*/
public @Nullable Serializable getSerializableExtra(String name) {
@@ -8956,6 +9022,22 @@ public class Intent implements Parcelable, Cloneable {
* Retrieve extended data from the intent.
*
* @param name The name of the desired item.
+ * @param clazz The type of the object expected.
+ *
+ * @return the value of an item previously added with putExtra(),
+ * or null if no Serializable value was found.
+ *
+ * @see #putExtra(String, Serializable)
+ */
+ public @Nullable <T extends Serializable> T getSerializableExtra(@Nullable String name,
+ @NonNull Class<T> clazz) {
+ return mExtras == null ? null : mExtras.getSerializable(name, clazz);
+ }
+
+ /**
+ * Retrieve extended data from the intent.
+ *
+ * @param name The name of the desired item.
*
* @return the value of an item previously added with
* putIntegerArrayListExtra(), or null if no
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index a05f5c927b29..c8bbb0c1994d 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -79,6 +79,13 @@ public final class AssetManager implements AutoCloseable {
@GuardedBy("sSync") private static ArraySet<ApkAssets> sSystemApkAssetsSet;
/**
+ * Cookie value to use when the actual cookie is unknown. This value tells the system to search
+ * all the ApkAssets for the asset.
+ * @hide
+ */
+ public static final int COOKIE_UNKNOWN = -1;
+
+ /**
* Mode for {@link #open(String, int)}: no specific information about how
* data will be accessed.
*/
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 18ec8f57ad3a..2c2a703b16e2 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -580,6 +580,24 @@ public class NetworkPolicyManager {
}
/**
+ * Notifies that the specified {@link NetworkStatsProvider} has reached its warning threshold
+ * which was set through {@link NetworkStatsProvider#onSetWarningAndLimit(String, long, long)}.
+ *
+ * @hide
+ */
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_STACK})
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public void notifyStatsProviderWarningReached() {
+ try {
+ mService.notifyStatsProviderWarningOrLimitReached();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Notifies that the specified {@link NetworkStatsProvider} has reached its quota
* which was set through {@link NetworkStatsProvider#onSetLimit(String, long)} or
* {@link NetworkStatsProvider#onSetWarningAndLimit(String, long, long)}.
@@ -590,7 +608,7 @@ public class NetworkPolicyManager {
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
android.Manifest.permission.NETWORK_STACK})
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public void notifyStatsProviderWarningOrLimitReached() {
+ public void notifyStatsProviderLimitReached() {
try {
mService.notifyStatsProviderWarningOrLimitReached();
} catch (RemoteException e) {
diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java
index 190adbdfd5db..61098d60566f 100644
--- a/core/java/android/view/HandwritingInitiator.java
+++ b/core/java/android/view/HandwritingInitiator.java
@@ -55,10 +55,10 @@ public class HandwritingInitiator {
*/
private final int mTouchSlop;
/**
- * The timeout used to distinguish tap from handwriting. If the stylus doesn't move before this
- * timeout, it's not considered as handwriting.
+ * The timeout used to distinguish tap or long click from handwriting. If the stylus doesn't
+ * move before this timeout, it's not considered as handwriting.
*/
- private final long mTapTimeoutInMillis;
+ private final long mHandwritingTimeoutInMillis;
private State mState = new State();
private final HandwritingAreaTracker mHandwritingAreasTracker = new HandwritingAreaTracker();
@@ -90,7 +90,7 @@ public class HandwritingInitiator {
public HandwritingInitiator(@NonNull ViewConfiguration viewConfiguration,
@NonNull InputMethodManager inputMethodManager) {
mTouchSlop = viewConfiguration.getScaledTouchSlop();
- mTapTimeoutInMillis = ViewConfiguration.getTapTimeout();
+ mHandwritingTimeoutInMillis = ViewConfiguration.getLongPressTimeout();
mImm = inputMethodManager;
}
@@ -145,7 +145,7 @@ public class HandwritingInitiator {
final long timeElapsed =
motionEvent.getEventTime() - mState.mStylusDownTimeInMillis;
- if (timeElapsed > mTapTimeoutInMillis) {
+ if (timeElapsed > mHandwritingTimeoutInMillis) {
reset();
return;
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index cdbf8b44140a..b72725ad2c32 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3165,11 +3165,8 @@ public final class ViewRootImpl implements ViewParent,
// possible that checking the most recent value is actually more
// correct here.
if (!mStopped || wasReportNextDraw) {
- boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
- (relayoutResult&WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0);
- if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
- || mHeight != host.getMeasuredHeight() || dispatchApplyInsets ||
- updatedConfiguration) {
+ if (mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight()
+ || dispatchApplyInsets || updatedConfiguration) {
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width,
lp.privateFlags);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height,
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 2dc5fbd5439f..b0da877bfddd 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -60,47 +60,41 @@ public final class WindowManagerGlobal {
private static boolean sUseBLASTAdapter = false;
/**
- * The user is navigating with keys (not the touch screen), so
- * navigational focus should be shown.
- */
- public static final int RELAYOUT_RES_IN_TOUCH_MODE = 0x1;
-
- /**
* This is the first time the window is being drawn,
* so the client must call drawingFinished() when done
*/
- public static final int RELAYOUT_RES_FIRST_TIME = 0x2;
+ public static final int RELAYOUT_RES_FIRST_TIME = 1;
/**
* The window manager has changed the surface from the last call.
*/
- public static final int RELAYOUT_RES_SURFACE_CHANGED = 0x4;
+ public static final int RELAYOUT_RES_SURFACE_CHANGED = 1 << 1;
/**
* The window is being resized by dragging on the docked divider. The client should render
* at (0, 0) and extend its background to the background frame passed into
* {@link IWindow#resized}.
*/
- public static final int RELAYOUT_RES_DRAG_RESIZING_DOCKED = 0x8;
+ public static final int RELAYOUT_RES_DRAG_RESIZING_DOCKED = 1 << 2;
/**
* The window is being resized by dragging one of the window corners,
* in this case the surface would be fullscreen-sized. The client should
* render to the actual frame location (instead of (0,curScrollY)).
*/
- public static final int RELAYOUT_RES_DRAG_RESIZING_FREEFORM = 0x10;
+ public static final int RELAYOUT_RES_DRAG_RESIZING_FREEFORM = 1 << 3;
/**
* The window manager has changed the size of the surface from the last call.
*/
- public static final int RELAYOUT_RES_SURFACE_RESIZED = 0x20;
+ public static final int RELAYOUT_RES_SURFACE_RESIZED = 1 << 4;
/**
* In multi-window we force show the system bars. Because we don't want that the surface size
* changes in this mode, we instead have a flag whether the system bar sizes should always be
* consumed, so the app is treated like there is no virtual system bars at all.
*/
- public static final int RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS = 0x40;
+ public static final int RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS = 1 << 5;
/**
* This flag indicates the client should not directly submit it's next frame,
@@ -108,7 +102,7 @@ public final class WindowManagerGlobal {
* {@link WindowManagerService#finishDrawing}. This is used by the WM
* BLASTSyncEngine to synchronize rendering of multiple windows.
*/
- public static final int RELAYOUT_RES_BLAST_SYNC = 0x80;
+ public static final int RELAYOUT_RES_BLAST_SYNC = 1 << 6;
/**
* Flag for relayout: the client will be later giving
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index ad151df05579..06588b2cbb6d 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -332,8 +332,7 @@ public class WindowlessWindowManager implements IWindowSession {
outInsetsState.set(mInsetsState);
}
- // Include whether the window is in touch mode.
- return isInTouchMode() ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0;
+ return 0;
}
@Override
diff --git a/core/proto/android/os/appbatterystats.proto b/core/proto/android/os/appbatterystats.proto
new file mode 100644
index 000000000000..8769ebb74979
--- /dev/null
+++ b/core/proto/android/os/appbatterystats.proto
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+syntax = "proto2";
+package android.os;
+
+option java_multiple_files = true;
+
+message AppBatteryStatsProto {
+ message UidStats {
+ optional int32 uid = 1;
+
+ message ProcessStateStats {
+ enum ProcessState {
+ UNSPECIFIED = 0;
+ FOREGROUND = 1;
+ BACKGROUND = 2;
+ FOREGROUND_SERVICE = 3;
+ CACHED = 4;
+ }
+
+ optional ProcessState process_state = 1;
+
+ // Time spent in this state in the past 24 hours
+ optional int64 duration_ms = 2;
+ // Estimated power consumed in this state in the past 24 hours
+ optional double power_mah = 3;
+ }
+
+ repeated ProcessStateStats process_state_stats = 2;
+ }
+
+ repeated UidStats uid_stats = 1;
+}
diff --git a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
index 1ae9649dfe06..e303934c4aad 100644
--- a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
+++ b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
@@ -60,7 +60,7 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class HandwritingInitiatorTest {
private static final int TOUCH_SLOP = 8;
- private static final long TAP_TIMEOUT = ViewConfiguration.getTapTimeout();
+ private static final long TIMEOUT = ViewConfiguration.getLongPressTimeout();
private static final Rect sHwArea = new Rect(100, 200, 500, 500);
private HandwritingInitiator mHandwritingInitiator;
@@ -177,7 +177,7 @@ public class HandwritingInitiatorTest {
}
@Test
- public void onTouchEvent_notStartHandwriting_when_stylusMove_afterTapTimeOut() {
+ public void onTouchEvent_notStartHandwriting_when_stylusMove_afterTimeOut() {
mHandwritingInitiator.onInputConnectionCreated(mTestView);
final int x1 = 10;
final int y1 = 10;
@@ -187,7 +187,7 @@ public class HandwritingInitiatorTest {
final int x2 = x1 + TOUCH_SLOP * 2;
final int y2 = y1;
- final long time2 = time1 + TAP_TIMEOUT + 10L;
+ final long time2 = time1 + TIMEOUT + 10L;
MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, time2);
mHandwritingInitiator.onTouchEvent(stylusEvent2);
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 2a82d8ecf5ee..df51871c57d9 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -71,14 +71,6 @@ prebuilt_etc {
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.cellbroadcastreceiver",
- system_ext_specific: true,
- sub_dir: "permissions",
- src: "com.android.cellbroadcastreceiver.xml",
- filename_from_src: true,
-}
-
-prebuilt_etc {
name: "privapp_whitelist_com.android.contacts",
product_specific: true,
sub_dir: "permissions",
diff --git a/data/etc/com.android.cellbroadcastreceiver.xml b/data/etc/com.android.cellbroadcastreceiver.xml
deleted file mode 100644
index bc62bbc845f3..000000000000
--- a/data/etc/com.android.cellbroadcastreceiver.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?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
- -->
-<permissions>
- <privapp-permissions package="com.android.cellbroadcastreceiver">
- <permission name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS"/>
- <permission name="android.permission.INTERACT_ACROSS_USERS"/>
- <permission name="android.permission.MANAGE_USERS"/>
- <permission name="android.permission.STATUS_BAR"/>
- <permission name="android.permission.MODIFY_PHONE_STATE"/>
- <permission name="android.permission.MODIFY_CELL_BROADCASTS"/>
- <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
- <permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
- <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
- </privapp-permissions>
-</permissions>
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index 2d1db716b700..d1873a0f40cf 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -76,8 +76,5 @@
<permission name="android.permission.FORCE_STOP_PACKAGES" />
<permission name="android.permission.ACCESS_FPS_COUNTER" />
<permission name="android.permission.CHANGE_CONFIGURATION" />
- <permission name="android.permission.LOG_COMPAT_CHANGE" />
- <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
- <permission name="android.permission.READ_DEVICE_CONFIG" />
</privapp-permissions>
</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 3e91eedf2dde..56285489a91d 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -38,24 +38,6 @@ applications that come with the platform
<permission name="android.permission.CRYPT_KEEPER"/>
</privapp-permissions>
- <privapp-permissions package="com.android.cellbroadcastreceiver.module">
- <permission name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS"/>
- <permission name="android.permission.INTERACT_ACROSS_USERS"/>
- <permission name="android.permission.MANAGE_USERS"/>
- <permission name="android.permission.STATUS_BAR"/>
- <permission name="android.permission.MODIFY_PHONE_STATE"/>
- <permission name="android.permission.MODIFY_CELL_BROADCASTS"/>
- <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
- <permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
- <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
- </privapp-permissions>
-
- <privapp-permissions package="com.android.cellbroadcastservice">
- <permission name="android.permission.MODIFY_PHONE_STATE"/>
- <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
- <permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.externalstorage">
<permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 61f7facf0916..a2f5301e353f 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -329,7 +329,7 @@ public class Typeface {
FontFamily.Builder familyBuilder = null;
for (final FontFileResourceEntry fontFile : filesEntry.getEntries()) {
final Font.Builder fontBuilder = new Font.Builder(mgr, fontFile.getFileName(),
- false /* isAsset */, 0 /* cookie */)
+ false /* isAsset */, AssetManager.COOKIE_UNKNOWN)
.setTtcIndex(fontFile.getTtcIndex())
.setFontVariationSettings(fontFile.getVariationSettings());
if (fontFile.getWeight() != Typeface.RESOLVE_BY_FONT_TABLE) {
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index cd7936d50dff..abd0be9c2872 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -179,7 +179,7 @@ public final class Font {
*/
public Builder(@NonNull AssetManager am, @NonNull String path) {
try {
- mBuffer = createBuffer(am, path, true /* is asset */, 0 /* cookie */);
+ mBuffer = createBuffer(am, path, true /* is asset */, AssetManager.COOKIE_UNKNOWN);
} catch (IOException e) {
mException = e;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
index c2d582354b13..7397e5273753 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
@@ -194,7 +194,7 @@ public class PipBoundsAlgorithm {
public float getAspectRatioOrDefault(
@android.annotation.Nullable PictureInPictureParams params) {
return params != null && params.hasSetAspectRatio()
- ? params.getAspectRatio()
+ ? params.getAspectRatioFloat()
: getDefaultAspectRatio();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index c1e78251da2b..5d6b041f9006 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -1071,13 +1071,13 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
*/
private boolean applyPictureInPictureParams(@NonNull PictureInPictureParams params) {
final Rational currentAspectRatio =
- mPictureInPictureParams != null ? mPictureInPictureParams.getAspectRatioRational()
+ mPictureInPictureParams != null ? mPictureInPictureParams.getAspectRatio()
: null;
final boolean aspectRatioChanged = !Objects.equals(currentAspectRatio,
- params.getAspectRatioRational());
+ params.getAspectRatio());
mPictureInPictureParams = params;
if (aspectRatioChanged) {
- mPipBoundsState.setAspectRatio(params.getAspectRatio());
+ mPipBoundsState.setAspectRatio(params.getAspectRatioFloat());
}
return aspectRatioChanged;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
index d880f821ee73..986554853034 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
@@ -75,7 +75,7 @@ public class TvPipBoundsState extends PipBoundsState {
public void setBoundsStateForEntry(ComponentName componentName, ActivityInfo activityInfo,
PictureInPictureParams params, PipBoundsAlgorithm pipBoundsAlgorithm) {
super.setBoundsStateForEntry(componentName, activityInfo, params, pipBoundsAlgorithm);
- setDesiredTvExpandedAspectRatio(params.getExpandedAspectRatio(), true);
+ setDesiredTvExpandedAspectRatio(params.getExpandedAspectRatioFloat(), true);
}
/** Resets the TV PiP state for a new activity. */
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index f1605f1ffe5d..033056cb2a69 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -132,31 +132,31 @@ public class Location implements Parcelable {
}
/**
- * Construct a new Location object that is copied from an existing one.
+ * Constructs a new location copied from the given location.
*/
- public Location(@NonNull Location l) {
- set(l);
+ public Location(@NonNull Location location) {
+ set(location);
}
/**
* Turns this location into a copy of the given location.
*/
- public void set(@NonNull Location l) {
- mFieldsMask = l.mFieldsMask;
- mProvider = l.mProvider;
- mTimeMs = l.mTimeMs;
- mElapsedRealtimeNs = l.mElapsedRealtimeNs;
- mElapsedRealtimeUncertaintyNs = l.mElapsedRealtimeUncertaintyNs;
- mLatitudeDegrees = l.mLatitudeDegrees;
- mLongitudeDegrees = l.mLongitudeDegrees;
- mHorizontalAccuracyMeters = l.mHorizontalAccuracyMeters;
- mAltitudeMeters = l.mAltitudeMeters;
- mAltitudeAccuracyMeters = l.mAltitudeAccuracyMeters;
- mSpeedMetersPerSecond = l.mSpeedMetersPerSecond;
- mSpeedAccuracyMetersPerSecond = l.mSpeedAccuracyMetersPerSecond;
- mBearingDegrees = l.mBearingDegrees;
- mBearingAccuracyDegrees = l.mBearingAccuracyDegrees;
- mExtras = (l.mExtras == null) ? null : new Bundle(l.mExtras);
+ public void set(@NonNull Location location) {
+ mFieldsMask = location.mFieldsMask;
+ mProvider = location.mProvider;
+ mTimeMs = location.mTimeMs;
+ mElapsedRealtimeNs = location.mElapsedRealtimeNs;
+ mElapsedRealtimeUncertaintyNs = location.mElapsedRealtimeUncertaintyNs;
+ mLatitudeDegrees = location.mLatitudeDegrees;
+ mLongitudeDegrees = location.mLongitudeDegrees;
+ mHorizontalAccuracyMeters = location.mHorizontalAccuracyMeters;
+ mAltitudeMeters = location.mAltitudeMeters;
+ mAltitudeAccuracyMeters = location.mAltitudeAccuracyMeters;
+ mSpeedMetersPerSecond = location.mSpeedMetersPerSecond;
+ mSpeedAccuracyMetersPerSecond = location.mSpeedAccuracyMetersPerSecond;
+ mBearingDegrees = location.mBearingDegrees;
+ mBearingAccuracyDegrees = location.mBearingAccuracyDegrees;
+ mExtras = (location.mExtras == null) ? null : new Bundle(location.mExtras);
}
/**
@@ -182,14 +182,13 @@ public class Location implements Parcelable {
}
/**
- * Returns the approximate distance in meters between this
- * location and the given location. Distance is defined using
- * the WGS84 ellipsoid.
+ * Returns the approximate distance in meters between this location and the given location.
+ * Distance is defined using the WGS84 ellipsoid.
*
* @param dest the destination location
* @return the approximate distance in meters
*/
- public @FloatRange float distanceTo(@NonNull Location dest) {
+ public @FloatRange(from = 0.0) float distanceTo(@NonNull Location dest) {
BearingDistanceCache cache = sBearingDistanceCache.get();
// See if we already have the result
if (mLatitudeDegrees != cache.mLat1 || mLongitudeDegrees != cache.mLon1
@@ -201,11 +200,10 @@ public class Location implements Parcelable {
}
/**
- * Returns the approximate initial bearing in degrees East of true
- * North when traveling along the shortest path between this
- * location and the given location. The shortest path is defined
- * using the WGS84 ellipsoid. Locations that are (nearly)
- * antipodal may produce meaningless results.
+ * Returns the approximate initial bearing in degrees east of true north when traveling along
+ * the shortest path between this location and the given location. The shortest path is defined
+ * using the WGS84 ellipsoid. Locations that are (nearly) antipodal may produce meaningless
+ * results.
*
* @param dest the destination location
* @return the initial bearing in degrees
@@ -254,7 +252,7 @@ public class Location implements Parcelable {
* not be used to order or compare locations. Prefer {@link #getElapsedRealtimeNanos} for that
* purpose, as the elapsed realtime clock is guaranteed to be monotonic.
*
- * <p>On the other hand, this method may be useful for presenting a human readable time to the
+ * <p>On the other hand, this method may be useful for presenting a human-readable time to the
* user, or as a heuristic for comparing location fixes across reboot or across devices.
*
* <p>All locations generated by the {@link LocationManager} are guaranteed to have this time
@@ -263,25 +261,24 @@ public class Location implements Parcelable {
*
* @return the Unix epoch time of this location
*/
- public @IntRange long getTime() {
+ public @IntRange(from = 0) long getTime() {
return mTimeMs;
}
/**
* Sets the Unix epoch time of this location fix, in milliseconds since the start of the Unix
- * epoch (00:00:00 January 1, 1970 UTC).
+ * epoch (00:00:00 January 1 1970 UTC).
*
* @param timeMs the Unix epoch time of this location
- * @see #getTime for more information about times / clocks
*/
- public void setTime(@IntRange long timeMs) {
+ public void setTime(@IntRange(from = 0) long timeMs) {
mTimeMs = timeMs;
}
/**
* Return the time of this fix in nanoseconds of elapsed realtime since system boot.
*
- * <p>This value can be compared with {@link android.os.SystemClock#elapsedRealtimeNanos}, to
+ * <p>This value can be compared with {@link android.os.SystemClock#elapsedRealtimeNanos} to
* reliably order or compare locations. This is reliable because elapsed realtime is guaranteed
* to be monotonic and continues to increment even when the system is in deep sleep (unlike
* {@link #getTime}). However, since elapsed realtime is with reference to system boot, it does
@@ -292,7 +289,7 @@ public class Location implements Parcelable {
*
* @return elapsed realtime of this location in nanoseconds
*/
- public @IntRange long getElapsedRealtimeNanos() {
+ public @IntRange(from = 0) long getElapsedRealtimeNanos() {
return mElapsedRealtimeNs;
}
@@ -302,7 +299,7 @@ public class Location implements Parcelable {
* @return elapsed realtime of this location in milliseconds
* @see #getElapsedRealtimeNanos()
*/
- public @IntRange long getElapsedRealtimeMillis() {
+ public @IntRange(from = 0) long getElapsedRealtimeMillis() {
return NANOSECONDS.toMillis(mElapsedRealtimeNs);
}
@@ -312,7 +309,7 @@ public class Location implements Parcelable {
*
* @return age of this location in milliseconds
*/
- public @IntRange long getElapsedRealtimeAgeMillis() {
+ public @IntRange(from = 0) long getElapsedRealtimeAgeMillis() {
return getElapsedRealtimeAgeMillis(SystemClock.elapsedRealtime());
}
@@ -323,7 +320,8 @@ public class Location implements Parcelable {
* @param referenceRealtimeMs reference realtime in milliseconds
* @return age of this location in milliseconds
*/
- public @IntRange long getElapsedRealtimeAgeMillis(@IntRange long referenceRealtimeMs) {
+ public long getElapsedRealtimeAgeMillis(
+ @IntRange(from = 0) long referenceRealtimeMs) {
return referenceRealtimeMs - getElapsedRealtimeMillis();
}
@@ -332,7 +330,7 @@ public class Location implements Parcelable {
*
* @param elapsedRealtimeNs elapsed realtime in nanoseconds
*/
- public void setElapsedRealtimeNanos(@IntRange long elapsedRealtimeNs) {
+ public void setElapsedRealtimeNanos(@IntRange(from = 0) long elapsedRealtimeNs) {
mElapsedRealtimeNs = elapsedRealtimeNs;
}
@@ -346,7 +344,7 @@ public class Location implements Parcelable {
*
* @return uncertainty in nanoseconds of the elapsed realtime of this location
*/
- public @FloatRange double getElapsedRealtimeUncertaintyNanos() {
+ public @FloatRange(from = 0.0) double getElapsedRealtimeUncertaintyNanos() {
return mElapsedRealtimeUncertaintyNs;
}
@@ -358,20 +356,20 @@ public class Location implements Parcelable {
* this location
*/
public void setElapsedRealtimeUncertaintyNanos(
- @FloatRange double elapsedRealtimeUncertaintyNs) {
+ @FloatRange(from = 0.0) double elapsedRealtimeUncertaintyNs) {
mElapsedRealtimeUncertaintyNs = elapsedRealtimeUncertaintyNs;
mFieldsMask |= HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK;
}
/**
- * True if this location has a elapsed realtime uncertainty, false otherwise.
+ * True if this location has an elapsed realtime uncertainty, false otherwise.
*/
public boolean hasElapsedRealtimeUncertaintyNanos() {
return (mFieldsMask & HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK) != 0;
}
/**
- * Removes the elapsed realtime uncertainy from this location.
+ * Removes the elapsed realtime uncertainty from this location.
*/
public void removeElapsedRealtimeUncertaintyNanos() {
mFieldsMask &= ~HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK;
@@ -383,7 +381,7 @@ public class Location implements Parcelable {
*
* @return latitude of this location
*/
- public @FloatRange double getLatitude() {
+ public @FloatRange(from = -90.0, to = 90.0) double getLatitude() {
return mLatitudeDegrees;
}
@@ -392,7 +390,7 @@ public class Location implements Parcelable {
*
* @param latitudeDegrees latitude in degrees
*/
- public void setLatitude(@FloatRange double latitudeDegrees) {
+ public void setLatitude(@FloatRange(from = -90.0, to = 90.0) double latitudeDegrees) {
mLatitudeDegrees = latitudeDegrees;
}
@@ -402,7 +400,7 @@ public class Location implements Parcelable {
*
* @return longitude of this location
*/
- public @FloatRange double getLongitude() {
+ public @FloatRange(from = -180.0, to = 180.0) double getLongitude() {
return mLongitudeDegrees;
}
@@ -411,7 +409,7 @@ public class Location implements Parcelable {
*
* @param longitudeDegrees longitude in degrees
*/
- public void setLongitude(@FloatRange double longitudeDegrees) {
+ public void setLongitude(@FloatRange(from = -180.0, to = 180.0) double longitudeDegrees) {
mLongitudeDegrees = longitudeDegrees;
}
@@ -423,12 +421,12 @@ public class Location implements Parcelable {
* reported location, there is a 68% chance that the true location falls within this circle.
* This accuracy value is only valid for horizontal positioning, and not vertical positioning.
*
- * <p>This is only valid if {@link #hasSpeed()} is true. All locations generated by the
+ * <p>This is only valid if {@link #hasAccuracy()} is true. All locations generated by the
* {@link LocationManager} include horizontal accuracy.
*
* @return horizontal accuracy of this location
*/
- public @FloatRange float getAccuracy() {
+ public @FloatRange(from = 0.0) float getAccuracy() {
return mHorizontalAccuracyMeters;
}
@@ -437,7 +435,7 @@ public class Location implements Parcelable {
*
* @param horizontalAccuracyMeters horizontal altitude in meters
*/
- public void setAccuracy(@FloatRange float horizontalAccuracyMeters) {
+ public void setAccuracy(@FloatRange(from = 0.0) float horizontalAccuracyMeters) {
mHorizontalAccuracyMeters = horizontalAccuracyMeters;
mFieldsMask |= HAS_HORIZONTAL_ACCURACY_MASK;
}
@@ -500,7 +498,7 @@ public class Location implements Parcelable {
*
* @return vertical accuracy of this location
*/
- public @FloatRange float getVerticalAccuracyMeters() {
+ public @FloatRange(from = 0.0) float getVerticalAccuracyMeters() {
return mAltitudeAccuracyMeters;
}
@@ -509,7 +507,7 @@ public class Location implements Parcelable {
*
* @param altitudeAccuracyMeters altitude accuracy in meters
*/
- public void setVerticalAccuracyMeters(@FloatRange float altitudeAccuracyMeters) {
+ public void setVerticalAccuracyMeters(@FloatRange(from = 0.0) float altitudeAccuracyMeters) {
mAltitudeAccuracyMeters = altitudeAccuracyMeters;
mFieldsMask |= HAS_ALTITUDE_ACCURACY_MASK;
}
@@ -538,17 +536,16 @@ public class Location implements Parcelable {
*
* @return speed at the time of this location
*/
- public @FloatRange float getSpeed() {
+ public @FloatRange(from = 0.0) float getSpeed() {
return mSpeedMetersPerSecond;
}
/**
- * Set the speed at the time of this location, in meters per second. Prefer not to set negative
- * speeds.
+ * Set the speed at the time of this location, in meters per second.
*
* @param speedMetersPerSecond speed in meters per second
*/
- public void setSpeed(@FloatRange float speedMetersPerSecond) {
+ public void setSpeed(@FloatRange(from = 0.0) float speedMetersPerSecond) {
mSpeedMetersPerSecond = speedMetersPerSecond;
mFieldsMask |= HAS_SPEED_MASK;
}
@@ -576,7 +573,7 @@ public class Location implements Parcelable {
*
* @return vertical accuracy of this location
*/
- public @FloatRange float getSpeedAccuracyMetersPerSecond() {
+ public @FloatRange(from = 0.0) float getSpeedAccuracyMetersPerSecond() {
return mSpeedAccuracyMetersPerSecond;
}
@@ -585,7 +582,8 @@ public class Location implements Parcelable {
*
* @param speedAccuracyMeterPerSecond speed accuracy in meters per second
*/
- public void setSpeedAccuracyMetersPerSecond(@FloatRange float speedAccuracyMeterPerSecond) {
+ public void setSpeedAccuracyMetersPerSecond(
+ @FloatRange(from = 0.0) float speedAccuracyMeterPerSecond) {
mSpeedAccuracyMetersPerSecond = speedAccuracyMeterPerSecond;
mFieldsMask |= HAS_SPEED_ACCURACY_MASK;
}
@@ -613,7 +611,7 @@ public class Location implements Parcelable {
*
* @return bearing at the time of this location
*/
- public @FloatRange(from = 0f, to = 360f, toInclusive = false) float getBearing() {
+ public @FloatRange(from = 0.0, to = 360.0, toInclusive = false) float getBearing() {
return mBearingDegrees;
}
@@ -663,7 +661,7 @@ public class Location implements Parcelable {
*
* @return bearing accuracy in degrees of this location
*/
- public @FloatRange float getBearingAccuracyDegrees() {
+ public @FloatRange(from = 0.0) float getBearingAccuracyDegrees() {
return mBearingAccuracyDegrees;
}
@@ -672,7 +670,7 @@ public class Location implements Parcelable {
*
* @param bearingAccuracyDegrees bearing accuracy in degrees
*/
- public void setBearingAccuracyDegrees(@FloatRange float bearingAccuracyDegrees) {
+ public void setBearingAccuracyDegrees(@FloatRange(from = 0.0) float bearingAccuracyDegrees) {
mBearingAccuracyDegrees = bearingAccuracyDegrees;
mFieldsMask |= HAS_BEARING_ACCURACY_MASK;
}
@@ -692,9 +690,11 @@ public class Location implements Parcelable {
}
/**
- * Returns true if the Location came from a mock provider.
+ * Returns true if this is a mock location. If this location comes from the Android framework,
+ * this indicates that the location was provided by a test location provider, and thus may not
+ * be related to the actual location of the device.
*
- * @return true if this Location came from a mock provider, false otherwise
+ * @return true if this location came from a mock provider, false otherwise
* @deprecated Prefer {@link #isMock()} instead.
*/
@Deprecated
@@ -703,9 +703,9 @@ public class Location implements Parcelable {
}
/**
- * Flag this Location as having come from a mock provider or not.
+ * Flag this location as having come from a mock provider or not.
*
- * @param isFromMockProvider true if this Location came from a mock provider, false otherwise
+ * @param isFromMockProvider true if this location came from a mock provider, false otherwise
* @deprecated Prefer {@link #setMock(boolean)} instead.
* @hide
*/
@@ -745,7 +745,7 @@ public class Location implements Parcelable {
* will be present for any location.
*
* <ul>
- * <li> satellites - the number of satellites used to derive the GNSS fix
+ * <li> satellites - the number of satellites used to derive a GNSS fix
* </ul>
*/
public @Nullable Bundle getExtras() {
@@ -899,7 +899,13 @@ public class Location implements Parcelable {
return s.toString();
}
- /** Dumps location. */
+ /**
+ * Dumps location information to the given Printer.
+ *
+ * @deprecated Prefer to use {@link #toString()} along with whatever custom formatting is
+ * required instead of this method. It is not this class's job to manage print representations.
+ */
+ @Deprecated
public void dump(@NonNull Printer pw, @Nullable String prefix) {
pw.println(prefix + this);
}
@@ -1209,10 +1215,10 @@ public class Location implements Parcelable {
* @throws IllegalArgumentException if results is null or has length < 1
*/
public static void distanceBetween(
- @FloatRange double startLatitude,
- @FloatRange double startLongitude,
- @FloatRange double endLatitude,
- @FloatRange double endLongitude,
+ @FloatRange(from = -90.0, to = 90.0) double startLatitude,
+ @FloatRange(from = -180.0, to = 180.0) double startLongitude,
+ @FloatRange(from = -90.0, to = 90.0) double endLatitude,
+ @FloatRange(from = -180.0, to = 180.0) double endLongitude,
float[] results) {
if (results == null || results.length < 1) {
throw new IllegalArgumentException("results is null or has length < 1");
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index bdbb740a849b..c186700a4326 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -39,6 +39,7 @@ import android.media.IRecordingConfigDispatcher;
import android.media.IRingtonePlayer;
import android.media.IStrategyPreferredDevicesDispatcher;
import android.media.ISpatializerCallback;
+import android.media.ISpatializerHeadTrackerAvailableCallback;
import android.media.ISpatializerHeadTrackingModeCallback;
import android.media.ISpatializerHeadToSoundStagePoseCallback;
import android.media.ISpatializerOutputCallback;
@@ -414,6 +415,11 @@ interface IAudioService {
boolean isHeadTrackerEnabled(in AudioDeviceAttributes device);
+ boolean isHeadTrackerAvailable();
+
+ void registerSpatializerHeadTrackerAvailableCallback(
+ in ISpatializerHeadTrackerAvailableCallback cb, boolean register);
+
void setSpatializerEnabled(boolean enabled);
boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af);
diff --git a/media/java/android/media/ISpatializerHeadTrackerAvailableCallback.aidl b/media/java/android/media/ISpatializerHeadTrackerAvailableCallback.aidl
new file mode 100644
index 000000000000..dc5ee1d4e985
--- /dev/null
+++ b/media/java/android/media/ISpatializerHeadTrackerAvailableCallback.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/**
+ * AIDL for the AudioService to signal whether audio device used by Spatializer has head tracker.
+ *
+ * {@hide}
+ */
+oneway interface ISpatializerHeadTrackerAvailableCallback {
+
+ void dispatchSpatializerHeadTrackerAvailable(boolean available);
+}
diff --git a/media/java/android/media/Spatializer.java b/media/java/android/media/Spatializer.java
index be0ef37345ed..8811e16b3317 100644
--- a/media/java/android/media/Spatializer.java
+++ b/media/java/android/media/Spatializer.java
@@ -185,6 +185,45 @@ public class Spatializer {
return false;
}
+ /**
+ * Returns whether a head tracker is currently available for the audio device used by the
+ * spatializer effect.
+ * @return true if a head tracker is available and the effect is enabled, false otherwise.
+ * @see OnHeadTrackerAvailableListener
+ * @see #addOnHeadTrackerAvailableListener(Executor, OnHeadTrackerAvailableListener)
+ */
+ public boolean isHeadTrackerAvailable() {
+ try {
+ return mAm.getService().isHeadTrackerAvailable();
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ return false;
+ }
+
+ /**
+ * Adds a listener to be notified of changes to the availability of a head tracker.
+ * @param executor the {@code Executor} handling the callback
+ * @param listener the listener to receive availability updates
+ * @see #removeOnHeadTrackerAvailableListener(OnHeadTrackerAvailableListener)
+ */
+ public void addOnHeadTrackerAvailableListener(@NonNull @CallbackExecutor Executor executor,
+ @NonNull OnHeadTrackerAvailableListener listener) {
+ mHeadTrackerListenerMgr.addListener(executor, listener,
+ "addOnHeadTrackerAvailableListener",
+ () -> new SpatializerHeadTrackerAvailableDispatcherStub());
+ }
+
+ /**
+ * Removes a previously registered listener for the availability of a head tracker.
+ * @param listener the listener previously registered with
+ * {@link #addOnHeadTrackerAvailableListener(Executor, OnHeadTrackerAvailableListener)}
+ */
+ public void removeOnHeadTrackerAvailableListener(
+ @NonNull OnHeadTrackerAvailableListener listener) {
+ mHeadTrackerListenerMgr.removeListener(listener, "removeOnHeadTrackerAvailableListener");
+ }
+
/** @hide */
@IntDef(flag = false, value = {
SPATIALIZER_IMMERSIVE_LEVEL_OTHER,
@@ -401,6 +440,22 @@ public class Spatializer {
@HeadTrackingModeSet int mode);
}
+ /**
+ * Interface to be notified of changes to the availability of a head tracker on the audio
+ * device to be used by the spatializer effect.
+ */
+ public interface OnHeadTrackerAvailableListener {
+ /**
+ * Called when the availability of the head tracker changed.
+ * @param spatializer the {@code Spatializer} instance for which the head tracker
+ * availability was updated
+ * @param available true if the audio device that would output audio processed by
+ * the {@code Spatializer} has a head tracker associated with it, false
+ * otherwise.
+ */
+ void onHeadTrackerAvailableChanged(@NonNull Spatializer spatializer,
+ boolean available);
+ }
/**
* @hide
@@ -935,6 +990,36 @@ public class Spatializer {
}
//-----------------------------------------------------------------------------
+ // head tracker availability callback management and stub
+ /**
+ * manages the OnHeadTrackerAvailableListener listeners and the
+ * SpatializerHeadTrackerAvailableDispatcherStub
+ */
+ private final CallbackUtil.LazyListenerManager<OnHeadTrackerAvailableListener>
+ mHeadTrackerListenerMgr = new CallbackUtil.LazyListenerManager();
+
+ private final class SpatializerHeadTrackerAvailableDispatcherStub
+ extends ISpatializerHeadTrackerAvailableCallback.Stub
+ implements CallbackUtil.DispatcherStub {
+ @Override
+ public void register(boolean register) {
+ try {
+ mAm.getService().registerSpatializerHeadTrackerAvailableCallback(this, register);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ @Override
+ @SuppressLint("GuardedBy") // lock applied inside callListeners method
+ public void dispatchSpatializerHeadTrackerAvailable(boolean available) {
+ mHeadTrackerListenerMgr.callListeners(
+ (listener) -> listener.onHeadTrackerAvailableChanged(
+ Spatializer.this, available));
+ }
+ }
+
+ //-----------------------------------------------------------------------------
// head pose callback management and stub
private final Object mPoseListenerLock = new Object();
/**
diff --git a/media/java/android/media/tv/AitInfo.java b/media/java/android/media/tv/AitInfo.java
index 8e80a62be3de..c88a2b5048df 100644
--- a/media/java/android/media/tv/AitInfo.java
+++ b/media/java/android/media/tv/AitInfo.java
@@ -17,7 +17,7 @@
package android.media.tv;
import android.annotation.NonNull;
-import android.media.tv.interactive.TvInteractiveAppInfo;
+import android.media.tv.interactive.TvInteractiveAppServiceInfo;
import android.os.Parcel;
import android.os.Parcelable;
@@ -50,7 +50,7 @@ public final class AitInfo implements Parcelable {
/**
* Constructs AIT info.
*/
- public AitInfo(@TvInteractiveAppInfo.InteractiveAppType int type, int version) {
+ public AitInfo(@TvInteractiveAppServiceInfo.InteractiveAppType int type, int version) {
mType = type;
mVersion = version;
}
@@ -58,7 +58,7 @@ public final class AitInfo implements Parcelable {
/**
* Gets interactive app type.
*/
- @TvInteractiveAppInfo.InteractiveAppType
+ @TvInteractiveAppServiceInfo.InteractiveAppType
public int getType() {
return mType;
}
diff --git a/media/java/android/media/tv/CommandRequest.java b/media/java/android/media/tv/CommandRequest.java
index ffb6e07bc485..3245fb504f85 100644
--- a/media/java/android/media/tv/CommandRequest.java
+++ b/media/java/android/media/tv/CommandRequest.java
@@ -24,6 +24,8 @@ import android.os.Parcelable;
* A request for command from broadcast signal.
*/
public final class CommandRequest extends BroadcastInfoRequest implements Parcelable {
+ public static final String ARGUMENT_TYPE_XML = "xml";
+ public static final String ARGUMENT_TYPE_JSON = "json";
private static final @TvInputManager.BroadcastInfoType int REQUEST_TYPE =
TvInputManager.BROADCAST_INFO_TYPE_COMMAND;
@@ -41,35 +43,38 @@ public final class CommandRequest extends BroadcastInfoRequest implements Parcel
}
};
- private final String mNameSpace;
+ private final String mNamespace;
private final String mName;
private final String mArguments;
+ private final String mArgumentType;
static CommandRequest createFromParcelBody(Parcel in) {
return new CommandRequest(in);
}
- public CommandRequest(int requestId, @RequestOption int option, @NonNull String nameSpace,
- @NonNull String name, @NonNull String arguments) {
+ public CommandRequest(int requestId, @RequestOption int option, @NonNull String namespace,
+ @NonNull String name, @NonNull String arguments, @NonNull String argumentType) {
super(REQUEST_TYPE, requestId, option);
- mNameSpace = nameSpace;
+ mNamespace = namespace;
mName = name;
mArguments = arguments;
+ mArgumentType = argumentType;
}
CommandRequest(Parcel source) {
super(REQUEST_TYPE, source);
- mNameSpace = source.readString();
+ mNamespace = source.readString();
mName = source.readString();
mArguments = source.readString();
+ mArgumentType = source.readString();
}
/**
* Gets the namespace of the command.
*/
@NonNull
- public String getNameSpace() {
- return mNameSpace;
+ public String getNamespace() {
+ return mNamespace;
}
/**
@@ -89,6 +94,15 @@ public final class CommandRequest extends BroadcastInfoRequest implements Parcel
return mArguments;
}
+ /**
+ * Gets the argument type of the command.
+ * It could be either JSON or XML.
+ */
+ @NonNull
+ public String getArgumentType() {
+ return mArgumentType;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -97,8 +111,9 @@ public final class CommandRequest extends BroadcastInfoRequest implements Parcel
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
- dest.writeString(mNameSpace);
+ dest.writeString(mNamespace);
dest.writeString(mName);
dest.writeString(mArguments);
+ dest.writeString(mArgumentType);
}
}
diff --git a/media/java/android/media/tv/CommandResponse.java b/media/java/android/media/tv/CommandResponse.java
index c8853f1d8373..8e448cdbd707 100644
--- a/media/java/android/media/tv/CommandResponse.java
+++ b/media/java/android/media/tv/CommandResponse.java
@@ -25,6 +25,8 @@ import android.os.Parcelable;
* A response for command from broadcast signal.
*/
public final class CommandResponse extends BroadcastInfoResponse implements Parcelable {
+ public static final String RESPONSE_TYPE_XML = "xml";
+ public static final String RESPONSE_TYPE_JSON = "json";
private static final @TvInputManager.BroadcastInfoType int RESPONSE_TYPE =
TvInputManager.BROADCAST_INFO_TYPE_COMMAND;
@@ -43,20 +45,23 @@ public final class CommandResponse extends BroadcastInfoResponse implements Parc
};
private final String mResponse;
+ private final String mResponseType;
static CommandResponse createFromParcelBody(Parcel in) {
return new CommandResponse(in);
}
- public CommandResponse(int requestId, int sequence,
- @ResponseResult int responseResult, @Nullable String response) {
+ public CommandResponse(int requestId, int sequence, @ResponseResult int responseResult,
+ @Nullable String response, @NonNull String responseType) {
super(RESPONSE_TYPE, requestId, sequence, responseResult);
mResponse = response;
+ mResponseType = responseType;
}
CommandResponse(Parcel source) {
super(RESPONSE_TYPE, source);
mResponse = source.readString();
+ mResponseType = source.readString();
}
/**
@@ -68,6 +73,15 @@ public final class CommandResponse extends BroadcastInfoResponse implements Parc
return mResponse;
}
+ /**
+ * Gets the type of the command response.
+ * It could be either JSON or XML.
+ */
+ @NonNull
+ public String getResponseType() {
+ return mResponseType;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -77,5 +91,6 @@ public final class CommandResponse extends BroadcastInfoResponse implements Parc
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(mResponse);
+ dest.writeString(mResponseType);
}
}
diff --git a/media/java/android/media/tv/SectionRequest.java b/media/java/android/media/tv/SectionRequest.java
index 5957528554dc..078e83222e4e 100644
--- a/media/java/android/media/tv/SectionRequest.java
+++ b/media/java/android/media/tv/SectionRequest.java
@@ -80,6 +80,11 @@ public final class SectionRequest extends BroadcastInfoRequest implements Parcel
/**
* Gets the version number of requested session. If it is null, value will be -1.
+ * <p>The consistency of version numbers between request and response depends on
+ * {@link BroadcastInfoRequest.RequestOption}. If the request has RequestOption value
+ * REQUEST_OPTION_AUTO_UPDATE, then the response may be set to the latest version which may be
+ * different from the version of the request. Otherwise, response with a different version from
+ * its request will be considered invalid.
*/
public int getVersion() {
return mVersion;
diff --git a/media/java/android/media/tv/SectionResponse.java b/media/java/android/media/tv/SectionResponse.java
index 35836bed385f..f38ea9dfac99 100644
--- a/media/java/android/media/tv/SectionResponse.java
+++ b/media/java/android/media/tv/SectionResponse.java
@@ -74,14 +74,20 @@ public final class SectionResponse extends BroadcastInfoResponse implements Parc
}
/**
- * Gets the Version number of requested session.
+ * Gets the Version number of requested session. If it is null, value will be -1.
+ * <p>The consistency of version numbers between request and response depends on
+ * {@link BroadcastInfoRequest.RequestOption}. If the request has RequestOption value
+ * REQUEST_OPTION_AUTO_UPDATE, then the response may be set to the latest version which may be
+ * different from the version of the request. Otherwise, response with a different version from
+ * its request will be considered invalid.
*/
public int getVersion() {
return mVersion;
}
/**
- * Gets the raw data of session.
+ * Gets the raw data of session. The sessionData field represents payload data of the session
+ * after session header, which includes version and sessionId.
*/
@NonNull
public Bundle getSessionData() {
diff --git a/media/java/android/media/tv/StreamEventResponse.java b/media/java/android/media/tv/StreamEventResponse.java
index f952ce929842..28dff374d539 100644
--- a/media/java/android/media/tv/StreamEventResponse.java
+++ b/media/java/android/media/tv/StreamEventResponse.java
@@ -43,7 +43,7 @@ public final class StreamEventResponse extends BroadcastInfoResponse implements
};
private final int mEventId;
- private final long mNpt;
+ private final long mNptMillis;
private final byte[] mData;
static StreamEventResponse createFromParcelBody(Parcel in) {
@@ -51,17 +51,17 @@ public final class StreamEventResponse extends BroadcastInfoResponse implements
}
public StreamEventResponse(int requestId, int sequence, @ResponseResult int responseResult,
- int eventId, long npt, @Nullable byte[] data) {
+ int eventId, long nptMillis, @Nullable byte[] data) {
super(RESPONSE_TYPE, requestId, sequence, responseResult);
mEventId = eventId;
- mNpt = npt;
+ mNptMillis = nptMillis;
mData = data;
}
private StreamEventResponse(@NonNull Parcel source) {
super(RESPONSE_TYPE, source);
mEventId = source.readInt();
- mNpt = source.readLong();
+ mNptMillis = source.readLong();
int dataLength = source.readInt();
mData = new byte[dataLength];
source.readByteArray(mData);
@@ -76,9 +76,10 @@ public final class StreamEventResponse extends BroadcastInfoResponse implements
/**
* Returns the NPT(Normal Play Time) value when the event occurred or will occur.
+ * <p>The time unit of NPT is millisecond.
*/
- public long getNpt() {
- return mNpt;
+ public long getNptMillis() {
+ return mNptMillis;
}
/**
@@ -98,7 +99,7 @@ public final class StreamEventResponse extends BroadcastInfoResponse implements
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(mEventId);
- dest.writeLong(mNpt);
+ dest.writeLong(mNptMillis);
dest.writeInt(mData.length);
dest.writeByteArray(mData);
}
diff --git a/media/java/android/media/tv/TableRequest.java b/media/java/android/media/tv/TableRequest.java
index 37df4eaf1ed0..a1a6b516859c 100644
--- a/media/java/android/media/tv/TableRequest.java
+++ b/media/java/android/media/tv/TableRequest.java
@@ -91,7 +91,12 @@ public final class TableRequest extends BroadcastInfoRequest implements Parcelab
}
/**
- * Gets the version number of requested table.
+ * Gets the version number of requested table. If it is null, value will be -1.
+ * <p>The consistency of version numbers between request and response depends on
+ * {@link BroadcastInfoRequest.RequestOption}. If the request has RequestOption value
+ * REQUEST_OPTION_AUTO_UPDATE, then the response may be set to the latest version which may be
+ * different from the version of the request. Otherwise, response with a different version from
+ * its request will be considered invalid.
*/
public int getVersion() {
return mVersion;
diff --git a/media/java/android/media/tv/TableResponse.java b/media/java/android/media/tv/TableResponse.java
index e9f1136875f5..afc9bee5fb85 100644
--- a/media/java/android/media/tv/TableResponse.java
+++ b/media/java/android/media/tv/TableResponse.java
@@ -76,7 +76,12 @@ public final class TableResponse extends BroadcastInfoResponse implements Parcel
}
/**
- * Gets the Version number of table.
+ * Gets the version number of requested table. If it is null, value will be -1.
+ * <p>The consistency of version numbers between request and response depends on
+ * {@link BroadcastInfoRequest.RequestOption}. If the request has RequestOption value
+ * REQUEST_OPTION_AUTO_UPDATE, then the response may be set to the latest version which may be
+ * different from the version of the request. Otherwise, response with a different version from
+ * its request will be considered invalid.
*/
public int getVersion() {
return mVersion;
diff --git a/media/java/android/media/tv/TimelineResponse.java b/media/java/android/media/tv/TimelineResponse.java
index fbeb0c4bf268..7de30f579a35 100644
--- a/media/java/android/media/tv/TimelineResponse.java
+++ b/media/java/android/media/tv/TimelineResponse.java
@@ -18,6 +18,7 @@ package android.media.tv;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -79,8 +80,8 @@ public final class TimelineResponse extends BroadcastInfoResponse implements Par
* that conveys Time Values on it.
*/
@Nullable
- public String getSelector() {
- return mSelector;
+ public Uri getSelector() {
+ return Uri.parse(mSelector);
}
/**
diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl
index aaabe342d9f1..839118265732 100644
--- a/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl
+++ b/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl
@@ -23,7 +23,7 @@ import android.media.tv.TvTrackInfo;
import android.media.tv.interactive.AppLinkInfo;
import android.media.tv.interactive.ITvInteractiveAppClient;
import android.media.tv.interactive.ITvInteractiveAppManagerCallback;
-import android.media.tv.interactive.TvInteractiveAppInfo;
+import android.media.tv.interactive.TvInteractiveAppServiceInfo;
import android.net.Uri;
import android.os.Bundle;
import android.view.Surface;
@@ -33,7 +33,7 @@ import android.view.Surface;
* @hide
*/
interface ITvInteractiveAppManager {
- List<TvInteractiveAppInfo> getTvInteractiveAppServiceList(int userId);
+ List<TvInteractiveAppServiceInfo> getTvInteractiveAppServiceList(int userId);
void prepare(String tiasId, int type, int userId);
void registerAppLinkInfo(String tiasId, in AppLinkInfo info, int userId);
void unregisterAppLinkInfo(String tiasId, in AppLinkInfo info, int userId);
diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppManagerCallback.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppManagerCallback.aidl
index 23be4c64fcc4..f410c0fac488 100644
--- a/media/java/android/media/tv/interactive/ITvInteractiveAppManagerCallback.aidl
+++ b/media/java/android/media/tv/interactive/ITvInteractiveAppManagerCallback.aidl
@@ -16,7 +16,7 @@
package android.media.tv.interactive;
-import android.media.tv.interactive.TvInteractiveAppInfo;
+import android.media.tv.interactive.TvInteractiveAppServiceInfo;
/**
* Interface to receive callbacks from ITvInteractiveAppManager regardless of sessions.
@@ -26,6 +26,6 @@ interface ITvInteractiveAppManagerCallback {
void onInteractiveAppServiceAdded(in String iAppServiceId);
void onInteractiveAppServiceRemoved(in String iAppServiceId);
void onInteractiveAppServiceUpdated(in String iAppServiceId);
- void onTvInteractiveAppInfoUpdated(in TvInteractiveAppInfo tvIAppInfo);
+ void onTvInteractiveAppServiceInfoUpdated(in TvInteractiveAppServiceInfo tvIAppInfo);
void onStateChanged(in String iAppServiceId, int type, int state, int err);
} \ No newline at end of file
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
index 9eb4a6c393ab..83ff0f50f1a3 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
@@ -249,7 +249,7 @@ public final class TvInteractiveAppManager {
*
* @see #sendAppLinkCommand(String, Bundle)
* @see #ACTION_APP_LINK_COMMAND
- * @see android.media.tv.interactive.TvInteractiveAppInfo#getId()
+ * @see android.media.tv.interactive.TvInteractiveAppServiceInfo#getId()
*/
public static final String INTENT_KEY_INTERACTIVE_APP_SERVICE_ID = "interactive_app_id";
@@ -269,7 +269,7 @@ public final class TvInteractiveAppManager {
*
* @see #sendAppLinkCommand(String, Bundle)
* @see #ACTION_APP_LINK_COMMAND
- * @see android.media.tv.interactive.TvInteractiveAppInfo#getSupportedTypes()
+ * @see android.media.tv.interactive.TvInteractiveAppServiceInfo#getSupportedTypes()
* @see android.media.tv.interactive.TvInteractiveAppView#createBiInteractiveApp(Uri, Bundle)
*/
public static final String INTENT_KEY_BI_INTERACTIVE_APP_TYPE = "bi_interactive_app_type";
@@ -543,11 +543,11 @@ public final class TvInteractiveAppManager {
}
@Override
- public void onTvInteractiveAppInfoUpdated(TvInteractiveAppInfo iAppInfo) {
+ public void onTvInteractiveAppServiceInfoUpdated(TvInteractiveAppServiceInfo iAppInfo) {
// TODO: add public API updateInteractiveAppInfo()
synchronized (mLock) {
for (TvInteractiveAppCallbackRecord record : mCallbackRecords) {
- record.postTvInteractiveAppInfoUpdated(iAppInfo);
+ record.postTvInteractiveAppServiceInfoUpdated(iAppInfo);
}
}
}
@@ -611,16 +611,17 @@ public final class TvInteractiveAppManager {
* This is called when the information about an existing TV Interactive App service has been
* updated.
*
- * <p>Because the system automatically creates a <code>TvInteractiveAppInfo</code> object
- * for each TV Interactive App service based on the information collected from the
+ * <p>Because the system automatically creates a <code>TvInteractiveAppServiceInfo</code>
+ * object for each TV Interactive App service based on the information collected from the
* <code>AndroidManifest.xml</code>, this method is only called back when such information
* has changed dynamically.
*
- * @param iAppInfo The <code>TvInteractiveAppInfo</code> object that contains new
+ * @param iAppInfo The <code>TvInteractiveAppServiceInfo</code> object that contains new
* information.
* @hide
*/
- public void onTvInteractiveAppInfoUpdated(@NonNull TvInteractiveAppInfo iAppInfo) {
+ public void onTvInteractiveAppServiceInfoUpdated(
+ @NonNull TvInteractiveAppServiceInfo iAppInfo) {
}
/**
@@ -634,7 +635,7 @@ public final class TvInteractiveAppManager {
*/
public void onTvInteractiveAppServiceStateChanged(
@NonNull String iAppServiceId,
- @TvInteractiveAppInfo.InteractiveAppType int type,
+ @TvInteractiveAppServiceInfo.InteractiveAppType int type,
@ServiceState int state,
@ErrorCode int err) {
}
@@ -680,11 +681,12 @@ public final class TvInteractiveAppManager {
});
}
- public void postTvInteractiveAppInfoUpdated(final TvInteractiveAppInfo iAppInfo) {
+ public void postTvInteractiveAppServiceInfoUpdated(
+ final TvInteractiveAppServiceInfo iAppInfo) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
- mCallback.onTvInteractiveAppInfoUpdated(iAppInfo);
+ mCallback.onTvInteractiveAppServiceInfoUpdated(iAppInfo);
}
});
}
@@ -737,11 +739,11 @@ public final class TvInteractiveAppManager {
/**
* Returns the complete list of TV Interactive App service on the system.
*
- * @return List of {@link TvInteractiveAppInfo} for each TV Interactive App service that
+ * @return List of {@link TvInteractiveAppServiceInfo} for each TV Interactive App service that
* describes its meta information.
*/
@NonNull
- public List<TvInteractiveAppInfo> getTvInteractiveAppServiceList() {
+ public List<TvInteractiveAppServiceInfo> getTvInteractiveAppServiceList() {
try {
return mService.getTvInteractiveAppServiceList(mUserId);
} catch (RemoteException e) {
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
index d22fd83872e1..316fbbab6d37 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
@@ -242,7 +242,7 @@ public abstract class TvInteractiveAppService extends Service {
/**
* Prepares TV Interactive App service for the given type.
*/
- public abstract void onPrepare(@TvInteractiveAppInfo.InteractiveAppType int type);
+ public abstract void onPrepare(@TvInteractiveAppServiceInfo.InteractiveAppType int type);
/**
* Called when a request to register an Android application link info record is received.
@@ -277,7 +277,7 @@ public abstract class TvInteractiveAppService extends Service {
@Nullable
public abstract Session onCreateSession(
@NonNull String iAppServiceId,
- @TvInteractiveAppInfo.InteractiveAppType int type);
+ @TvInteractiveAppServiceInfo.InteractiveAppType int type);
/**
* Notifies the system when the state of the interactive app RTE has been changed.
@@ -289,7 +289,7 @@ public abstract class TvInteractiveAppService extends Service {
* {@link TvInteractiveAppManager#SERVICE_STATE_ERROR}.
*/
public final void notifyStateChanged(
- @TvInteractiveAppInfo.InteractiveAppType int type,
+ @TvInteractiveAppServiceInfo.InteractiveAppType int type,
@TvInteractiveAppManager.ServiceState int state,
@TvInteractiveAppManager.ErrorCode int error) {
SomeArgs args = SomeArgs.obtain();
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppInfo.aidl b/media/java/android/media/tv/interactive/TvInteractiveAppServiceInfo.aidl
index 5e1501677b3b..49600a05cb7f 100644
--- a/media/java/android/media/tv/interactive/TvInteractiveAppInfo.aidl
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppServiceInfo.aidl
@@ -16,4 +16,4 @@
package android.media.tv.interactive;
-parcelable TvInteractiveAppInfo; \ No newline at end of file
+parcelable TvInteractiveAppServiceInfo; \ No newline at end of file
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppInfo.java b/media/java/android/media/tv/interactive/TvInteractiveAppServiceInfo.java
index 6103db001b19..9c1b2425c013 100644
--- a/media/java/android/media/tv/interactive/TvInteractiveAppInfo.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppServiceInfo.java
@@ -45,9 +45,9 @@ import java.util.List;
/**
* This class is used to specify meta information of a TV interactive app.
*/
-public final class TvInteractiveAppInfo implements Parcelable {
+public final class TvInteractiveAppServiceInfo implements Parcelable {
private static final boolean DEBUG = false;
- private static final String TAG = "TvInteractiveAppInfo";
+ private static final String TAG = "TvInteractiveAppServiceInfo";
private static final String XML_START_TAG_NAME = "tv-interactive-app";
@@ -71,7 +71,7 @@ public final class TvInteractiveAppInfo implements Parcelable {
private final String mId;
private int mTypes;
- public TvInteractiveAppInfo(@NonNull Context context, @NonNull ComponentName component) {
+ public TvInteractiveAppServiceInfo(@NonNull Context context, @NonNull ComponentName component) {
if (context == null) {
throw new IllegalArgumentException("context cannot be null.");
}
@@ -94,28 +94,28 @@ public final class TvInteractiveAppInfo implements Parcelable {
mId = id;
mTypes = toTypesFlag(types);
}
- private TvInteractiveAppInfo(ResolveInfo service, String id, int types) {
+ private TvInteractiveAppServiceInfo(ResolveInfo service, String id, int types) {
mService = service;
mId = id;
mTypes = types;
}
- private TvInteractiveAppInfo(@NonNull Parcel in) {
+ private TvInteractiveAppServiceInfo(@NonNull Parcel in) {
mService = ResolveInfo.CREATOR.createFromParcel(in);
mId = in.readString();
mTypes = in.readInt();
}
- public static final @NonNull Creator<TvInteractiveAppInfo> CREATOR =
- new Creator<TvInteractiveAppInfo>() {
+ public static final @NonNull Creator<TvInteractiveAppServiceInfo> CREATOR =
+ new Creator<TvInteractiveAppServiceInfo>() {
@Override
- public TvInteractiveAppInfo createFromParcel(Parcel in) {
- return new TvInteractiveAppInfo(in);
+ public TvInteractiveAppServiceInfo createFromParcel(Parcel in) {
+ return new TvInteractiveAppServiceInfo(in);
}
@Override
- public TvInteractiveAppInfo[] newArray(int size) {
- return new TvInteractiveAppInfo[size];
+ public TvInteractiveAppServiceInfo[] newArray(int size) {
+ return new TvInteractiveAppServiceInfo[size];
}
};
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppView.java b/media/java/android/media/tv/interactive/TvInteractiveAppView.java
index 773e54f30744..212051120e77 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppView.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppView.java
@@ -148,12 +148,14 @@ public class TvInteractiveAppView extends ViewGroup {
/**
* Sets the callback to be invoked when an event is dispatched to this TvInteractiveAppView.
*
- * @param callback The callback to receive events. A value of {@code null} removes the existing
- * callback.
+ * @param callback the callback to receive events. MUST NOT be {@code null}.
+ *
+ * @see #clearCallback()
*/
public void setCallback(
@NonNull @CallbackExecutor Executor executor,
@NonNull TvInteractiveAppCallback callback) {
+ com.android.internal.util.AnnotationValidations.validate(NonNull.class, null, callback);
synchronized (mCallbackLock) {
mCallbackExecutor = executor;
mCallback = callback;
@@ -162,6 +164,8 @@ public class TvInteractiveAppView extends ViewGroup {
/**
* Clears the callback.
+ *
+ * @see #setCallback(Executor, TvInteractiveAppCallback)
*/
public void clearCallback() {
synchronized (mCallbackLock) {
@@ -389,13 +393,13 @@ public class TvInteractiveAppView extends ViewGroup {
* Prepares the interactive application.
*
* @param iAppServiceId the interactive app service ID, which can be found in
- * {@link TvInteractiveAppInfo#getId()}.
+ * {@link TvInteractiveAppServiceInfo#getId()}.
*
* @see android.media.tv.interactive.TvInteractiveAppManager#getTvInteractiveAppServiceList()
*/
public void prepareInteractiveApp(
@NonNull String iAppServiceId,
- @TvInteractiveAppInfo.InteractiveAppType int type) {
+ @TvInteractiveAppServiceInfo.InteractiveAppType int type) {
// TODO: document and handle the cases that this method is called multiple times.
if (DEBUG) {
Log.d(TAG, "prepareInteractiveApp");
diff --git a/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
index 7eaa01e262fe..01ff02dfc5b3 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
+++ b/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
@@ -26,6 +26,7 @@ import android.net.NetworkStats;
oneway interface INetworkStatsProviderCallback {
void notifyStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats);
void notifyAlertReached();
- void notifyWarningOrLimitReached();
+ void notifyWarningReached();
+ void notifyLimitReached();
void unregister();
}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/NetworkStatsProvider.java b/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/NetworkStatsProvider.java
index 23fc06927ef9..d37a53dbf1e9 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/NetworkStatsProvider.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/netstats/provider/NetworkStatsProvider.java
@@ -152,19 +152,19 @@ public abstract class NetworkStatsProvider {
try {
// Reuse the code path to notify warning reached with limit reached
// since framework handles them in the same way.
- getProviderCallbackBinderOrThrow().notifyWarningOrLimitReached();
+ getProviderCallbackBinderOrThrow().notifyWarningReached();
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
}
/**
- * Notify system that the quota set by {@link #onSetLimit} or limit set by
+ * Notify system that the limit set by {@link #onSetLimit} or limit set by
* {@link #onSetWarningAndLimit} has been reached.
*/
public void notifyLimitReached() {
try {
- getProviderCallbackBinderOrThrow().notifyWarningOrLimitReached();
+ getProviderCallbackBinderOrThrow().notifyLimitReached();
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
index 8c5207cbae4a..e3794e441a23 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
@@ -2393,10 +2393,17 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
@Override
- public void notifyWarningOrLimitReached() {
- Log.d(TAG, mTag + ": notifyWarningOrLimitReached");
+ public void notifyWarningReached() {
+ Log.d(TAG, mTag + ": notifyWarningReached");
BinderUtils.withCleanCallingIdentity(() ->
- mNetworkPolicyManager.notifyStatsProviderWarningOrLimitReached());
+ mNetworkPolicyManager.notifyStatsProviderWarningReached());
+ }
+
+ @Override
+ public void notifyLimitReached() {
+ Log.d(TAG, mTag + ": notifyLimitReached");
+ BinderUtils.withCleanCallingIdentity(() ->
+ mNetworkPolicyManager.notifyStatsProviderLimitReached());
}
@Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 3d91c5aceeed..7f300cafaa08 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -1117,7 +1117,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
final boolean isOnCall = Utils.isAudioModeOngoingCall(mContext);
if ((mIsActiveDeviceHearingAid)
|| (mIsActiveDeviceHeadset && isOnCall)
- || (mIsActiveDeviceA2dp && !isOnCall)) {
+ || (mIsActiveDeviceA2dp && !isOnCall)
+ || mIsActiveDeviceLeAudio) {
if (isTwsBatteryAvailable(leftBattery, rightBattery) && !shortSummary) {
stringRes = R.string.bluetooth_active_battery_level_untethered;
} else if (batteryLevelPercentageString != null && !shortSummary) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LeAudioProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LeAudioProfile.java
index e203cbaa3da5..19df1e9c0730 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LeAudioProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LeAudioProfile.java
@@ -246,6 +246,13 @@ public class LeAudioProfile implements LocalBluetoothProfile {
return R.drawable.ic_bt_le_audio;
}
+ public int getAudioLocation(BluetoothDevice device) {
+ if (mService == null || device == null) {
+ return BluetoothLeAudio.AUDIO_LOCATION_INVALID;
+ }
+ return mService.getAudioLocation(device);
+ }
+
@RequiresApi(Build.VERSION_CODES.S)
protected void finalize() {
if (DEBUG) {
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 4b45cc338a6a..e24b2d6c6aa9 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -314,11 +314,6 @@
<!-- To change system captions state -->
<uses-permission android:name="android.permission.SET_SYSTEM_AUDIO_CAPTION" />
- <!-- Compat framework -->
- <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
- <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
- <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
-
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
diff --git a/packages/SystemUI/res/drawable/ic_circular_unchecked.xml b/packages/SystemUI/res/drawable/ic_circular_unchecked.xml
index 9b43cf64f116..779ab816d925 100644
--- a/packages/SystemUI/res/drawable/ic_circular_unchecked.xml
+++ b/packages/SystemUI/res/drawable/ic_circular_unchecked.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
- android:fillColor="@color/media_dialog_inactive_item_main_content"
+ android:fillColor="@color/media_dialog_item_main_content"
android:pathData="M12,22q-2.075,0 -3.9,-0.788 -1.825,-0.787 -3.175,-2.137 -1.35,-1.35 -2.137,-3.175Q2,14.075 2,12t0.788,-3.9q0.787,-1.825 2.137,-3.175 1.35,-1.35 3.175,-2.137Q9.925,2 12,2t3.9,0.788q1.825,0.787 3.175,2.137 1.35,1.35 2.137,3.175Q22,9.925 22,12t-0.788,3.9q-0.787,1.825 -2.137,3.175 -1.35,1.35 -3.175,2.137Q14.075,22 12,22zM12,12zM12,20q3.325,0 5.663,-2.337Q20,15.325 20,12t-2.337,-5.662Q15.325,4 12,4T6.338,6.338Q4,8.675 4,12q0,3.325 2.338,5.663Q8.675,20 12,20z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/media_output_status_check.xml b/packages/SystemUI/res/drawable/media_output_status_check.xml
index 1b750f8959b9..5fbc42b245b8 100644
--- a/packages/SystemUI/res/drawable/media_output_status_check.xml
+++ b/packages/SystemUI/res/drawable/media_output_status_check.xml
@@ -21,6 +21,6 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
- android:fillColor="@color/media_dialog_item_status"
+ android:fillColor="@color/media_dialog_item_main_content"
android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/media_output_status_failed.xml b/packages/SystemUI/res/drawable/media_output_status_failed.xml
index 05c635833441..0599e239a9ee 100644
--- a/packages/SystemUI/res/drawable/media_output_status_failed.xml
+++ b/packages/SystemUI/res/drawable/media_output_status_failed.xml
@@ -21,6 +21,6 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
- android:fillColor="@color/media_dialog_inactive_item_main_content"
+ android:fillColor="@color/media_dialog_item_main_content"
android:pathData="M11,7h2v2h-2zM11,11h2v6h-2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
</vector>
diff --git a/packages/SystemUI/res/layout/media_output_list_item.xml b/packages/SystemUI/res/layout/media_output_list_item.xml
index eeb37c7b062d..20747fad021b 100644
--- a/packages/SystemUI/res/layout/media_output_list_item.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item.xml
@@ -83,7 +83,7 @@
android:ellipsize="end"
android:maxLines="1"
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:textColor="@color/media_dialog_inactive_item_main_content"
+ android:textColor="@color/media_dialog_item_main_content"
android:textSize="16sp"/>
<TextView
android:id="@+id/subtitle"
@@ -91,7 +91,7 @@
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
- android:textColor="@color/media_dialog_inactive_item_main_content"
+ android:textColor="@color/media_dialog_item_main_content"
android:textSize="14sp"
android:fontFamily="@*android:string/config_bodyFontFamily"
android:visibility="gone"/>
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
index ad2bc79a5c96..5aa608084510 100644
--- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
@@ -37,7 +37,5 @@
android:layout_gravity="center"
android:minWidth="@dimen/ongoing_appops_chip_min_width"
android:maxWidth="@dimen/ongoing_appops_chip_max_width"
- android:clipChildren="false"
- android:clipToPadding="false"
/>
</com.android.systemui.privacy.OngoingPrivacyChip> \ No newline at end of file
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 4b96d5d660ee..3a638b1e5098 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -67,10 +67,12 @@
<!-- media output dialog-->
<color name="media_dialog_background">@color/material_dynamic_neutral10</color>
- <color name="media_dialog_active_item_main_content">@color/material_dynamic_neutral10</color>
- <color name="media_dialog_inactive_item_main_content">@color/material_dynamic_neutral10</color>
- <color name="media_dialog_item_status">@color/material_dynamic_neutral10</color>
- <color name="media_dialog_item_background">@color/material_dynamic_secondary95</color>
+ <color name="media_dialog_item_main_content">@color/material_dynamic_primary90</color>
+ <color name="media_dialog_item_background">@color/material_dynamic_neutral_variant20</color>
+ <color name="media_dialog_connected_item_background">@color/material_dynamic_secondary20</color>
+ <color name="media_dialog_seekbar_progress">@color/material_dynamic_secondary40</color>
+ <color name="media_dialog_button_background">@color/material_dynamic_primary70</color>
+ <color name="media_dialog_solid_button_text">@color/material_dynamic_secondary20</color>
<!-- Biometric dialog colors -->
<color name="biometric_dialog_gray">#ffcccccc</color>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index c56ba7b6b1ce..02a4070415dd 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -37,6 +37,7 @@
<dimen name="controls_task_view_right_margin">8dp</dimen>
<dimen name="split_shade_header_height">42dp</dimen>
+ <dimen name="status_bar_header_height_keyguard">42dp</dimen>
<!-- Distance that the full shade transition takes in order to complete by tapping on a button
like "expand". -->
diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
index f267088ea203..bdd704936594 100644
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
@@ -24,6 +24,7 @@
<dimen name="keyguard_split_shade_top_margin">72dp</dimen>
<dimen name="split_shade_header_height">56dp</dimen>
+ <dimen name="status_bar_header_height_keyguard">56dp</dimen>
<dimen name="qs_media_session_height_expanded">184dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 1edaaadfb433..49fc8482712a 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -176,10 +176,12 @@
<!-- media output dialog-->
<color name="media_dialog_background" android:lstar="98">@color/material_dynamic_neutral90</color>
- <color name="media_dialog_active_item_main_content">@color/material_dynamic_primary10</color>
- <color name="media_dialog_inactive_item_main_content">@color/material_dynamic_primary40</color>
- <color name="media_dialog_item_status">@color/material_dynamic_primary10</color>
+ <color name="media_dialog_item_main_content">@color/material_dynamic_primary20</color>
<color name="media_dialog_item_background">@color/material_dynamic_secondary95</color>
+ <color name="media_dialog_connected_item_background">@color/material_dynamic_primary90</color>
+ <color name="media_dialog_seekbar_progress">@color/material_dynamic_secondary40</color>
+ <color name="media_dialog_button_background">@color/material_dynamic_primary40</color>
+ <color name="media_dialog_solid_button_text">@color/material_dynamic_neutral95</color>
<!-- controls -->
<color name="control_primary_text">#E6FFFFFF</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ffae6015c732..f73010e2a39a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -941,6 +941,9 @@
<!-- Three privacy items. This value must not be exceeded -->
<dimen name="ongoing_appops_chip_max_width">76dp</dimen>
<dimen name="ongoing_appops_dot_diameter">6dp</dimen>
+ <dimen name="ongoing_appops_chip_min_animation_width">10dp</dimen>
+ <dimen name="ongoing_appops_chip_animation_in_status_bar_translation_x">15dp</dimen>
+ <dimen name="ongoing_appops_chip_animation_out_status_bar_translation_x">7dp</dimen>
<!-- Total minimum padding to enforce to ensure that the dot can always show -->
<dimen name="ongoing_appops_dot_min_padding">20dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 3ae21e08005d..f5c1382b9ae9 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -486,7 +486,7 @@
<style name="MediaOutputItemInactiveTitle">
<item name="android:textSize">16sp</item>
- <item name="android:textColor">@color/media_dialog_inactive_item_main_content</item>
+ <item name="android:textColor">@color/media_dialog_item_main_content</item>
</style>
<style name="TunerSettings" parent="@android:style/Theme.DeviceDefault.Settings">
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 64c2d2e3858e..c100a0744b85 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -726,8 +726,8 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
boolean isCameraPrivacyEnabled = false;
if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE
- && mSensorPrivacyManager.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA,
- mCurrentDialogArgs.argi1 /* userId */)) {
+ && mSensorPrivacyManager.isSensorPrivacyEnabled(
+ SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE, SensorPrivacyManager.Sensors.CAMERA)) {
isCameraPrivacyEnabled = true;
}
// TODO(b/141025588): Create separate methods for handling hard and soft errors.
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 61cfe925f640..2db3de173257 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -145,7 +145,7 @@ public class Flags {
/***************************************/
// 900 - media
public static final BooleanFlag MEDIA_TAP_TO_TRANSFER = new BooleanFlag(900, true);
- public static final BooleanFlag MEDIA_SESSION_ACTIONS = new BooleanFlag(901, false);
+ public static final BooleanFlag MEDIA_SESSION_ACTIONS = new BooleanFlag(901, true);
public static final BooleanFlag MEDIA_SESSION_LAYOUT = new BooleanFlag(902, true);
public static final BooleanFlag MEDIA_NEARBY_DEVICES = new BooleanFlag(903, true);
public static final BooleanFlag MEDIA_MUTE_AWAIT = new BooleanFlag(904, true);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 736e2e0e4035..acad30b4276f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -20,6 +20,7 @@ import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN;
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_TRANSITION_FROM_AOD;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_UNLOCK_ANIMATION;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
@@ -123,11 +124,11 @@ import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
@@ -1557,6 +1558,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
public void setOccluded(boolean isOccluded, boolean animate) {
Trace.beginSection("KeyguardViewMediator#setOccluded");
if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded);
+ mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD);
mHandler.removeMessages(SET_OCCLUDED);
Message msg = mHandler.obtainMessage(SET_OCCLUDED, isOccluded ? 1 : 0, animate ? 1 : 0);
mHandler.sendMessage(msg);
@@ -2805,6 +2807,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) {
Trace.beginSection("KeyguardViewMediator#startKeyguardExitAnimation");
+ mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD);
Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM,
new StartKeyguardExitAnimParams(transit, startTime, fadeoutDuration, apps,
wallpapers, nonApps, finishedCallback));
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index ffdd5376b12e..510d15bd7b73 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -137,6 +137,7 @@ public class MediaControlPanel {
private MediaCarouselController mMediaCarouselController;
private final MediaOutputDialogFactory mMediaOutputDialogFactory;
private final FalsingManager mFalsingManager;
+ private final MediaFlags mMediaFlags;
// Used for swipe-to-dismiss logging.
protected boolean mIsImpressed = false;
@@ -155,7 +156,7 @@ public class MediaControlPanel {
Lazy<MediaDataManager> lazyMediaDataManager,
MediaOutputDialogFactory mediaOutputDialogFactory,
MediaCarouselController mediaCarouselController,
- FalsingManager falsingManager, SystemClock systemClock) {
+ FalsingManager falsingManager, MediaFlags mediaFlags, SystemClock systemClock) {
mContext = context;
mBackgroundExecutor = backgroundExecutor;
mActivityStarter = activityStarter;
@@ -166,6 +167,7 @@ public class MediaControlPanel {
mMediaOutputDialogFactory = mediaOutputDialogFactory;
mMediaCarouselController = mediaCarouselController;
mFalsingManager = falsingManager;
+ mMediaFlags = mediaFlags;
mSystemClock = systemClock;
loadDimens();
@@ -504,8 +506,9 @@ public class MediaControlPanel {
List<MediaAction> actionIcons = data.getActions();
List<Integer> actionsWhenCollapsed = data.getActionsToShowInCompact();
- // If we got session actions, use those instead
- if (data.getSemanticActions() != null) {
+ // If the session actions flag is enabled, but we're still using the regular layout, use
+ // the session actions anyways
+ if (mMediaFlags.areMediaSessionActionsEnabled() && data.getSemanticActions() != null) {
MediaButton semanticActions = data.getSemanticActions();
actionIcons = new ArrayList<MediaAction>();
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index ea92abd27e97..9e14fe91f21d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -610,8 +610,7 @@ class MediaDataManager(
var actionIcons: List<MediaAction> = emptyList()
var actionsToShowCollapsed: List<Int> = emptyList()
var semanticActions: MediaButton? = null
- if (mediaFlags.areMediaSessionActionsEnabled(sbn.packageName, sbn.user.identifier) &&
- mediaController.playbackState != null) {
+ if (mediaFlags.areMediaSessionActionsEnabled() && mediaController.playbackState != null) {
semanticActions = createActionsFromState(sbn.packageName, mediaController)
} else {
val actions = createActionsFromNotification(sbn)
@@ -727,7 +726,7 @@ class MediaDataManager(
}
}
- // Finally, assign the remaining button slots: play/pause A B C D
+ // Finally, assign the remaining button slots: C A play/pause B D
// A = previous, else custom action (if not reserved)
// B = next, else custom action (if not reserved)
// C and D are always custom actions
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt
index f5200f9c8c93..dd35a9a81399 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt
@@ -16,7 +16,6 @@
package com.android.systemui.media
-import android.app.StatusBarManager
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
@@ -27,17 +26,16 @@ class MediaFlags @Inject constructor(private val featureFlags: FeatureFlags) {
/**
* Check whether media control actions should be based on PlaybackState instead of notification
*/
- fun areMediaSessionActionsEnabled(packageName: String, userId: Int): Boolean {
- val enabled = StatusBarManager.useMediaSessionActionsForApp(packageName, userId)
- // Allow global override with flag
- return enabled || featureFlags.isEnabled(Flags.MEDIA_SESSION_ACTIONS)
+ fun areMediaSessionActionsEnabled(): Boolean {
+ return featureFlags.isEnabled(Flags.MEDIA_SESSION_ACTIONS)
}
/**
* Check whether media controls should use the new session-based layout
*/
fun useMediaSessionLayout(): Boolean {
- return featureFlags.isEnabled(Flags.MEDIA_SESSION_LAYOUT)
+ return featureFlags.isEnabled(Flags.MEDIA_SESSION_ACTIONS) &&
+ featureFlags.isEnabled(Flags.MEDIA_SESSION_LAYOUT)
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index 0b23ad50a726..a6464829623f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -119,7 +119,9 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mCheckBox.setVisibility(View.GONE);
mStatusIcon.setVisibility(View.GONE);
mContainerLayout.setOnClickListener(null);
- mTitleText.setTextColor(mController.getColorInactiveItem());
+ mTitleText.setTextColor(mController.getColorItemContent());
+ mSubTitleText.setTextColor(mController.getColorItemContent());
+ mTwoLineTitleText.setTextColor(mController.getColorItemContent());
mSeekBar.getProgressDrawable().setColorFilter(
new PorterDuffColorFilter(mController.getColorSeekbarProgress(),
PorterDuff.Mode.SRC_IN));
@@ -140,7 +142,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
&& !mController.hasAdjustVolumeUserRestriction()) {
mProgressBar.getIndeterminateDrawable().setColorFilter(
new PorterDuffColorFilter(
- mController.getColorInactiveItem(),
+ mController.getColorItemContent(),
PorterDuff.Mode.SRC_IN));
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
false /* showSeekBar*/,
@@ -155,7 +157,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mTitleIcon.setAlpha(DEVICE_CONNECTED_ALPHA);
mStatusIcon.setImageDrawable(
mContext.getDrawable(R.drawable.media_output_status_failed));
- mStatusIcon.setColorFilter(mController.getColorInactiveItem());
+ mStatusIcon.setColorFilter(mController.getColorItemContent());
setTwoLineLayout(device, false /* bFocused */,
false /* showSeekBar */, false /* showProgressBar */,
true /* showSubtitle */, true /* showStatus */);
@@ -163,7 +165,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
} else if (mController.getSelectedMediaDevice().size() > 1
&& isDeviceIncluded(mController.getSelectedMediaDevice(), device)) {
- mTitleText.setTextColor(mController.getColorActiveItem());
+ mTitleText.setTextColor(mController.getColorItemContent());
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
true /* showSeekBar */,
false /* showProgressBar */, false /* showStatus */);
@@ -173,13 +175,13 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
onCheckBoxClicked(false, device);
});
- setCheckBoxColor(mCheckBox, mController.getColorActiveItem());
+ setCheckBoxColor(mCheckBox, mController.getColorItemContent());
initSeekbar(device);
} else if (!mController.hasAdjustVolumeUserRestriction() && currentlyConnected) {
mStatusIcon.setImageDrawable(
mContext.getDrawable(R.drawable.media_output_status_check));
- mStatusIcon.setColorFilter(mController.getColorActiveItem());
- mTitleText.setTextColor(mController.getColorActiveItem());
+ mStatusIcon.setColorFilter(mController.getColorItemContent());
+ mTitleText.setTextColor(mController.getColorItemContent());
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
true /* showSeekBar */,
false /* showProgressBar */, true /* showStatus */);
@@ -192,7 +194,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
onCheckBoxClicked(true, device);
});
- setCheckBoxColor(mCheckBox, mController.getColorInactiveItem());
+ setCheckBoxColor(mCheckBox, mController.getColorItemContent());
setSingleLineLayout(getItemTitle(device), false /* bFocused */,
false /* showSeekBar */,
false /* showProgressBar */, false /* showStatus */);
@@ -214,7 +216,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
@Override
void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) {
if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) {
- mTitleText.setTextColor(mController.getColorInactiveItem());
+ mTitleText.setTextColor(mController.getColorItemContent());
mCheckBox.setVisibility(View.GONE);
setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new),
false /* bFocused */);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index 62d5c8e51005..df0c14b25c26 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -170,14 +170,16 @@ public abstract class MediaOutputBaseAdapter extends
void setSingleLineLayout(CharSequence title, boolean bFocused, boolean showSeekBar,
boolean showProgressBar, boolean showStatus) {
mTwoLineLayout.setVisibility(View.GONE);
+ boolean isActive = showSeekBar || showProgressBar;
final Drawable backgroundDrawable =
- showSeekBar || showProgressBar
+ isActive
? mContext.getDrawable(R.drawable.media_output_item_background_active)
.mutate() : mContext.getDrawable(
R.drawable.media_output_item_background)
.mutate();
backgroundDrawable.setColorFilter(new PorterDuffColorFilter(
- mController.getColorItemBackground(),
+ isActive ? mController.getColorConnectedItemBackground()
+ : mController.getColorItemBackground(),
PorterDuff.Mode.SRC_IN));
mItemLayout.setBackground(backgroundDrawable);
mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE);
@@ -366,7 +368,7 @@ public abstract class MediaOutputBaseAdapter extends
.mutate();
drawable.setColorFilter(
new PorterDuffColorFilter(Utils.getColorStateListDefaultColor(mContext,
- R.color.media_dialog_active_item_main_content),
+ R.color.media_dialog_item_main_content),
PorterDuff.Mode.SRC_IN));
return drawable;
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index a8141c0e2fec..dcb1c7c4637c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -216,6 +216,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
PorterDuff.Mode.SRC_IN);
mDoneButton.getBackground().setColorFilter(buttonColorFilter);
mStopButton.getBackground().setColorFilter(buttonColorFilter);
+ mDoneButton.setTextColor(mAdapter.getController().getColorPositiveButtonText());
}
mHeaderIcon.setVisibility(View.VISIBLE);
mHeaderIcon.setImageIcon(icon);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 0b6c68d17a4c..ea7f7f2bb646 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -110,11 +110,12 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
private MediaOutputMetricLogger mMetricLogger;
- private int mColorActiveItem;
- private int mColorInactiveItem;
+ private int mColorItemContent;
private int mColorSeekbarProgress;
private int mColorButtonBackground;
private int mColorItemBackground;
+ private int mColorConnectedItemBackground;
+ private int mColorPositiveButtonText;
@Inject
public MediaOutputController(@NonNull Context context, String packageName,
@@ -133,16 +134,18 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
mDialogLaunchAnimator = dialogLaunchAnimator;
mNearbyMediaDevicesManager = nearbyMediaDevicesManagerOptional.orElse(null);
- mColorActiveItem = Utils.getColorStateListDefaultColor(mContext,
- R.color.media_dialog_active_item_main_content);
- mColorInactiveItem = Utils.getColorStateListDefaultColor(mContext,
- R.color.media_dialog_inactive_item_main_content);
+ mColorItemContent = Utils.getColorStateListDefaultColor(mContext,
+ R.color.media_dialog_item_main_content);
mColorSeekbarProgress = Utils.getColorStateListDefaultColor(mContext,
- android.R.color.system_accent1_200);
+ R.color.media_dialog_seekbar_progress);
mColorButtonBackground = Utils.getColorStateListDefaultColor(mContext,
- R.color.media_dialog_item_background);
+ R.color.media_dialog_button_background);
mColorItemBackground = Utils.getColorStateListDefaultColor(mContext,
- android.R.color.system_accent2_50);
+ R.color.media_dialog_item_background);
+ mColorConnectedItemBackground = Utils.getColorStateListDefaultColor(mContext,
+ R.color.media_dialog_connected_item_background);
+ mColorPositiveButtonText = Utils.getColorStateListDefaultColor(mContext,
+ R.color.media_dialog_solid_button_text);
}
void start(@NonNull Callback cb) {
@@ -322,8 +325,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
}
void setColorFilter(Drawable drawable, boolean isActive) {
- drawable.setColorFilter(new PorterDuffColorFilter(isActive
- ? mColorActiveItem : mColorInactiveItem,
+ drawable.setColorFilter(new PorterDuffColorFilter(mColorItemContent,
PorterDuff.Mode.SRC_IN));
}
@@ -358,26 +360,32 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
ColorScheme mCurrentColorScheme = new ColorScheme(wallpaperColors,
isDarkTheme);
if (isDarkTheme) {
- mColorActiveItem = mCurrentColorScheme.getNeutral1().get(10);
- mColorInactiveItem = mCurrentColorScheme.getNeutral1().get(10);
- mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(2);
- mColorButtonBackground = mCurrentColorScheme.getAccent1().get(2);
- mColorItemBackground = mCurrentColorScheme.getAccent2().get(0);
+ mColorItemContent = mCurrentColorScheme.getAccent1().get(2); // A1-100
+ mColorSeekbarProgress = mCurrentColorScheme.getAccent2().get(7); // A2-600
+ mColorButtonBackground = mCurrentColorScheme.getAccent1().get(4); // A1-300
+ mColorItemBackground = mCurrentColorScheme.getNeutral2().get(9); // N2-800
+ mColorConnectedItemBackground = mCurrentColorScheme.getAccent2().get(9); // A2-800
+ mColorPositiveButtonText = mCurrentColorScheme.getAccent2().get(9); // A2-800
} else {
- mColorActiveItem = mCurrentColorScheme.getNeutral1().get(10);
- mColorInactiveItem = mCurrentColorScheme.getAccent1().get(7);
- mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(3);
- mColorButtonBackground = mCurrentColorScheme.getAccent1().get(3);
- mColorItemBackground = mCurrentColorScheme.getAccent2().get(0);
+ mColorItemContent = mCurrentColorScheme.getAccent1().get(9); // A1-800
+ mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(4); // A1-300
+ mColorButtonBackground = mCurrentColorScheme.getAccent1().get(7); // A1-600
+ mColorItemBackground = mCurrentColorScheme.getAccent2().get(1); // A2-50
+ mColorConnectedItemBackground = mCurrentColorScheme.getAccent1().get(2); // A1-100
+ mColorPositiveButtonText = mCurrentColorScheme.getNeutral1().get(1); // N1-50
}
}
- public int getColorActiveItem() {
- return mColorActiveItem;
+ public int getColorConnectedItemBackground() {
+ return mColorConnectedItemBackground;
+ }
+
+ public int getColorPositiveButtonText() {
+ return mColorPositiveButtonText;
}
- public int getColorInactiveItem() {
- return mColorInactiveItem;
+ public int getColorItemContent() {
+ return mColorItemContent;
}
public int getColorSeekbarProgress() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
index 71cacac7f4df..3d5b3a3f70df 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
@@ -32,6 +32,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import com.android.internal.widget.CachingIconView
+import com.android.settingslib.Utils
import com.android.systemui.R
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.statusbar.gesture.TapGestureDetector
@@ -150,40 +151,36 @@ abstract class MediaTttChipControllerCommon<T : ChipInfoCommon>(
appNameOverride: CharSequence? = null,
) {
val appIconView = currentChipView.requireViewById<CachingIconView>(R.id.app_icon)
- appIconView.contentDescription = appNameOverride ?: getAppName(appPackageName)
-
- val appIcon = appIconDrawableOverride ?: getAppIcon(appPackageName)
- val visibility = if (appIcon != null) {
- View.VISIBLE
- } else {
- View.GONE
- }
- appIconView.setImageDrawable(appIcon)
- appIconView.visibility = visibility
- }
-
- /** Returns the icon of the app playing the media or null if we can't find it. */
- private fun getAppIcon(appPackageName: String?): Drawable? {
- appPackageName ?: return null
- return try {
- context.packageManager.getApplicationIcon(appPackageName)
- } catch (e: PackageManager.NameNotFoundException) {
- Log.w(TAG, "Cannot find icon for package $appPackageName", e)
- null
- }
+ val appInfo = getAppInfo(appPackageName)
+ appIconView.contentDescription = appNameOverride ?: appInfo.appName
+ appIconView.setImageDrawable(appIconDrawableOverride ?: appInfo.appIcon)
}
- /** Returns the name of the app playing the media or null if we can't find it. */
- private fun getAppName(appPackageName: String?): String? {
- appPackageName ?: return null
- return try {
- context.packageManager.getApplicationInfo(
- appPackageName, PackageManager.ApplicationInfoFlags.of(0)
- ).loadLabel(context.packageManager).toString()
- } catch (e: PackageManager.NameNotFoundException) {
- Log.w(TAG, "Cannot find name for package $appPackageName", e)
- null
+ /**
+ * Returns the app name and icon of the app playing media, or a default name and icon if we
+ * can't find the app name/icon.
+ */
+ private fun getAppInfo(appPackageName: String?): AppInfo {
+ if (appPackageName != null) {
+ try {
+ return AppInfo(
+ appName = context.packageManager.getApplicationInfo(
+ appPackageName, PackageManager.ApplicationInfoFlags.of(0)
+ ).loadLabel(context.packageManager).toString(),
+ appIcon = context.packageManager.getApplicationIcon(appPackageName)
+ )
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.w(TAG, "Cannot find package $appPackageName", e)
+ }
}
+ return AppInfo(
+ appName = context.getString(R.string.media_output_dialog_unknown_launch_app_name),
+ appIcon = context.resources.getDrawable(R.drawable.ic_cast).apply {
+ this.setTint(
+ Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
+ )
+ }
+ )
}
private fun onScreenTapped(e: MotionEvent) {
@@ -205,3 +202,8 @@ object MediaTttRemovalReason {
const val REASON_TIMEOUT = "TIMEOUT"
const val REASON_SCREEN_TAP = "SCREEN_TAP"
}
+
+private data class AppInfo(
+ val appName: String,
+ val appIcon: Drawable
+)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 3dd717d2f377..eaa66bbc15ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -226,10 +226,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
? MathUtils.lerp(shortestWidth, getWidth(), fractionToShade)
: getWidth();
ActivatableNotificationView anv = (ActivatableNotificationView) this;
- NotificationBackgroundView bg = anv.getBackgroundNormal();
- if (bg != null) {
- anv.getBackgroundNormal().setActualWidth((int) actualWidth);
- }
+ anv.setBackgroundWidth((int) actualWidth);
if (mShelfIcons != null) {
mShelfIcons.setActualLayoutWidth((int) actualWidth);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
index 465ab93132f9..3013ad0070a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
@@ -188,7 +188,7 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver,
setContentDescription(state.contentDescription);
int newVisibility = state.visible && !mForceHidden ? View.VISIBLE : View.GONE;
- if (newVisibility != mMobileGroup.getVisibility()) {
+ if (newVisibility != mMobileGroup.getVisibility() && STATE_ICON == mVisibleState) {
mMobileGroup.setVisibility(newVisibility);
needsLayout = true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
index 9795dcf1fcd8..b74140da99d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
@@ -16,9 +16,12 @@
package com.android.systemui.statusbar.events
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.content.Context
-import android.graphics.Point
+import android.graphics.Rect
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
@@ -30,6 +33,7 @@ import com.android.systemui.R
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
import com.android.systemui.statusbar.window.StatusBarWindowController
import javax.inject.Inject
+import kotlin.math.roundToInt
/**
* Controls the view for system event animations.
@@ -38,7 +42,7 @@ class SystemEventChipAnimationController @Inject constructor(
private val context: Context,
private val statusBarWindowController: StatusBarWindowController,
private val contentInsetsProvider: StatusBarContentInsetsProvider
-) : SystemStatusChipAnimationCallback {
+) : SystemStatusAnimationCallback {
private lateinit var animationWindowView: FrameLayout
@@ -49,90 +53,169 @@ class SystemEventChipAnimationController @Inject constructor(
private var chipRight = 0
private var chipLeft = 0
private var chipWidth = 0
- private var dotCenter = Point(0, 0)
+ private var chipMinWidth = context.resources.getDimensionPixelSize(
+ R.dimen.ongoing_appops_chip_min_animation_width)
private var dotSize = context.resources.getDimensionPixelSize(
R.dimen.ongoing_appops_dot_diameter)
- // If the chip animates away to a persistent dot, then we modify the CHIP_OUT animation
- private var isAnimatingToDot = false
+ // Use during animation so that multiple animators can update the drawing rect
+ private var animRect = Rect()
// TODO: move to dagger
private var initialized = false
- override fun onChipAnimationStart(
- viewCreator: ViewCreator,
- @SystemAnimationState state: Int
- ) {
- if (!initialized) init()
-
- if (state == ANIMATING_IN) {
- animationDirection = if (animationWindowView.isLayoutRtl) RIGHT else LEFT
-
- // Initialize the animated view
- val insets = contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()
- currentAnimatedView = viewCreator(context).also {
- animationWindowView.addView(
- it.view,
- layoutParamsDefault(
- if (animationWindowView.isLayoutRtl) insets.first
- else insets.second))
- it.view.alpha = 0f
- // For some reason, the window view's measured width is always 0 here, so use the
- // parent (status bar)
- it.view.measure(
- View.MeasureSpec.makeMeasureSpec(
- (animationWindowView.parent as View).width, AT_MOST),
- View.MeasureSpec.makeMeasureSpec(animationWindowView.height, AT_MOST))
- chipWidth = it.chipWidth
- }
+ /**
+ * Give the chip controller a chance to inflate and configure the chip view before we start
+ * animating
+ */
+ fun prepareChipAnimation(viewCreator: ViewCreator) {
+ if (!initialized) {
+ init()
+ }
+ animationDirection = if (animationWindowView.isLayoutRtl) RIGHT else LEFT
- // decide which direction we're animating from, and then set some screen coordinates
- val contentRect = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation()
- when (animationDirection) {
- LEFT -> {
- chipRight = contentRect.right
- chipLeft = contentRect.right - chipWidth
- }
- else /* RIGHT */ -> {
- chipLeft = contentRect.left
- chipRight = contentRect.left + chipWidth
- }
- }
+ // Initialize the animated view
+ val insets = contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()
+ currentAnimatedView = viewCreator(context).also {
+ animationWindowView.addView(
+ it.view,
+ layoutParamsDefault(
+ if (animationWindowView.isLayoutRtl) insets.first
+ else insets.second))
+ it.view.alpha = 0f
+ // For some reason, the window view's measured width is always 0 here, so use the
+ // parent (status bar)
+ it.view.measure(
+ View.MeasureSpec.makeMeasureSpec(
+ (animationWindowView.parent as View).width, AT_MOST),
+ View.MeasureSpec.makeMeasureSpec(animationWindowView.height, AT_MOST))
+ chipWidth = it.chipWidth
+ }
- currentAnimatedView?.apply {
- updateAnimatedViewBoundsForAmount(0.1f, this)
+ // decide which direction we're animating from, and then set some screen coordinates
+ val contentRect = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation()
+ when (animationDirection) {
+ LEFT -> {
+ chipRight = contentRect.right
+ chipLeft = contentRect.right - chipWidth
}
- } else {
- // We are animating away
- currentAnimatedView!!.view.apply {
- alpha = 1f
+ else /* RIGHT */ -> {
+ chipLeft = contentRect.left
+ chipRight = contentRect.left + chipWidth
}
}
}
- override fun onChipAnimationEnd(@SystemAnimationState state: Int) {
- if (state == ANIMATING_IN) {
- // Finished animating in
- currentAnimatedView?.apply {
- updateAnimatedViewBoundsForAmount(1f, this)
+ override fun onSystemEventAnimationBegin(): Animator {
+ initializeAnimRect()
+
+ val alphaIn = ValueAnimator.ofFloat(0f, 1f).apply {
+ startDelay = 117
+ duration = 83
+ interpolator = null
+ addUpdateListener { currentAnimatedView?.view?.alpha = animatedValue as Float }
+ }
+ val moveIn = ValueAnimator.ofInt(chipMinWidth, chipWidth).apply {
+ startDelay = 117
+ duration = 383
+ interpolator = STATUS_BAR_X_MOVE_IN
+ addUpdateListener {
+ updateAnimatedViewBoundsWidth(animatedValue as Int)
}
+ }
+ val animSet = AnimatorSet()
+ animSet.playTogether(alphaIn, moveIn)
+ return animSet
+ }
+
+ override fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator {
+ initializeAnimRect()
+ val finish = if (hasPersistentDot) {
+ createMoveOutAnimationForDot()
} else {
- // Finished animating away
- currentAnimatedView!!.view.apply {
- visibility = View.INVISIBLE
+ createMoveOutAnimationDefault()
+ }
+
+ finish.addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ animationWindowView.removeView(currentAnimatedView!!.view)
+ }
+ })
+
+ return finish
+ }
+
+ private fun createMoveOutAnimationForDot(): Animator {
+ val width1 = ValueAnimator.ofInt(chipWidth, chipMinWidth).apply {
+ duration = 150
+ interpolator = STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_1
+ addUpdateListener {
+ updateAnimatedViewBoundsWidth(it.animatedValue as Int)
+ }
+ }
+
+ val width2 = ValueAnimator.ofInt(chipMinWidth, dotSize).apply {
+ startDelay = 150
+ duration = 333
+ interpolator = STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_2
+ addUpdateListener {
+ updateAnimatedViewBoundsWidth(it.animatedValue as Int)
}
- animationWindowView.removeView(currentAnimatedView!!.view)
}
+
+ val keyFrame1Height = dotSize * 2
+ val v = currentAnimatedView!!.view
+ val chipVerticalCenter = v.top + v.measuredHeight / 2
+ val height1 = ValueAnimator.ofInt(
+ currentAnimatedView!!.view.measuredHeight, keyFrame1Height).apply {
+ startDelay = 133
+ duration = 100
+ interpolator = STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_1
+ addUpdateListener {
+ updateAnimatedViewBoundsHeight(it.animatedValue as Int, chipVerticalCenter)
+ }
+ }
+
+ val height2 = ValueAnimator.ofInt(keyFrame1Height, dotSize).apply {
+ startDelay = 233
+ duration = 250
+ interpolator = STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_2
+ addUpdateListener {
+ updateAnimatedViewBoundsHeight(it.animatedValue as Int, chipVerticalCenter)
+ }
+ }
+
+ // Move the chip view to overlap exactly with the privacy dot. The chip displays by default
+ // exactly adjacent to the dot, so we can just move over by the diameter of the dot itself
+ val moveOut = ValueAnimator.ofInt(0, dotSize).apply {
+ startDelay = 50
+ duration = 183
+ interpolator = STATUS_CHIP_MOVE_TO_DOT
+ addUpdateListener {
+ // If RTL, we can just invert the move
+ val amt = if (animationDirection == LEFT) {
+ animatedValue as Int
+ } else {
+ -(animatedValue as Int)
+ }
+ updateAnimatedBoundsX(amt)
+ }
+ }
+
+ val animSet = AnimatorSet()
+ animSet.playTogether(width1, width2, height1, height2, moveOut)
+ return animSet
}
- override fun onChipAnimationUpdate(
- animator: ValueAnimator,
- @SystemAnimationState state: Int
- ) {
- currentAnimatedView?.apply {
- val amt = (animator.animatedValue as Float).amt()
- view.alpha = (animator.animatedValue as Float)
- updateAnimatedViewBoundsForAmount(amt, this)
+ private fun createMoveOutAnimationDefault(): Animator {
+ val moveOut = ValueAnimator.ofInt(chipWidth, chipMinWidth).apply {
+ duration = 383
+ addUpdateListener {
+ currentAnimatedView?.apply {
+ updateAnimatedViewBoundsWidth(it.animatedValue as Int)
+ }
+ }
}
+ return moveOut
}
private fun init() {
@@ -144,7 +227,6 @@ class SystemEventChipAnimationController @Inject constructor(
statusBarWindowController.addViewToWindow(animationWindowView, lp)
animationWindowView.clipToPadding = false
animationWindowView.clipChildren = false
- animationWindowView.measureAllChildren = true
}
private fun layoutParamsDefault(marginEnd: Int): FrameLayout.LayoutParams =
@@ -153,29 +235,55 @@ class SystemEventChipAnimationController @Inject constructor(
it.marginEnd = marginEnd
}
- private fun updateAnimatedViewBoundsForAmount(amt: Float, chip: BackgroundAnimatableView) {
+ private fun initializeAnimRect() = animRect.set(
+ chipLeft,
+ currentAnimatedView!!.view.top,
+ chipRight,
+ currentAnimatedView!!.view.bottom)
+
+ /**
+ * To be called during an animation, sets the width and updates the current animated chip view
+ */
+ private fun updateAnimatedViewBoundsWidth(width: Int) {
when (animationDirection) {
LEFT -> {
- chip.setBoundsForAnimation(
- (chipRight - (chipWidth * amt)).toInt(),
- chip.view.top,
- chipRight,
- chip.view.bottom)
- }
- else /* RIGHT */ -> {
- chip.setBoundsForAnimation(
- chipLeft,
- chip.view.top,
- (chipLeft + (chipWidth * amt)).toInt(),
- chip.view.bottom)
+ animRect.set((chipRight - width), animRect.top, chipRight, animRect.bottom)
+ } else /* RIGHT */ -> {
+ animRect.set(chipLeft, animRect.top, (chipLeft + width), animRect.bottom)
}
}
+
+ updateCurrentAnimatedView()
}
- private fun start() = if (animationWindowView.isLayoutRtl) right() else left()
- private fun right() = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation().right
- private fun left() = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation().left
- private fun Float.amt() = 0.01f.coerceAtLeast(this)
+ /**
+ * To be called during an animation, updates the animation rect and sends the update to the chip
+ */
+ private fun updateAnimatedViewBoundsHeight(height: Int, verticalCenter: Int) {
+ animRect.set(
+ animRect.left,
+ verticalCenter - (height.toFloat() / 2).roundToInt(),
+ animRect.right,
+ verticalCenter + (height.toFloat() / 2).roundToInt())
+
+ updateCurrentAnimatedView()
+ }
+
+ /**
+ * To be called during an animation, updates the animation rect offset and updates the chip
+ */
+ private fun updateAnimatedBoundsX(translation: Int) {
+ currentAnimatedView?.view?.translationX = translation.toFloat()
+ }
+
+ /**
+ * To be called during an animation. Sets the chip rect to animRect
+ */
+ private fun updateCurrentAnimatedView() {
+ currentAnimatedView?.setBoundsForAnimation(
+ animRect.left, animRect.top, animRect.right, animRect.bottom
+ )
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
index 947f3eb2ee12..36233e4e3eab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -19,14 +19,12 @@ package com.android.systemui.statusbar.events
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
-import android.animation.ValueAnimator
import android.annotation.IntDef
import android.os.Process
import android.provider.DeviceConfig
import android.util.Log
+import android.view.animation.PathInterpolator
import com.android.systemui.Dumpable
-import com.android.systemui.animation.Interpolators.STANDARD_ACCELERATE
-import com.android.systemui.animation.Interpolators.STANDARD_DECELERATE
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
@@ -38,6 +36,7 @@ import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.time.SystemClock
import java.io.FileDescriptor
import java.io.PrintWriter
+import java.lang.IllegalStateException
import javax.inject.Inject
@@ -116,7 +115,10 @@ class SystemStatusAnimationScheduler @Inject constructor(
scheduledEvent?.updateFromEvent(event)
if (event.forceVisible) {
hasPersistentDot = true
- notifyTransitionToPersistentDot()
+ // If we missed the chance to show the persistent dot, do it now
+ if (animationState == IDLE) {
+ notifyTransitionToPersistentDot()
+ }
}
} else {
if (DEBUG) {
@@ -162,68 +164,90 @@ class SystemStatusAnimationScheduler @Inject constructor(
return
}
- // Schedule the animation to start after a debounce period
- cancelExecutionRunnable = executor.executeDelayed({
- cancelExecutionRunnable = null
- animationState = ANIMATING_IN
- statusBarWindowController.setForceStatusBarVisible(true)
-
- val entranceAnimator = ValueAnimator.ofFloat(1f, 0f)
- entranceAnimator.duration = ENTRANCE_ANIM_LENGTH
- entranceAnimator.addListener(systemAnimatorAdapter)
- entranceAnimator.addUpdateListener(systemUpdateListener)
- entranceAnimator.interpolator = STANDARD_ACCELERATE
-
- val chipAnimator = ValueAnimator.ofFloat(0f, 1f)
- chipAnimator.duration = CHIP_ANIM_LENGTH
- chipAnimator.addListener(
- ChipAnimatorAdapter(RUNNING_CHIP_ANIM, scheduledEvent!!.viewCreator))
- chipAnimator.addUpdateListener(chipUpdateListener)
- chipAnimator.interpolator = STANDARD_DECELERATE
-
- val aSet2 = AnimatorSet()
- aSet2.playSequentially(entranceAnimator, chipAnimator)
- aSet2.start()
-
- executor.executeDelayed({
- animationState = ANIMATING_OUT
-
- val systemAnimator = ValueAnimator.ofFloat(0f, 1f)
- systemAnimator.duration = ENTRANCE_ANIM_LENGTH
- systemAnimator.addListener(systemAnimatorAdapter)
- systemAnimator.addUpdateListener(systemUpdateListener)
- systemAnimator.interpolator = STANDARD_DECELERATE
- systemAnimator.addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator?) {
- statusBarWindowController.setForceStatusBarVisible(false)
+ chipAnimationController.prepareChipAnimation(scheduledEvent!!.viewCreator)
+ animationState = ANIMATION_QUEUED
+ executor.executeDelayed({
+ runChipAnimation()
+ }, DEBOUNCE_DELAY)
+ }
+
+ /**
+ * 1. Define a total budget for the chip animation (1500ms)
+ * 2. Send out callbacks to listeners so that they can generate animations locally
+ * 3. Update the scheduler state so that clients know where we are
+ * 4. Maybe: provide scaffolding such as: dot location, margins, etc
+ * 5. Maybe: define a maximum animation length and enforce it. Probably only doable if we
+ * collect all of the animators and run them together.
+ */
+ private fun runChipAnimation() {
+ statusBarWindowController.setForceStatusBarVisible(true)
+ animationState = ANIMATING_IN
+
+ val animSet = collectStartAnimations()
+ if (animSet.totalDuration > 500) {
+ throw IllegalStateException("System animation total length exceeds budget. " +
+ "Expected: 500, actual: ${animSet.totalDuration}")
+ }
+ animSet.addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ animationState = RUNNING_CHIP_ANIM
+ }
+ })
+ animSet.start()
+
+ executor.executeDelayed({
+ val animSet2 = collectFinishAnimations()
+ animationState = ANIMATING_OUT
+ animSet2.addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ animationState = if (hasPersistentDot) {
+ SHOWING_PERSISTENT_DOT
+ } else {
+ IDLE
}
- })
-
- val chipAnimator = ValueAnimator.ofFloat(1f, 0f)
- chipAnimator.duration = CHIP_ANIM_LENGTH
- val endState = if (hasPersistentDot) {
- SHOWING_PERSISTENT_DOT
- } else {
- IDLE
+
+ statusBarWindowController.setForceStatusBarVisible(false)
}
- chipAnimator.addListener(
- ChipAnimatorAdapter(endState, scheduledEvent!!.viewCreator))
- chipAnimator.addUpdateListener(chipUpdateListener)
- chipAnimator.interpolator = STANDARD_ACCELERATE
+ })
+ animSet2.start()
+ scheduledEvent = null
+ }, DISPLAY_LENGTH)
+ }
- val aSet2 = AnimatorSet()
+ private fun collectStartAnimations(): AnimatorSet {
+ val animators = mutableListOf<Animator>()
+ listeners.forEach { listener ->
+ listener.onSystemEventAnimationBegin()?.let { anim ->
+ animators.add(anim)
+ }
+ }
+ animators.add(chipAnimationController.onSystemEventAnimationBegin())
+ val animSet = AnimatorSet().also {
+ it.playTogether(animators)
+ }
- aSet2.play(chipAnimator).before(systemAnimator)
- if (hasPersistentDot) {
- val dotAnim = notifyTransitionToPersistentDot()
- if (dotAnim != null) aSet2.playTogether(systemAnimator, dotAnim)
- }
+ return animSet
+ }
- aSet2.start()
+ private fun collectFinishAnimations(): AnimatorSet {
+ val animators = mutableListOf<Animator>()
+ listeners.forEach { listener ->
+ listener.onSystemEventAnimationFinish(hasPersistentDot)?.let { anim ->
+ animators.add(anim)
+ }
+ }
+ animators.add(chipAnimationController.onSystemEventAnimationFinish(hasPersistentDot))
+ if (hasPersistentDot) {
+ val dotAnim = notifyTransitionToPersistentDot()
+ if (dotAnim != null) {
+ animators.add(dotAnim)
+ }
+ }
+ val animSet = AnimatorSet().also {
+ it.playTogether(animators)
+ }
- scheduledEvent = null
- }, DISPLAY_LENGTH)
- }, DELAY)
+ return animSet
}
private fun notifyTransitionToPersistentDot(): Animator? {
@@ -257,18 +281,6 @@ class SystemStatusAnimationScheduler @Inject constructor(
return null
}
- private fun notifySystemStart() {
- listeners.forEach { it.onSystemChromeAnimationStart() }
- }
-
- private fun notifySystemFinish() {
- listeners.forEach { it.onSystemChromeAnimationEnd() }
- }
-
- private fun notifySystemAnimationUpdate(anim: ValueAnimator) {
- listeners.forEach { it.onSystemChromeAnimationUpdate(anim) }
- }
-
override fun addCallback(listener: SystemStatusAnimationCallback) {
Assert.isMainThread()
@@ -287,24 +299,6 @@ class SystemStatusAnimationScheduler @Inject constructor(
}
}
- private val systemUpdateListener = ValueAnimator.AnimatorUpdateListener {
- anim -> notifySystemAnimationUpdate(anim)
- }
-
- private val systemAnimatorAdapter = object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(p0: Animator?) {
- notifySystemFinish()
- }
-
- override fun onAnimationStart(p0: Animator?) {
- notifySystemStart()
- }
- }
-
- private val chipUpdateListener = ValueAnimator.AnimatorUpdateListener {
- anim -> chipAnimationController.onChipAnimationUpdate(anim, animationState)
- }
-
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
pw.println("Scheduled event: $scheduledEvent")
pw.println("Has persistent privacy dot: $hasPersistentDot")
@@ -318,24 +312,6 @@ class SystemStatusAnimationScheduler @Inject constructor(
}
}
}
-
- inner class ChipAnimatorAdapter(
- @SystemAnimationState val endState: Int,
- val viewCreator: ViewCreator
- ) : AnimatorListenerAdapter() {
- override fun onAnimationEnd(p0: Animator?) {
- chipAnimationController.onChipAnimationEnd(animationState)
- animationState = if (endState == SHOWING_PERSISTENT_DOT && !hasPersistentDot) {
- IDLE
- } else {
- endState
- }
- }
-
- override fun onAnimationStart(p0: Animator?) {
- chipAnimationController.onChipAnimationStart(viewCreator, animationState)
- }
- }
}
/**
@@ -344,16 +320,14 @@ class SystemStatusAnimationScheduler @Inject constructor(
* create space for the chip animation to display. This means hiding the system elements in the
* status bar and keyguard.
*
- * TODO: the chip animation really only has one client, we can probably remove it from this
- * interface
- *
* The value animators themselves are simple animators from 0.0 to 1.0. Listeners can apply any
* interpolation they choose but realistically these are most likely to be simple alpha transitions
*/
interface SystemStatusAnimationCallback {
- @JvmDefault fun onSystemChromeAnimationUpdate(animator: ValueAnimator) {}
- @JvmDefault fun onSystemChromeAnimationStart() {}
- @JvmDefault fun onSystemChromeAnimationEnd() {}
+ /** Implement this method to return an [Animator] or [AnimatorSet] that presents the chip */
+ fun onSystemEventAnimationBegin(): Animator? { return null }
+ /** Implement this method to return an [Animator] or [AnimatorSet] that hides the chip */
+ fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator? { return null }
// Best method name, change my mind
@JvmDefault
@@ -363,50 +337,61 @@ interface SystemStatusAnimationCallback {
@JvmDefault fun onHidePersistentDot(): Animator? { return null }
}
-interface SystemStatusChipAnimationCallback {
- fun onChipAnimationUpdate(animator: ValueAnimator, @SystemAnimationState state: Int) {}
-
- fun onChipAnimationStart(
- viewCreator: ViewCreator,
- @SystemAnimationState state: Int
- ) {}
-
- fun onChipAnimationEnd(@SystemAnimationState state: Int) {}
-}
-
/**
+ * Animation state IntDef
*/
@Retention(AnnotationRetention.SOURCE)
@IntDef(
value = [
- IDLE, ANIMATING_IN, RUNNING_CHIP_ANIM, ANIMATING_OUT, SHOWING_PERSISTENT_DOT
+ IDLE,
+ ANIMATION_QUEUED,
+ ANIMATING_IN,
+ RUNNING_CHIP_ANIM,
+ ANIMATING_OUT,
+ SHOWING_PERSISTENT_DOT
]
)
annotation class SystemAnimationState
/** No animation is in progress */
const val IDLE = 0
+/** An animation is queued, and awaiting the debounce period */
+const val ANIMATION_QUEUED = 1
/** System is animating out, and chip is animating in */
-const val ANIMATING_IN = 1
+const val ANIMATING_IN = 2
/** Chip has animated in and is awaiting exit animation, and optionally playing its own animation */
-const val RUNNING_CHIP_ANIM = 2
+const val RUNNING_CHIP_ANIM = 3
/** Chip is animating away and system is animating back */
-const val ANIMATING_OUT = 3
+const val ANIMATING_OUT = 4
/** Chip has animated away, and the persistent dot is showing */
-const val SHOWING_PERSISTENT_DOT = 4
+const val SHOWING_PERSISTENT_DOT = 5
+
+/** Commonly-needed interpolators can go here */
+@JvmField val STATUS_BAR_X_MOVE_OUT = PathInterpolator(0.33f, 0f, 0f, 1f)
+@JvmField val STATUS_BAR_X_MOVE_IN = PathInterpolator(0f, 0f, 0f, 1f)
+/**
+ * Status chip animation to dot have multiple stages of motion, the _1 and _2 interpolators should
+ * be used in succession
+ */
+val STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_1 = PathInterpolator(0.44f, 0f, 0.25f, 1f)
+val STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_2 = PathInterpolator(0.3f, 0f, 0.26f, 1f)
+val STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_1 = PathInterpolator(0.4f, 0f, 0.17f, 1f)
+val STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_2 = PathInterpolator(0.3f, 0f, 0f, 1f)
+val STATUS_CHIP_MOVE_TO_DOT = PathInterpolator(0f, 0f, 0.05f, 1f)
private const val TAG = "SystemStatusAnimationScheduler"
-private const val DELAY = 0L
+private const val DEBOUNCE_DELAY = 100L
/**
- * The total time spent animation should be 1500ms. The entrance animation is how much time
- * we give to the system to animate system elements out of the way. Total chip animation length
- * will be equivalent to 2*chip_anim_length + display_length
+ * The total time spent on the chip animation is 1500ms, broken up into 3 sections:
+ * - 500ms to animate the chip in (including animating system icons away)
+ * - 500ms holding the chip on screen
+ * - 500ms to animate the chip away (and system icons back)
+ *
+ * So DISPLAY_LENGTH should be the sum of the first 2 phases, while the final 500ms accounts for
+ * the actual animation
*/
-private const val ENTRANCE_ANIM_LENGTH = 250L
-private const val CHIP_ANIM_LENGTH = 250L
-// 1s + entrance time + chip anim_length
-private const val DISPLAY_LENGTH = 1500L
+private const val DISPLAY_LENGTH = 1000L
private const val MIN_UPTIME: Long = 5 * 1000
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index fca2aa167e37..577d536262b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -163,10 +163,13 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
}
/**
- * @return The background of this view.
+ * @param width The actual width to apply to the background view.
*/
- public NotificationBackgroundView getBackgroundNormal() {
- return mBackgroundNormal;
+ public void setBackgroundWidth(int width) {
+ if (mBackgroundNormal == null) {
+ return;
+ }
+ mBackgroundNormal.setActualWidth(width);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index c237e1deeae3..e479509247d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -79,7 +79,6 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.ContrastColorUtil;
import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.CallLayout;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.classifier.FalsingCollector;
@@ -90,6 +89,7 @@ import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.RemoteInputController;
+import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
import com.android.systemui.statusbar.notification.ExpandAnimationParameters;
@@ -111,10 +111,11 @@ import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.SwipeableView;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
+import com.android.systemui.statusbar.policy.SmartReplyConstants;
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
import com.android.systemui.util.Compile;
import com.android.systemui.util.DumpUtilsKt;
@@ -169,6 +170,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private RowContentBindStage mRowContentBindStage;
private PeopleNotificationIdentifier mPeopleNotificationIdentifier;
private Optional<BubblesManager> mBubblesManagerOptional;
+ private MetricsLogger mMetricsLogger;
private int mIconTransformContentShift;
private int mMaxHeadsUpHeightBeforeN;
private int mMaxHeadsUpHeightBeforeP;
@@ -304,8 +306,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
final boolean wasExpanded = mGroupExpansionManager.isGroupExpanded(mEntry);
boolean nowExpanded = mGroupExpansionManager.toggleGroupExpansion(mEntry);
mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded);
- MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER,
- nowExpanded);
+ mMetricsLogger.action(MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER, nowExpanded);
onExpansionChanged(true /* userAction */, wasExpanded);
} else if (mEnableNonGroupedNotificationExpand) {
if (v.isAccessibilityFocused()) {
@@ -327,8 +328,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
notifyHeightChanged(true);
mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded);
- MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_EXPANDER,
- nowExpanded);
+ mMetricsLogger.action(MetricsEvent.ACTION_NOTIFICATION_EXPANDER, nowExpanded);
}
}
};
@@ -1271,7 +1271,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
addView(mMenuRow.getMenuView(), menuIndex);
}
for (NotificationContentView l : mLayouts) {
- l.initView();
+ l.reinflate();
l.reInflateViews();
}
mEntry.getSbn().clearPackageContext();
@@ -1464,7 +1464,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
* @param fromAccessibility whether this dismiss is coming from an accessibility action
*/
public void performDismiss(boolean fromAccessibility) {
- Dependency.get(MetricsLogger.class).count(NotificationCounters.NOTIFICATION_DISMISSED, 1);
+ mMetricsLogger.count(NotificationCounters.NOTIFICATION_DISMISSED, 1);
dismiss(fromAccessibility);
if (mEntry.isDismissable()) {
if (mOnUserInteractionCallback != null) {
@@ -1600,7 +1600,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
PeopleNotificationIdentifier peopleNotificationIdentifier,
OnUserInteractionCallback onUserInteractionCallback,
Optional<BubblesManager> bubblesManagerOptional,
- NotificationGutsManager gutsManager) {
+ NotificationGutsManager gutsManager,
+ MetricsLogger metricsLogger,
+ SmartReplyConstants smartReplyConstants,
+ SmartReplyController smartReplyController) {
mEntry = entry;
mAppName = appName;
if (mMenuRow == null) {
@@ -1623,15 +1626,18 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mFalsingManager = falsingManager;
mFalsingCollector = falsingCollector;
mStatusBarStateController = statusBarStateController;
-
mPeopleNotificationIdentifier = peopleNotificationIdentifier;
for (NotificationContentView l : mLayouts) {
- l.setPeopleNotificationIdentifier(mPeopleNotificationIdentifier);
- l.setRemoteInputViewSubcomponentFactory(rivSubcomponentFactory);
+ l.initialize(
+ mPeopleNotificationIdentifier,
+ rivSubcomponentFactory,
+ smartReplyConstants,
+ smartReplyController);
}
mOnUserInteractionCallback = onUserInteractionCallback;
mBubblesManagerOptional = bubblesManagerOptional;
mNotificationGutsManager = gutsManager;
+ mMetricsLogger = metricsLogger;
cacheIsSystemNotification();
}
@@ -3127,7 +3133,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
if (mGroupMembershipManager.isGroupSummary(mEntry)) {
event = MetricsEvent.ACTION_NOTIFICATION_GROUP_GESTURE_EXPANDER;
}
- MetricsLogger.action(mContext, event, userExpanded);
+ mMetricsLogger.action(event, userExpanded);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index c4beb5bf4d7b..599039d46556 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -27,6 +27,7 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.internal.logging.MetricsLogger;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
@@ -35,6 +36,7 @@ import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.FeedbackIcon;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
@@ -49,6 +51,7 @@ import com.android.systemui.statusbar.notification.row.dagger.NotificationRowSco
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.SmartReplyConstants;
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
import com.android.systemui.util.time.SystemClock;
import com.android.systemui.wmshell.BubblesManager;
@@ -82,6 +85,7 @@ public class ExpandableNotificationRowController implements NotifViewController
private final HeadsUpManager mHeadsUpManager;
private final ExpandableNotificationRow.OnExpandClickListener mOnExpandClickListener;
private final StatusBarStateController mStatusBarStateController;
+ private final MetricsLogger mMetricsLogger;
private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger =
this::logNotificationExpansion;
@@ -94,16 +98,21 @@ public class ExpandableNotificationRowController implements NotifViewController
private final boolean mAllowLongPress;
private final PeopleNotificationIdentifier mPeopleNotificationIdentifier;
private final Optional<BubblesManager> mBubblesManagerOptional;
+ private final SmartReplyConstants mSmartReplyConstants;
+ private final SmartReplyController mSmartReplyController;
private final ExpandableNotificationRowDragController mDragController;
@Inject
public ExpandableNotificationRowController(
ExpandableNotificationRow view,
- NotificationListContainer listContainer,
- RemoteInputViewSubcomponent.Factory rivSubcomponentFactory,
ActivatableNotificationViewController activatableNotificationViewController,
+ RemoteInputViewSubcomponent.Factory rivSubcomponentFactory,
+ MetricsLogger metricsLogger,
+ NotificationListContainer listContainer,
NotificationMediaManager mediaManager,
+ SmartReplyConstants smartReplyConstants,
+ SmartReplyController smartReplyController,
PluginManager pluginManager,
SystemClock clock,
@AppName String appName,
@@ -152,6 +161,9 @@ public class ExpandableNotificationRowController implements NotifViewController
mPeopleNotificationIdentifier = peopleNotificationIdentifier;
mBubblesManagerOptional = bubblesManagerOptional;
mDragController = dragController;
+ mMetricsLogger = metricsLogger;
+ mSmartReplyConstants = smartReplyConstants;
+ mSmartReplyController = smartReplyController;
}
/**
@@ -179,7 +191,10 @@ public class ExpandableNotificationRowController implements NotifViewController
mPeopleNotificationIdentifier,
mOnUserInteractionCallback,
mBubblesManagerOptional,
- mNotificationGutsManager
+ mNotificationGutsManager,
+ mMetricsLogger,
+ mSmartReplyConstants,
+ mSmartReplyController
);
mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
if (mAllowLongPress) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index adb4ce68c031..b9c7113206df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -39,7 +39,6 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.RemoteInputController;
@@ -94,7 +93,6 @@ public class NotificationContentView extends FrameLayout implements Notification
private final Rect mClipBounds = new Rect();
private int mMinContractedHeight;
- private int mNotificationContentMarginEnd;
private View mContractedChild;
private View mExpandedChild;
private View mHeadsUpChild;
@@ -116,7 +114,7 @@ public class NotificationContentView extends FrameLayout implements Notification
private NotificationViewWrapper mContractedWrapper;
private NotificationViewWrapper mExpandedWrapper;
private NotificationViewWrapper mHeadsUpWrapper;
- private HybridGroupManager mHybridGroupManager;
+ private final HybridGroupManager mHybridGroupManager;
private int mClipTopAmount;
private int mContentHeight;
private int mVisibleType = VISIBLE_TYPE_NONE;
@@ -128,7 +126,6 @@ public class NotificationContentView extends FrameLayout implements Notification
private int mHeadsUpHeight;
private int mNotificationMaxHeight;
private NotificationEntry mNotificationEntry;
- private GroupMembershipManager mGroupMembershipManager;
private RemoteInputController mRemoteInputController;
private Runnable mExpandedVisibleListener;
private PeopleNotificationIdentifier mPeopleIdentifier;
@@ -184,7 +181,6 @@ public class NotificationContentView extends FrameLayout implements Notification
private boolean mFocusOnVisibilityChange;
private boolean mHeadsUpAnimatingAway;
private int mClipBottomAmount;
- private boolean mIsLowPriority;
private boolean mIsContentExpandable;
private boolean mRemoteInputVisible;
private int mUnrestrictedContentHeight;
@@ -192,16 +188,23 @@ public class NotificationContentView extends FrameLayout implements Notification
public NotificationContentView(Context context, AttributeSet attrs) {
super(context, attrs);
mHybridGroupManager = new HybridGroupManager(getContext());
- mSmartReplyConstants = Dependency.get(SmartReplyConstants.class);
- mSmartReplyController = Dependency.get(SmartReplyController.class);
- initView();
+ reinflate();
}
- public void initView() {
+ public void initialize(
+ PeopleNotificationIdentifier peopleNotificationIdentifier,
+ RemoteInputViewSubcomponent.Factory rivSubcomponentFactory,
+ SmartReplyConstants smartReplyConstants,
+ SmartReplyController smartReplyController) {
+ mPeopleIdentifier = peopleNotificationIdentifier;
+ mRemoteInputSubcomponentFactory = rivSubcomponentFactory;
+ mSmartReplyConstants = smartReplyConstants;
+ mSmartReplyController = smartReplyController;
+ }
+
+ public void reinflate() {
mMinContractedHeight = getResources().getDimensionPixelSize(
R.dimen.min_notification_layout_height);
- mNotificationContentMarginEnd = getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.notification_content_margin_end);
}
public void setHeights(int smallHeight, int headsUpMaxHeight, int maxHeight) {
@@ -1606,7 +1609,6 @@ public class NotificationContentView extends FrameLayout implements Notification
}
public void setGroupMembershipManager(GroupMembershipManager groupMembershipManager) {
- mGroupMembershipManager = groupMembershipManager;
}
public void setRemoteInputController(RemoteInputController r) {
@@ -1694,10 +1696,6 @@ public class NotificationContentView extends FrameLayout implements Notification
mContainingNotification = containingNotification;
}
- public void setPeopleNotificationIdentifier(PeopleNotificationIdentifier peopleIdentifier) {
- mPeopleIdentifier = peopleIdentifier;
- }
-
public void requestSelectLayout(boolean needsAnimation) {
selectLayout(needsAnimation, false);
}
@@ -1865,7 +1863,6 @@ public class NotificationContentView extends FrameLayout implements Notification
}
public void setIsLowPriority(boolean isLowPriority) {
- mIsLowPriority = isLowPriority;
}
public boolean isDimmable() {
@@ -2090,10 +2087,6 @@ public class NotificationContentView extends FrameLayout implements Notification
return false;
}
- public void setRemoteInputViewSubcomponentFactory(RemoteInputViewSubcomponent.Factory factory) {
- mRemoteInputSubcomponentFactory = factory;
- }
-
private static class RemoteInputViewData {
@Nullable RemoteInputView mView;
@Nullable RemoteInputViewController mController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 27cc326fda19..ade95a8cbfe7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -782,6 +782,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
y = (int) (mAmbientState.getStackY() + mAmbientState.getStackHeight());
drawDebugInfo(canvas, y, Color.BLUE,
/* label= */ "mAmbientState.getStackY() + mAmbientState.getStackHeight() = "+y);
+
+ y = (int) mAmbientState.getStackY() + mContentHeight;
+ drawDebugInfo(canvas, y, Color.MAGENTA,
+ /* label= */ "mAmbientState.getStackY() + mContentHeight = " + y);
+
+ y = (int) mAmbientState.getStackY() + mIntrinsicContentHeight;
+ drawDebugInfo(canvas, y, Color.YELLOW,
+ /* label= */ "mAmbientState.getStackY() + mIntrinsicContentHeight = " + y);
}
private void drawDebugInfo(Canvas canvas, int y, int color, String label) {
@@ -1293,14 +1301,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mOnStackYChanged.accept(listenerNeedsAnimation);
}
if (mQsExpansionFraction <= 0 && !shouldSkipHeightUpdate()) {
- final float endHeight = updateStackEndHeight(
- getHeight(), getEmptyBottomMargin(), mTopPadding);
+ final float endHeight = updateStackEndHeight();
updateStackHeight(endHeight, fraction);
}
}
- public float updateStackEndHeight(float height, float bottomMargin, float topPadding) {
- final float stackEndHeight = Math.max(0f, height - bottomMargin - topPadding);
+ private float updateStackEndHeight() {
+ final float stackEndHeight = Math.max(0f, mIntrinsicContentHeight);
mAmbientState.setStackEndHeight(stackEndHeight);
return stackEndHeight;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 65173a230871..cb332bdf59b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -174,7 +174,7 @@ public class KeyguardStatusBarView extends RelativeLayout {
}
private void updateKeyguardStatusBarHeight() {
- MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
+ MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
lp.height = getStatusBarHeaderHeightKeyguard(mContext);
setLayoutParams(lp);
}
@@ -510,28 +510,6 @@ public class KeyguardStatusBarView extends RelativeLayout {
}
}
- void onSystemChromeAnimationStart(boolean isAnimatingOut) {
- if (isAnimatingOut) {
- mSystemIconsContainer.setVisibility(View.VISIBLE);
- mSystemIconsContainer.setAlpha(0f);
- }
- }
-
- void onSystemChromeAnimationEnd(boolean isAnimatingIn) {
- // Make sure the system icons are out of the way
- if (isAnimatingIn) {
- mSystemIconsContainer.setVisibility(View.INVISIBLE);
- mSystemIconsContainer.setAlpha(0f);
- } else {
- mSystemIconsContainer.setAlpha(1f);
- mSystemIconsContainer.setVisibility(View.VISIBLE);
- }
- }
-
- void onSystemChromeAnimationUpdate(float animatedValue) {
- mSystemIconsContainer.setAlpha(animatedValue);
- }
-
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index 1df1aff38593..af4fb8e2cf49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -17,8 +17,6 @@
package com.android.systemui.statusbar.phone;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
-import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_IN;
-import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_OUT;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -47,6 +45,7 @@ import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.fragment.StatusBarSystemEventAnimator;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserInfoTracker;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherController;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherFeatureController;
@@ -107,6 +106,8 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
@Override
public void onDensityOrFontScaleChanged() {
mView.loadDimens();
+ // The animator is dependent on resources for offsets
+ mSystemEventAnimator = new StatusBarSystemEventAnimator(mView, getResources());
}
@Override
@@ -123,21 +124,16 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
private final SystemStatusAnimationCallback mAnimationCallback =
new SystemStatusAnimationCallback() {
+ @NonNull
@Override
- public void onSystemChromeAnimationStart() {
- mView.onSystemChromeAnimationStart(
- mAnimationScheduler.getAnimationState() == ANIMATING_OUT);
+ public Animator onSystemEventAnimationFinish(boolean hasPersistentDot) {
+ return mSystemEventAnimator.onSystemEventAnimationFinish(hasPersistentDot);
}
+ @NonNull
@Override
- public void onSystemChromeAnimationEnd() {
- mView.onSystemChromeAnimationEnd(
- mAnimationScheduler.getAnimationState() == ANIMATING_IN);
- }
-
- @Override
- public void onSystemChromeAnimationUpdate(@NonNull ValueAnimator anim) {
- mView.onSystemChromeAnimationUpdate((float) anim.getAnimatedValue());
+ public Animator onSystemEventAnimationBegin() {
+ return mSystemEventAnimator.onSystemEventAnimationBegin();
}
};
@@ -232,6 +228,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
private int mStatusBarState;
private boolean mDozing;
private boolean mShowingKeyguardHeadsUp;
+ private StatusBarSystemEventAnimator mSystemEventAnimator;
@Inject
public KeyguardStatusBarViewController(
@@ -302,6 +299,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
mView.setKeyguardUserAvatarEnabled(
!mFeatureController.isStatusBarUserSwitcherFeatureEnabled());
mFeatureController.addCallback(enabled -> mView.setKeyguardUserAvatarEnabled(!enabled));
+ mSystemEventAnimator = new StatusBarSystemEventAnimator(mView, r);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 24f5ff86a794..78edc07c8544 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -445,7 +445,7 @@ public abstract class PanelViewController {
mLockscreenGestureLogger.log(LockscreenUiEvent.LOCKSCREEN_UNLOCK);
}
@Classifier.InteractionType int interactionType = vel == 0 ? GENERIC
- : vel > 0 ? QUICK_SETTINGS
+ : y - mInitialTouchY > 0 ? QUICK_SETTINGS
: (mKeyguardStateController.canDismissLockScreen()
? UNLOCK : BOUNCER_UNLOCK);
@@ -532,7 +532,7 @@ public abstract class PanelViewController {
return true;
}
- @Classifier.InteractionType int interactionType = vel > 0
+ @Classifier.InteractionType int interactionType = y - mInitialTouchY > 0
? QUICK_SETTINGS : (
mKeyguardStateController.canDismissLockScreen() ? UNLOCK : BOUNCER_UNLOCK);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 2c84219dbfd0..33bc40119745 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -20,12 +20,10 @@ import static android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS;
import static android.app.StatusBarManager.DISABLE_ONGOING_CALL_CHIP;
import static android.app.StatusBarManager.DISABLE_SYSTEM_INFO;
-import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_IN;
-import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_OUT;
import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.IDLE;
import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.SHOWING_PERSISTENT_DOT;
-import android.animation.ValueAnimator;
+import android.animation.Animator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
@@ -136,6 +134,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
}
};
private OperatorNameViewController mOperatorNameViewController;
+ private StatusBarSystemEventAnimator mSystemEventAnimator;
@SuppressLint("ValidFragment")
public CollapsedStatusBarFragment(
@@ -210,7 +209,8 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
initEmergencyCryptkeeperText();
initOperatorName();
initNotificationIconArea();
- mAnimationScheduler.addCallback(this);
+ mSystemEventAnimator =
+ new StatusBarSystemEventAnimator(mSystemIconArea, getResources());
}
@VisibleForTesting
@@ -245,6 +245,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
mCommandQueue.addCallback(this);
mStatusBarStateController.addCallback(this);
initOngoingCallChip();
+ mAnimationScheduler.addCallback(this);
mSecureSettings.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON),
@@ -258,6 +259,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
mCommandQueue.removeCallback(this);
mStatusBarStateController.removeCallback(this);
mOngoingCallController.removeCallback(mOngoingCallListener);
+ mAnimationScheduler.removeCallback(this);
mSecureSettings.unregisterContentObserver(mVolumeSettingObserver);
}
@@ -265,7 +267,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
public void onDestroyView() {
super.onDestroyView();
mStatusBarIconController.removeIconGroup(mDarkIconManager);
- mAnimationScheduler.removeCallback(this);
if (mNetworkController.hasEmergencyCryptKeeperText()) {
mNetworkController.removeCallback(mSignalCallback);
}
@@ -576,35 +577,16 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
disable(getContext().getDisplayId(), mDisabled1, mDisabled2, false /* animate */);
}
+ @Nullable
@Override
- public void onSystemChromeAnimationStart() {
- if (mAnimationScheduler.getAnimationState() == ANIMATING_OUT
- && !isSystemIconAreaDisabled()) {
- mSystemIconArea.setVisibility(View.VISIBLE);
- mSystemIconArea.setAlpha(0f);
- }
- }
-
- @Override
- public void onSystemChromeAnimationEnd() {
- // Make sure the system icons are out of the way
- if (mAnimationScheduler.getAnimationState() == ANIMATING_IN) {
- mSystemIconArea.setVisibility(View.INVISIBLE);
- mSystemIconArea.setAlpha(0f);
- } else {
- if (isSystemIconAreaDisabled()) {
- // don't unhide
- return;
- }
-
- mSystemIconArea.setAlpha(1f);
- mSystemIconArea.setVisibility(View.VISIBLE);
- }
+ public Animator onSystemEventAnimationBegin() {
+ return mSystemEventAnimator.onSystemEventAnimationBegin();
}
+ @Nullable
@Override
- public void onSystemChromeAnimationUpdate(@NonNull ValueAnimator animator) {
- mSystemIconArea.setAlpha((float) animator.getAnimatedValue());
+ public Animator onSystemEventAnimationFinish(boolean hasPersistentDot) {
+ return mSystemEventAnimator.onSystemEventAnimationFinish(hasPersistentDot);
}
private boolean isSystemIconAreaDisabled() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
new file mode 100644
index 000000000000..f530ec83aec5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 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.fragment
+
+import android.animation.Animator
+import android.animation.AnimatorSet
+import android.animation.ValueAnimator
+import android.content.res.Resources
+import android.view.View
+import com.android.systemui.R
+import com.android.systemui.statusbar.events.STATUS_BAR_X_MOVE_IN
+import com.android.systemui.statusbar.events.STATUS_BAR_X_MOVE_OUT
+import com.android.systemui.statusbar.events.SystemStatusAnimationCallback
+
+/**
+ * Tied directly to [SystemStatusAnimationScheduler]. Any StatusBar-like thing (keyguard, collapsed
+ * status bar fragment), can just feed this an animatable view to get the default system status
+ * animation.
+ *
+ * This animator relies on resources, and should be recreated whenever resources are updated. While
+ * this class could be used directly as the animation callback, it's probably best to forward calls
+ * to it so that it can be recreated at any moment without needing to remove/add callback.
+ */
+class StatusBarSystemEventAnimator(
+ val animatedView: View,
+ resources: Resources
+) : SystemStatusAnimationCallback {
+ private val translationXIn: Int = resources.getDimensionPixelSize(
+ R.dimen.ongoing_appops_chip_animation_in_status_bar_translation_x)
+ private val translationXOut: Int = resources.getDimensionPixelSize(
+ R.dimen.ongoing_appops_chip_animation_out_status_bar_translation_x)
+
+ override fun onSystemEventAnimationBegin(): Animator {
+ val moveOut = ValueAnimator.ofFloat(0f, 1f).setDuration(383)
+ moveOut.interpolator = STATUS_BAR_X_MOVE_OUT
+ moveOut.addUpdateListener { animation: ValueAnimator ->
+ animatedView.translationX = -(translationXIn * animation.animatedValue as Float)
+ }
+ val alphaOut = ValueAnimator.ofFloat(1f, 0f).setDuration(133)
+ alphaOut.interpolator = null
+ alphaOut.addUpdateListener { animation: ValueAnimator ->
+ animatedView.alpha = animation.animatedValue as Float
+ }
+
+ val animSet = AnimatorSet()
+ animSet.playTogether(moveOut, alphaOut)
+ return animSet
+ }
+
+ override fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator {
+ animatedView.translationX = translationXOut.toFloat()
+ val moveIn = ValueAnimator.ofFloat(1f, 0f).setDuration(467)
+ moveIn.startDelay = 33
+ moveIn.interpolator = STATUS_BAR_X_MOVE_IN
+ moveIn.addUpdateListener { animation: ValueAnimator ->
+ animatedView.translationX = translationXOut * animation.animatedValue as Float
+ }
+ val alphaIn = ValueAnimator.ofFloat(0f, 1f).setDuration(167)
+ alphaIn.startDelay = 67
+ alphaIn.interpolator = null
+ alphaIn.addUpdateListener { animation: ValueAnimator ->
+ animatedView.alpha = animation.animatedValue as Float
+ }
+
+ val animatorSet = AnimatorSet()
+ animatorSet.playTogether(moveIn, alphaIn)
+
+ return animatorSet
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
index bd878750dfe1..f8451017b367 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
@@ -299,10 +299,7 @@ class RemoteInputViewControllerImpl @Inject constructor(
view.clearAttachment()
entry.remoteInputUri = null
entry.remoteInputMimeType = null
- val resultSource = entry.editedSuggestionInfo
- ?.let { RemoteInput.SOURCE_FREE_FORM_INPUT }
- ?: RemoteInput.SOURCE_CHOICE
- RemoteInput.setResultsSource(fillInIntent, resultSource)
+ RemoteInput.setResultsSource(fillInIntent, remoteInputResultsSource)
return fillInIntent
}
@@ -332,10 +329,12 @@ class RemoteInputViewControllerImpl @Inject constructor(
entry.remoteInputText = fullText
// mirror prepareRemoteInputFromText for text input
- val resultSource = entry.editedSuggestionInfo
- ?.let { RemoteInput.SOURCE_FREE_FORM_INPUT }
- ?: RemoteInput.SOURCE_CHOICE
- RemoteInput.setResultsSource(fillInIntent, resultSource)
+ RemoteInput.setResultsSource(fillInIntent, remoteInputResultsSource)
return fillInIntent
}
+
+ private val remoteInputResultsSource
+ get() = entry.editedSuggestionInfo
+ ?.let { RemoteInput.SOURCE_CHOICE }
+ ?: RemoteInput.SOURCE_FREE_FORM_INPUT
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt b/packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt
new file mode 100644
index 000000000000..c0538c110426
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 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.util.animation
+
+import kotlin.math.roundToLong
+
+/** A generic util class for animations in SysUI. */
+class AnimationUtil {
+ companion object {
+ /**
+ * Returns the number of milliseconds there are in [numFrames] for a 60 fps device.
+ *
+ * Note that this method can be used on any device, not just 60 fps devices. Animation
+ * lengths are typically specified in terms of number of frames for a 60 fps device, and
+ * the value "5 frames" is often more meaningful than "83ms". This method allows us to
+ * write animation code in terms of the more meaningful "5" number.
+ *
+ * @param numFrames must be >= 0.
+ */
+ fun getMsForFrames(numFrames: Int): Long {
+ if (numFrames < 0) {
+ throw IllegalArgumentException("numFrames must be >= 0")
+ }
+ return (numFrames * 1000f / 60f).roundToLong()
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
index daf81bdc6e82..dcbe0ab96dac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
@@ -37,6 +37,7 @@ import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import javax.inject.Provider
+import org.mockito.Mockito.`when` as whenever
private val DATA = MediaData(
userId = -1,
@@ -82,6 +83,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
+ whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
mediaCarouselController = MediaCarouselController(
context,
mediaControlPanelFactory,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index 90eff1ae9804..cb68d81287df 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -101,6 +101,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Mock private lateinit var mediaOutputDialogFactory: MediaOutputDialogFactory
@Mock private lateinit var mediaCarouselController: MediaCarouselController
@Mock private lateinit var falsingManager: FalsingManager
+ @Mock private lateinit var mediaFlags: MediaFlags
private lateinit var appIcon: ImageView
private lateinit var albumView: ImageView
private lateinit var titleText: TextView
@@ -146,7 +147,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
player = MediaControlPanel(context, bgExecutor, activityStarter, broadcastSender,
mediaViewController, seekBarViewModel, Lazy { mediaDataManager },
- mediaOutputDialogFactory, mediaCarouselController, falsingManager, clock)
+ mediaOutputDialogFactory, mediaCarouselController, falsingManager, mediaFlags, clock)
whenever(seekBarViewModel.progress).thenReturn(seekBarData)
// Set up mock views for the players
@@ -214,6 +215,9 @@ public class MediaControlPanelTest : SysuiTestCase() {
device = device,
active = true,
resumeAction = null)
+
+ whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(false)
+ whenever(mediaFlags.useMediaSessionLayout()).thenReturn(false)
}
/**
@@ -291,6 +295,9 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindSemanticActionsOldLayout() {
+ whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
+ whenever(mediaFlags.useMediaSessionLayout()).thenReturn(false)
+
val icon = Icon.createWithResource(context, android.R.drawable.ic_media_play)
val semanticActions = MediaButton(
playOrPause = MediaAction(icon, Runnable {}, "play"),
@@ -325,6 +332,9 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindSemanticActionsNewLayout() {
+ whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
+ whenever(mediaFlags.useMediaSessionLayout()).thenReturn(true)
+
val icon = Icon.createWithResource(context, android.R.drawable.ic_media_play)
val semanticActions = MediaButton(
playOrPause = MediaAction(icon, Runnable {}, "play"),
@@ -371,6 +381,9 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindNotificationActionsNewLayout() {
+ whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
+ whenever(mediaFlags.useMediaSessionLayout()).thenReturn(true)
+
val icon = Icon.createWithResource(context, android.R.drawable.ic_media_play)
val actions = listOf(
MediaAction(icon, Runnable {}, "previous"),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
index be2450d11c08..925ae30e8773 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -26,7 +26,6 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.SbnBuilder
import com.android.systemui.tuner.TunerService
import com.android.systemui.util.concurrency.FakeExecutor
-import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.time.FakeSystemClock
@@ -38,7 +37,6 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyBoolean
-import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
@@ -169,7 +167,7 @@ class MediaDataManagerTest : SysuiTestCase() {
whenever(mediaSmartspaceTarget.featureType).thenReturn(SmartspaceTarget.FEATURE_MEDIA)
whenever(mediaSmartspaceTarget.iconGrid).thenReturn(listOf(mediaRecommendationItem))
whenever(mediaSmartspaceTarget.creationTimeMillis).thenReturn(1234L)
- whenever(mediaFlags.areMediaSessionActionsEnabled(any(), anyInt())).thenReturn(false)
+ whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(false)
}
@After
@@ -596,7 +594,7 @@ class MediaDataManagerTest : SysuiTestCase() {
@Test
fun testPlaybackActions_noState_usesNotification() {
val desc = "Notification Action"
- whenever(mediaFlags.areMediaSessionActionsEnabled(any(), anyInt())).thenReturn(true)
+ whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
whenever(controller.playbackState).thenReturn(null)
val notifWithAction = SbnBuilder().run {
@@ -623,7 +621,7 @@ class MediaDataManagerTest : SysuiTestCase() {
@Test
fun testPlaybackActions_hasPrevNext() {
val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4")
- whenever(mediaFlags.areMediaSessionActionsEnabled(any(), anyInt())).thenReturn(true)
+ whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
val stateActions = PlaybackState.ACTION_PLAY or
PlaybackState.ACTION_SKIP_TO_PREVIOUS or
PlaybackState.ACTION_SKIP_TO_NEXT
@@ -671,7 +669,7 @@ class MediaDataManagerTest : SysuiTestCase() {
@Test
fun testPlaybackActions_noPrevNext_usesCustom() {
val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4", "custom 5")
- whenever(mediaFlags.areMediaSessionActionsEnabled(any(), anyInt())).thenReturn(true)
+ whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
val stateActions = PlaybackState.ACTION_PLAY
val stateBuilder = PlaybackState.Builder()
.setActions(stateActions)
@@ -709,7 +707,7 @@ class MediaDataManagerTest : SysuiTestCase() {
@Test
fun testPlaybackActions_reservedSpace() {
val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4")
- whenever(mediaFlags.areMediaSessionActionsEnabled(any(), anyInt())).thenReturn(true)
+ whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true)
val stateActions = PlaybackState.ACTION_PLAY
val stateBuilder = PlaybackState.Builder()
.setActions(stateActions)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
index ccce5778c150..962d78c129f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
@@ -81,6 +81,9 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
whenever(packageManager.getApplicationIcon(PACKAGE_NAME)).thenReturn(appIconFromPackageName)
whenever(applicationInfo.loadLabel(packageManager)).thenReturn(APP_NAME)
whenever(packageManager.getApplicationInfo(
+ any(), any<PackageManager.ApplicationInfoFlags>()
+ )).thenThrow(PackageManager.NameNotFoundException())
+ whenever(packageManager.getApplicationInfo(
eq(PACKAGE_NAME), any<PackageManager.ApplicationInfoFlags>()
)).thenReturn(applicationInfo)
context.setMockPackageManager(packageManager)
@@ -189,6 +192,28 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
verify(windowManager, never()).removeView(any())
}
+
+ @Test
+ fun displayChip_nullAppIconDrawableAndNullPackageName_stillHasIcon() {
+ controllerCommon.displayChip(getState())
+ val chipView = getChipView()
+
+ controllerCommon.setIcon(chipView, appPackageName = null, appIconDrawableOverride = null)
+
+ assertThat(chipView.getAppIconView().drawable).isNotNull()
+ }
+
+ @Test
+ fun displayChip_nullAppIconDrawableAndInvalidPackageName_stillHasIcon() {
+ controllerCommon.displayChip(getState())
+ val chipView = getChipView()
+
+ controllerCommon.setIcon(
+ chipView, appPackageName = "fakePackageName", appIconDrawableOverride = null
+ )
+
+ assertThat(chipView.getAppIconView().drawable).isNotNull()
+ }
@Test
fun setIcon_nullAppIconDrawable_iconIsFromPackageName() {
@@ -212,6 +237,28 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
}
@Test
+ fun displayChip_nullAppNameAndNullPackageName_stillHasContentDescription() {
+ controllerCommon.displayChip(getState())
+ val chipView = getChipView()
+
+ controllerCommon.setIcon(chipView, appPackageName = null, appNameOverride = null)
+
+ assertThat(chipView.getAppIconView().contentDescription.toString()).isNotEmpty()
+ }
+
+ @Test
+ fun displayChip_nullAppNameAndInvalidPackageName_stillHasContentDescription() {
+ controllerCommon.displayChip(getState())
+ val chipView = getChipView()
+
+ controllerCommon.setIcon(
+ chipView, appPackageName = "fakePackageName", appNameOverride = null
+ )
+
+ assertThat(chipView.getAppIconView().contentDescription.toString()).isNotEmpty()
+ }
+
+ @Test
fun displayChip_nullAppName_iconContentDescriptionIsFromPackageName() {
controllerCommon.displayChip(getState())
val chipView = getChipView()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
index 7fc5ece670d4..251ac7d250fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
@@ -41,6 +41,7 @@ import android.testing.TestableLooper;
import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
import androidx.test.filters.SmallTest;
+import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.NotificationMessagingUtil;
import com.android.systemui.R;
@@ -87,6 +88,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder;
+import com.android.systemui.statusbar.policy.SmartReplyConstants;
import com.android.systemui.statusbar.policy.SmartReplyStateInflater;
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -252,13 +254,17 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
.thenAnswer((Answer<ExpandableNotificationRowController>) invocation ->
new ExpandableNotificationRowController(
viewCaptor.getValue(),
- mListContainer,
- mock(RemoteInputViewSubcomponent.Factory.class),
mock(ActivatableNotificationViewController.class),
+ mock(RemoteInputViewSubcomponent.Factory.class),
+ mock(MetricsLogger.class),
+ mListContainer,
mNotificationMediaManager,
+ mock(SmartReplyConstants.class),
+ mock(SmartReplyController.class),
mock(PluginManager.class),
new FakeSystemClock(),
- "FOOBAR", "FOOBAR",
+ "FOOBAR",
+ "FOOBAR",
mKeyguardBypassController,
mGroupMembershipManager,
mGroupExpansionManager,
@@ -275,8 +281,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
mock(FeatureFlags.class),
mPeopleNotificationIdentifier,
Optional.of(mock(BubblesManager.class)),
- mock(ExpandableNotificationRowDragController.class)
- ));
+ mock(ExpandableNotificationRowDragController.class)));
when(mNotificationRowComponentBuilder.activatableNotificationView(any()))
.thenReturn(mNotificationRowComponentBuilder);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 72f8f70058fc..1ecb09bc8514 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -44,6 +44,7 @@ import android.text.TextUtils;
import android.view.LayoutInflater;
import android.widget.RemoteViews;
+import com.android.internal.logging.MetricsLogger;
import com.android.systemui.TestableDependency;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.FalsingManagerFake;
@@ -54,6 +55,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -73,6 +75,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder;
+import com.android.systemui.statusbar.policy.SmartReplyConstants;
import com.android.systemui.statusbar.policy.SmartReplyStateInflater;
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
import com.android.systemui.tests.R;
@@ -505,7 +508,10 @@ public class NotificationTestHelper {
mPeopleNotificationIdentifier,
mOnUserInteractionCallback,
Optional.of(mock(BubblesManager.class)),
- mock(NotificationGutsManager.class));
+ mock(NotificationGutsManager.class),
+ mock(MetricsLogger.class),
+ mock(SmartReplyConstants.class),
+ mock(SmartReplyController.class));
row.setAboveShelfChangedListener(aboveShelf -> { });
mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index eafcc354fac4..56541f3ceb6f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -161,17 +161,6 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
}
@Test
- public void testUpdateStackEndHeight_forEndOfStackHeightAnimation() {
- final float nsslHeight = 10f;
- final float bottomMargin = 1f;
- final float topPadding = 1f;
-
- mStackScroller.updateStackEndHeight(nsslHeight, bottomMargin, topPadding);
- final float stackEndHeight = nsslHeight - bottomMargin - topPadding;
- assertTrue(mAmbientState.getStackEndHeight() == stackEndHeight);
- }
-
- @Test
public void testUpdateStackHeight_withDozeAmount_whenDozeChanging() {
final float dozeAmount = 0.5f;
mAmbientState.setDozeAmount(dozeAmount);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/animation/AnimationUtilTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/animation/AnimationUtilTest.kt
new file mode 100644
index 000000000000..92afb038b321
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/animation/AnimationUtilTest.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 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.util.animation
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import java.lang.IllegalArgumentException
+
+@SmallTest
+class AnimationUtilTest : SysuiTestCase() {
+ @Test
+ fun getMsForFrames_5frames_returns83() {
+ assertThat(AnimationUtil.getMsForFrames(5)).isEqualTo(83L)
+ }
+
+ @Test
+ fun getMsForFrames_7frames_returns117() {
+ assertThat(AnimationUtil.getMsForFrames(7)).isEqualTo(117L)
+ }
+
+ @Test
+ fun getMsForFrames_30frames_returns500() {
+ assertThat(AnimationUtil.getMsForFrames(30)).isEqualTo(500L)
+ }
+
+ @Test
+ fun getMsForFrames_60frames_returns1000() {
+ assertThat(AnimationUtil.getMsForFrames(60)).isEqualTo(1000L)
+ }
+
+ @Test(expected = IllegalArgumentException::class)
+ fun getMsForFrames_negativeFrames_throwsException() {
+ AnimationUtil.getMsForFrames(-1)
+ }
+}
diff --git a/services/api/current.txt b/services/api/current.txt
index 5a2880223f6c..780fccfc2e4d 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -47,6 +47,9 @@ package com.android.server.am {
package com.android.server.pm {
public interface PackageManagerLocal {
+ method public void reconcileSdkData(@Nullable String, @NonNull String, @NonNull java.util.List<java.lang.String>, int, int, int, @NonNull String, int) throws java.io.IOException;
+ field public static final int FLAG_STORAGE_CE = 2; // 0x2
+ field public static final int FLAG_STORAGE_DE = 1; // 0x1
}
}
diff --git a/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchPerUserService.java b/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchPerUserService.java
index 116c7391b388..8e0e3959dd0e 100644
--- a/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchPerUserService.java
+++ b/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchPerUserService.java
@@ -107,6 +107,10 @@ public class CloudSearchPerUserService extends
@GuardedBy("mLock")
public void onSearchLocked(@NonNull SearchRequest searchRequest,
@NonNull ICloudSearchManagerCallback callback) {
+ if (mRemoteComponentName == null) {
+ return;
+ }
+
String filterList = searchRequest.getSearchConstraints().containsKey(
SearchRequest.CONSTRAINT_SEARCH_PROVIDER_FILTER)
? searchRequest.getSearchConstraints().getString(
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 569d4809a541..2dfe94729bb8 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -1302,7 +1302,7 @@ final class UiModeManagerService extends SystemService {
pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState);
pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" (");
- pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") ");
+ pw.print(Shell.nightModeToStr(mNightMode, mNightModeCustomType)); pw.print(") ");
pw.print(" mOverrideOn/Off="); pw.print(mOverrideNightModeOn);
pw.print("/"); pw.print(mOverrideNightModeOff);
@@ -1917,7 +1917,8 @@ final class UiModeManagerService extends SystemService {
public static final String NIGHT_MODE_STR_YES = "yes";
public static final String NIGHT_MODE_STR_NO = "no";
public static final String NIGHT_MODE_STR_AUTO = "auto";
- public static final String NIGHT_MODE_STR_CUSTOM = "custom";
+ public static final String NIGHT_MODE_STR_CUSTOM_SCHEDULE = "custom_schedule";
+ public static final String NIGHT_MODE_STR_CUSTOM_BEDTIME = "custom_bedtime";
public static final String NIGHT_MODE_STR_UNKNOWN = "unknown";
private final IUiModeManager mInterface;
@@ -1931,7 +1932,7 @@ final class UiModeManagerService extends SystemService {
pw.println("UiModeManager service (uimode) commands:");
pw.println(" help");
pw.println(" Print this help text.");
- pw.println(" night [yes|no|auto|custom]");
+ pw.println(" night [yes|no|auto|custom_schedule|custom_bedtime]");
pw.println(" Set or read night mode.");
pw.println(" car [yes|no]");
pw.println(" Set or read car mode.");
@@ -2001,14 +2002,19 @@ final class UiModeManagerService extends SystemService {
}
final int mode = strToNightMode(modeStr);
+ final int customType = strToNightModeCustomType(modeStr);
if (mode >= 0) {
mInterface.setNightMode(mode);
+ if (mode == UiModeManager.MODE_NIGHT_CUSTOM) {
+ mInterface.setNightModeCustomType(customType);
+ }
printCurrentNightMode();
return 0;
} else {
err.println("Error: mode must be '" + NIGHT_MODE_STR_YES + "', '"
+ NIGHT_MODE_STR_NO + "', or '" + NIGHT_MODE_STR_AUTO
- + "', or '" + NIGHT_MODE_STR_CUSTOM + "'");
+ + "', or '" + NIGHT_MODE_STR_CUSTOM_SCHEDULE + "', or '"
+ + NIGHT_MODE_STR_CUSTOM_BEDTIME + "'");
return -1;
}
}
@@ -2016,11 +2022,12 @@ final class UiModeManagerService extends SystemService {
private void printCurrentNightMode() throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
final int currMode = mInterface.getNightMode();
- final String currModeStr = nightModeToStr(currMode);
+ final int customType = mInterface.getNightModeCustomType();
+ final String currModeStr = nightModeToStr(currMode, customType);
pw.println("Night mode: " + currModeStr);
}
- private static String nightModeToStr(int mode) {
+ private static String nightModeToStr(int mode, int customType) {
switch (mode) {
case UiModeManager.MODE_NIGHT_YES:
return NIGHT_MODE_STR_YES;
@@ -2029,7 +2036,12 @@ final class UiModeManagerService extends SystemService {
case UiModeManager.MODE_NIGHT_AUTO:
return NIGHT_MODE_STR_AUTO;
case MODE_NIGHT_CUSTOM:
- return NIGHT_MODE_STR_CUSTOM;
+ if (customType == UiModeManager.MODE_NIGHT_CUSTOM_TYPE_SCHEDULE) {
+ return NIGHT_MODE_STR_CUSTOM_SCHEDULE;
+ }
+ if (customType == UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME) {
+ return NIGHT_MODE_STR_CUSTOM_BEDTIME;
+ }
default:
return NIGHT_MODE_STR_UNKNOWN;
}
@@ -2043,13 +2055,25 @@ final class UiModeManagerService extends SystemService {
return UiModeManager.MODE_NIGHT_NO;
case NIGHT_MODE_STR_AUTO:
return UiModeManager.MODE_NIGHT_AUTO;
- case NIGHT_MODE_STR_CUSTOM:
+ case NIGHT_MODE_STR_CUSTOM_SCHEDULE:
+ case NIGHT_MODE_STR_CUSTOM_BEDTIME:
return UiModeManager.MODE_NIGHT_CUSTOM;
default:
return -1;
}
}
+ private static int strToNightModeCustomType(String customTypeStr) {
+ switch (customTypeStr) {
+ case NIGHT_MODE_STR_CUSTOM_BEDTIME:
+ return UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME;
+ case NIGHT_MODE_STR_CUSTOM_SCHEDULE:
+ return UiModeManager.MODE_NIGHT_CUSTOM_TYPE_SCHEDULE;
+ default:
+ return -1;
+ }
+ }
+
private int handleCarMode() throws RemoteException {
final PrintWriter err = getErrPrintWriter();
final String modeStr = getNextArg();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0735648c1069..9d9ee8c7a03b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2911,12 +2911,35 @@ public class ActivityManagerService extends IActivityManager.Stub
return mAtmInternal.compatibilityInfoForPackage(ai);
}
+ /**
+ * Enforces that the uid that calls a method is not an
+ * {@link UserHandle#isIsolated(int) isolated} uid.
+ *
+ * @param caller the name of the method being called.
+ * @throws SecurityException if the calling uid is an isolated uid.
+ */
/* package */ void enforceNotIsolatedCaller(String caller) {
if (UserHandle.isIsolated(Binder.getCallingUid())) {
throw new SecurityException("Isolated process not allowed to call " + caller);
}
}
+ /**
+ * Enforces that the uid that calls a method is not an
+ * {@link UserHandle#isIsolated(int) isolated} uid or an
+ * {@link Process#isSdkSandboxUid(int) SDK sandbox} uid.
+ *
+ * @param caller the name of the method being called.
+ * @throws SecurityException if the calling uid is an isolated uid or SDK sandbox uid.
+ */
+ void enforceNotIsolatedOrSdkSandboxCaller(String caller) {
+ enforceNotIsolatedCaller(caller);
+
+ if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
+ throw new SecurityException("SDK sandbox process not allowed to call " + caller);
+ }
+ }
+
@Override
public void setPackageScreenCompatMode(String packageName, int mode) {
mActivityTaskManager.setPackageScreenCompatMode(packageName, mode);
@@ -12843,7 +12866,7 @@ public class ActivityManagerService extends IActivityManager.Stub
public Intent registerReceiverWithFeature(IApplicationThread caller, String callerPackage,
String callerFeatureId, String receiverId, IIntentReceiver receiver,
IntentFilter filter, String permission, int userId, int flags) {
- enforceNotIsolatedCaller("registerReceiver");
+ enforceNotIsolatedOrSdkSandboxCaller("registerReceiver");
ArrayList<Intent> stickyIntents = null;
ProcessRecord callerApp = null;
final boolean visibleToInstantApps
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index d01be5820d34..309a4ff16753 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -102,6 +102,7 @@ import android.media.IRecordingConfigDispatcher;
import android.media.IRingtonePlayer;
import android.media.ISpatializerCallback;
import android.media.ISpatializerHeadToSoundStagePoseCallback;
+import android.media.ISpatializerHeadTrackerAvailableCallback;
import android.media.ISpatializerHeadTrackingModeCallback;
import android.media.ISpatializerOutputCallback;
import android.media.IStrategyPreferredDevicesDispatcher;
@@ -8723,6 +8724,11 @@ public class AudioService extends IAudioService.Stub
return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device));
}
+ /** @see Spatializer#isHeadTrackerAvailable() */
+ public boolean isHeadTrackerAvailable() {
+ return mSpatializerHelper.isHeadTrackerAvailable();
+ }
+
/** @see Spatializer#setSpatializerEnabled(boolean) */
public void setSpatializerEnabled(boolean enabled) {
enforceModifyDefaultAudioEffectsPermission();
@@ -8767,6 +8773,13 @@ public class AudioService extends IAudioService.Stub
mSpatializerHelper.unregisterHeadTrackingModeCallback(cb);
}
+ /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */
+ public void registerSpatializerHeadTrackerAvailableCallback(
+ @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) {
+ Objects.requireNonNull(cb);
+ mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register);
+ }
+
/** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */
public void registerHeadToSoundstagePoseCallback(
@NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 5af73c9e46ea..4a853e18b3a4 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -30,6 +30,7 @@ import android.media.INativeSpatializerCallback;
import android.media.ISpatializer;
import android.media.ISpatializerCallback;
import android.media.ISpatializerHeadToSoundStagePoseCallback;
+import android.media.ISpatializerHeadTrackerAvailableCallback;
import android.media.ISpatializerHeadTrackingCallback;
import android.media.ISpatializerHeadTrackingModeCallback;
import android.media.ISpatializerOutputCallback;
@@ -126,6 +127,7 @@ public class SpatializerHelper {
private boolean mBinauralSupported = false;
private int mActualHeadTrackingMode = Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED;
private int mDesiredHeadTrackingMode = Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD;
+ private boolean mHeadTrackerAvailable = false;
/**
* The desired head tracking mode when enabling head tracking, tracks mDesiredHeadTrackingMode,
* except when head tracking gets disabled through setting the desired mode to
@@ -831,6 +833,7 @@ public class SpatializerHelper {
mSpatCallback = null;
try {
mSpat.registerHeadTrackingCallback(null);
+ mHeadTrackerAvailable = false;
mSpat.release();
} catch (RemoteException e) {
Log.e(TAG, "Can't set release spatializer cleanly", e);
@@ -890,6 +893,18 @@ public class SpatializerHelper {
mHeadTrackingModeCallbacks.unregister(callback);
}
+ final RemoteCallbackList<ISpatializerHeadTrackerAvailableCallback> mHeadTrackerCallbacks =
+ new RemoteCallbackList<>();
+
+ synchronized void registerHeadTrackerAvailableCallback(
+ @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) {
+ if (register) {
+ mHeadTrackerCallbacks.register(cb);
+ } else {
+ mHeadTrackerCallbacks.unregister(cb);
+ }
+ }
+
synchronized int[] getSupportedHeadTrackingModes() {
switch (mState) {
case STATE_UNINITIALIZED:
@@ -1090,6 +1105,10 @@ public class SpatializerHelper {
return false;
}
+ synchronized boolean isHeadTrackerAvailable() {
+ return mHeadTrackerAvailable;
+ }
+
private boolean checkSpatForHeadTracking(String funcName) {
switch (mState) {
case STATE_UNINITIALIZED:
@@ -1115,7 +1134,8 @@ public class SpatializerHelper {
mHeadTrackingModeCallbacks.getBroadcastItem(i)
.dispatchSpatializerActualHeadTrackingModeChanged(newMode);
} catch (RemoteException e) {
- Log.e(TAG, "Error in dispatchSpatializerActualHeadTrackingModeChanged", e);
+ Log.e(TAG, "Error in dispatchSpatializerActualHeadTrackingModeChanged("
+ + newMode + ")", e);
}
}
mHeadTrackingModeCallbacks.finishBroadcast();
@@ -1128,12 +1148,27 @@ public class SpatializerHelper {
mHeadTrackingModeCallbacks.getBroadcastItem(i)
.dispatchSpatializerDesiredHeadTrackingModeChanged(newMode);
} catch (RemoteException e) {
- Log.e(TAG, "Error in dispatchSpatializerDesiredHeadTrackingModeChanged", e);
+ Log.e(TAG, "Error in dispatchSpatializerDesiredHeadTrackingModeChanged("
+ + newMode + ")", e);
}
}
mHeadTrackingModeCallbacks.finishBroadcast();
}
+ private void dispatchHeadTrackerAvailable(boolean available) {
+ final int nbCallbacks = mHeadTrackerCallbacks.beginBroadcast();
+ for (int i = 0; i < nbCallbacks; i++) {
+ try {
+ mHeadTrackerCallbacks.getBroadcastItem(i)
+ .dispatchSpatializerHeadTrackerAvailable(available);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in dispatchSpatializerHeadTrackerAvailable("
+ + available + ")", e);
+ }
+ }
+ mHeadTrackerCallbacks.finishBroadcast();
+ }
+
//------------------------------------------------------
// head pose
final RemoteCallbackList<ISpatializerHeadToSoundStagePoseCallback> mHeadPoseCallbacks =
@@ -1348,6 +1383,10 @@ public class SpatializerHelper {
try {
Log.i(TAG, "setHeadSensor:" + headHandle);
mSpat.setHeadSensor(headHandle);
+ if (mHeadTrackerAvailable != (headHandle != -1)) {
+ mHeadTrackerAvailable = (headHandle != -1);
+ dispatchHeadTrackerAvailable(mHeadTrackerAvailable);
+ }
} catch (Exception e) {
Log.e(TAG, "Error calling setHeadSensor:" + headHandle, e);
}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 76b9830cbde9..5902f487d353 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -27,6 +27,7 @@ import android.os.CreateAppDataArgs;
import android.os.CreateAppDataResult;
import android.os.IBinder;
import android.os.IInstalld;
+import android.os.ReconcileSdkDataArgs;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.storage.CrateMetadata;
@@ -215,6 +216,21 @@ public class Installer extends SystemService {
return result;
}
+ static ReconcileSdkDataArgs buildReconcileSdkDataArgs(String uuid, String packageName,
+ List<String> subDirNames, int userId, int appId,
+ String seInfo, int flags) {
+ final ReconcileSdkDataArgs args = new ReconcileSdkDataArgs();
+ args.uuid = uuid;
+ args.packageName = packageName;
+ args.subDirNames = subDirNames;
+ args.userId = userId;
+ args.appId = appId;
+ args.previousAppId = 0;
+ args.seInfo = seInfo;
+ args.flags = flags;
+ return args;
+ }
+
public @NonNull CreateAppDataResult createAppData(@NonNull CreateAppDataArgs args)
throws InstallerException {
if (!checkBeforeRemote()) {
@@ -247,6 +263,18 @@ public class Installer extends SystemService {
}
}
+ void reconcileSdkData(@NonNull ReconcileSdkDataArgs args)
+ throws InstallerException {
+ if (!checkBeforeRemote()) {
+ return;
+ }
+ try {
+ mInstalld.reconcileSdkData(args);
+ } catch (Exception e) {
+ throw InstallerException.from(e);
+ }
+ }
+
/**
* Class that collects multiple {@code installd} operations together in an
* attempt to more efficiently execute them in bulk.
diff --git a/services/core/java/com/android/server/pm/PackageManagerLocal.java b/services/core/java/com/android/server/pm/PackageManagerLocal.java
index 7b76567fcc6e..39cc37ea2e7c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerLocal.java
+++ b/services/core/java/com/android/server/pm/PackageManagerLocal.java
@@ -16,8 +16,16 @@
package com.android.server.pm;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
/**
* In-process API for server side PackageManager related infrastructure.
*
@@ -28,4 +36,48 @@ import android.annotation.SystemApi;
*/
@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
public interface PackageManagerLocal {
+
+ /**
+ * Indicates if operation should include device encrypted storage.
+ */
+ int FLAG_STORAGE_DE = Installer.FLAG_STORAGE_DE;
+ /**
+ * Indicates if operation should include credential encrypted storage.
+ */
+ int FLAG_STORAGE_CE = Installer.FLAG_STORAGE_CE;
+
+ /**
+ * Constants for use with {@link #reconcileSdkData} to specify which storage areas should be
+ * included for operation.
+ *
+ * @hide
+ */
+ @IntDef(prefix = "FLAG_STORAGE_", value = {
+ FLAG_STORAGE_DE,
+ FLAG_STORAGE_CE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface StorageFlags {}
+
+ /**
+ * Reconcile sdk data sub-directories for the given {@code packagName}.
+ *
+ * Sub directories are created if they do not exist already. If there is an existing per-
+ * sdk directory that is missing from {@code subDirNames}, then it is removed.
+ *
+ * Sdk package path is created if it doesn't exist before creating per-sdk directories.
+ *
+ * @param volumeUuid the volume in which the sdk data should be prepared.
+ * @param packageName package name of the app for which sdk data directory will be prepared.
+ * @param subDirNames names of sub directories that should be reconciled against.
+ * @param userId id of the user to whom the package belongs to.
+ * @param appId id of the package.
+ * @param previousAppId previous id of the package if package is being updated.
+ * @param flags flags from StorageManager to indicate which storage areas should be included.
+ * @param seInfo seInfo tag to be used for selinux policy.
+ * @throws IOException If any error occurs during the operation.
+ */
+ void reconcileSdkData(@Nullable String volumeUuid, @NonNull String packageName,
+ @NonNull List<String> subDirNames, int userId, int appId, int previousAppId,
+ @NonNull String seInfo, @StorageFlags int flags) throws IOException;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 67056ead3423..eaecb17103a5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -132,6 +132,7 @@ import android.os.Parcel;
import android.os.ParcelableException;
import android.os.PersistableBundle;
import android.os.Process;
+import android.os.ReconcileSdkDataArgs;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -6032,6 +6033,22 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
private class PackageManagerLocalImpl implements PackageManagerLocal {
+ @Override
+ public void reconcileSdkData(@Nullable String volumeUuid, @NonNull String packageName,
+ @NonNull List<String> subDirNames, int userId, int appId, int previousAppId,
+ @NonNull String seInfo, int flags) throws IOException {
+ synchronized (mInstallLock) {
+ ReconcileSdkDataArgs args = mInstaller.buildReconcileSdkDataArgs(volumeUuid,
+ packageName, subDirNames, userId, appId, seInfo,
+ flags);
+ args.previousAppId = previousAppId;
+ try {
+ mInstaller.reconcileSdkData(args);
+ } catch (InstallerException e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+ }
}
private class PackageManagerInternalImpl extends PackageManagerInternalBase {
diff --git a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
index 53a9244837ed..6adf733ddae9 100644
--- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
+++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
@@ -42,8 +42,8 @@ import android.media.tv.interactive.ITvInteractiveAppService;
import android.media.tv.interactive.ITvInteractiveAppServiceCallback;
import android.media.tv.interactive.ITvInteractiveAppSession;
import android.media.tv.interactive.ITvInteractiveAppSessionCallback;
-import android.media.tv.interactive.TvInteractiveAppInfo;
import android.media.tv.interactive.TvInteractiveAppService;
+import android.media.tv.interactive.TvInteractiveAppServiceInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -130,7 +130,7 @@ public class TvInteractiveAppManagerService extends SystemService {
new Intent(TvInteractiveAppService.SERVICE_INTERFACE),
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
userId);
- List<TvInteractiveAppInfo> iAppList = new ArrayList<>();
+ List<TvInteractiveAppServiceInfo> iAppList = new ArrayList<>();
for (ResolveInfo ri : services) {
ServiceInfo si = ri.serviceInfo;
@@ -143,8 +143,8 @@ public class TvInteractiveAppManagerService extends SystemService {
ComponentName component = new ComponentName(si.packageName, si.name);
try {
- TvInteractiveAppInfo info =
- new TvInteractiveAppInfo(mContext, component);
+ TvInteractiveAppServiceInfo info =
+ new TvInteractiveAppServiceInfo(mContext, component);
iAppList.add(info);
} catch (Exception e) {
Slogf.e(TAG, "failed to load TV Interactive App service " + si.name, e);
@@ -154,10 +154,10 @@ public class TvInteractiveAppManagerService extends SystemService {
}
// sort the iApp list by iApp service id
- Collections.sort(iAppList, Comparator.comparing(TvInteractiveAppInfo::getId));
+ Collections.sort(iAppList, Comparator.comparing(TvInteractiveAppServiceInfo::getId));
Map<String, TvInteractiveAppState> iAppMap = new HashMap<>();
ArrayMap<String, Integer> tiasAppCount = new ArrayMap<>(iAppMap.size());
- for (TvInteractiveAppInfo info : iAppList) {
+ for (TvInteractiveAppServiceInfo info : iAppList) {
String iAppServiceId = info.getId();
if (DEBUG) {
Slogf.d(TAG, "add " + iAppServiceId);
@@ -195,7 +195,7 @@ public class TvInteractiveAppManagerService extends SystemService {
for (String iAppServiceId : userState.mIAppMap.keySet()) {
if (!iAppMap.containsKey(iAppServiceId)) {
- TvInteractiveAppInfo info = userState.mIAppMap.get(iAppServiceId).mInfo;
+ TvInteractiveAppServiceInfo info = userState.mIAppMap.get(iAppServiceId).mInfo;
ServiceState serviceState = userState.mServiceStateMap.get(info.getComponent());
if (serviceState != null) {
abortPendingCreateSessionRequestsLocked(serviceState, iAppServiceId, userId);
@@ -283,7 +283,7 @@ public class TvInteractiveAppManagerService extends SystemService {
userState.mCallbacks.finishBroadcast();
}
- private int getInteractiveAppUid(TvInteractiveAppInfo info) {
+ private int getInteractiveAppUid(TvInteractiveAppServiceInfo info) {
try {
return getContext().getPackageManager().getApplicationInfo(
info.getServiceInfo().packageName, 0).uid;
@@ -642,7 +642,7 @@ public class TvInteractiveAppManagerService extends SystemService {
private final class BinderService extends ITvInteractiveAppManager.Stub {
@Override
- public List<TvInteractiveAppInfo> getTvInteractiveAppServiceList(int userId) {
+ public List<TvInteractiveAppServiceInfo> getTvInteractiveAppServiceList(int userId) {
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(),
Binder.getCallingUid(), userId, "getTvInteractiveAppServiceList");
final long identity = Binder.clearCallingIdentity();
@@ -653,7 +653,7 @@ public class TvInteractiveAppManagerService extends SystemService {
mGetServiceListCalled = true;
}
UserState userState = getOrCreateUserStateLocked(resolvedUserId);
- List<TvInteractiveAppInfo> iAppList = new ArrayList<>();
+ List<TvInteractiveAppServiceInfo> iAppList = new ArrayList<>();
for (TvInteractiveAppState state : userState.mIAppMap.values()) {
iAppList.add(state.mInfo);
}
@@ -1738,7 +1738,7 @@ public class TvInteractiveAppManagerService extends SystemService {
private static final class TvInteractiveAppState {
private String mIAppServiceId;
private ComponentName mComponentName;
- private TvInteractiveAppInfo mInfo;
+ private TvInteractiveAppServiceInfo mInfo;
private int mUid;
private int mIAppNumber;
}
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 543e44cce8b6..ffc438834658 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -746,8 +746,9 @@ class ActivityClientController extends IActivityClientController.Stub {
// if it is not already expanding to fullscreen. Otherwise, the arguments will
// be used the next time the activity enters PiP.
final Task rootTask = r.getRootTask();
- rootTask.setPictureInPictureAspectRatio(r.pictureInPictureArgs.getAspectRatio(),
- r.pictureInPictureArgs.getExpandedAspectRatio());
+ rootTask.setPictureInPictureAspectRatio(
+ r.pictureInPictureArgs.getAspectRatioFloat(),
+ r.pictureInPictureArgs.getExpandedAspectRatioFloat());
rootTask.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
}
}
@@ -828,7 +829,7 @@ class ActivityClientController extends IActivityClientController.Stub {
if (params.hasSetAspectRatio()
&& !mService.mWindowManager.isValidPictureInPictureAspectRatio(
- r.mDisplayContent, params.getAspectRatio())) {
+ r.mDisplayContent, params.getAspectRatioFloat())) {
throw new IllegalArgumentException(String.format(caller
+ ": Aspect ratio is too extreme (must be between %f and %f).",
minAspectRatio, maxAspectRatio));
@@ -836,7 +837,7 @@ class ActivityClientController extends IActivityClientController.Stub {
if (mService.mSupportsExpandedPictureInPicture && params.hasSetExpandedAspectRatio()
&& !mService.mWindowManager.isValidExpandedPictureInPictureAspectRatio(
- r.mDisplayContent, params.getExpandedAspectRatio())) {
+ r.mDisplayContent, params.getExpandedAspectRatioFloat())) {
throw new IllegalArgumentException(String.format(caller
+ ": Expanded aspect ratio is not extreme enough (must not be between"
+ " %f and %f).",
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b5312c4de437..988a7c6cde9a 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -3523,8 +3523,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
// Only update the saved args from the args that are set
r.setPictureInPictureParams(params);
- final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
- final float expandedAspectRatio = r.pictureInPictureArgs.getExpandedAspectRatio();
+ final float aspectRatio = r.pictureInPictureArgs.getAspectRatioFloat();
+ final float expandedAspectRatio =
+ r.pictureInPictureArgs.getExpandedAspectRatioFloat();
final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
mRootWindowContainer.moveActivityToPinnedRootTask(r,
null /* launchIntoPipHostActivity */, "enterPictureInPictureMode");
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 597d29f5cd03..d187bd6f3dfd 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -63,8 +63,6 @@ import static com.android.server.wm.TaskFragmentProto.DISPLAY_ID;
import static com.android.server.wm.TaskFragmentProto.MIN_HEIGHT;
import static com.android.server.wm.TaskFragmentProto.MIN_WIDTH;
import static com.android.server.wm.TaskFragmentProto.WINDOW_CONTAINER;
-import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
-import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainerChildProto.TASK_FRAGMENT;
import android.annotation.IntDef;
@@ -2370,8 +2368,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
if (!hasChild()) {
return false;
}
- return isAnimating(TRANSITION | CHILDREN, WindowState.EXIT_ANIMATING_TYPES)
- || inTransition();
+ return isExitAnimationRunningSelfOrChild() || inTransition();
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index dab02dec5f7d..e7b4e834eb5a 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1196,6 +1196,23 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
return false;
}
+ boolean isExitAnimationRunningSelfOrChild() {
+ if (!mTransitionController.isShellTransitionsEnabled()) {
+ return isAnimating(TRANSITION | CHILDREN, WindowState.EXIT_ANIMATING_TYPES);
+ }
+ if (mTransitionController.isCollecting(this)) {
+ return true;
+ }
+
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ WindowContainer child = mChildren.get(i);
+ if (child.isExitAnimationRunningSelfOrChild()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
void sendAppVisibilityToClients() {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowContainer wc = mChildren.get(i);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d5f7a22a3d2b..c50888b5a172 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -119,7 +119,6 @@ import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
-import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
@@ -2503,8 +2502,6 @@ public class WindowManagerService extends IWindowManager.Stub
ProtoLog.v(WM_DEBUG_FOCUS, "Relayout of %s: focusMayChange=%b",
win, focusMayChange);
- result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0;
-
if (DEBUG_LAYOUT) {
Slog.v(TAG_WM, "Relayout complete " + win + ": outFrames=" + outFrames);
}
@@ -2563,8 +2560,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
focusMayChange = true;
win.mAnimatingExit = true;
- } else if (win.mDisplayContent.okToAnimate() && win.isAnimating(TRANSITION | PARENTS,
- WindowState.EXIT_ANIMATING_TYPES)) {
+ } else if (win.mDisplayContent.okToAnimate() && win.isExitAnimationRunningSelfOrParent()) {
// Currently in a hide animation... turn this into
// an exit.
win.mAnimatingExit = true;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f66739293512..60e196c58465 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -134,6 +134,7 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITIO
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_STARTING_REVEAL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainerChildProto.WINDOW;
@@ -2610,8 +2611,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mWmService.mAccessibilityController.onWindowTransition(this, transit);
}
}
- final boolean isAnimating = mAnimatingExit
- || isAnimating(TRANSITION | PARENTS, EXIT_ANIMATING_TYPES);
+ final boolean isAnimating = mAnimatingExit || isExitAnimationRunningSelfOrParent();
final boolean lastWindowIsStartingWindow = startingWindow && mActivityRecord != null
&& mActivityRecord.isLastWindow(this);
// We delay the removal of a window if it has a showing surface that can be used to run
@@ -4977,6 +4977,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return false;
}
+ boolean isExitAnimationRunningSelfOrParent() {
+ return inAppOrRecentsTransition()
+ || isAnimating(0 /* flags */, ANIMATION_TYPE_WINDOW_ANIMATION);
+ }
+
+ boolean isExitAnimationRunningSelfOrChild() {
+ return isAnimating(CHILDREN, ANIMATION_TYPE_WINDOW_ANIMATION);
+ }
+
private boolean shouldFinishAnimatingExit() {
// Exit animation might be applied soon.
if (inTransition()) {
@@ -4988,7 +4997,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return true;
}
// Exit animation is running.
- if (isAnimating(TRANSITION | PARENTS, EXIT_ANIMATING_TYPES)) {
+ if (isExitAnimationRunningSelfOrParent()) {
ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "shouldWaitAnimatingExit: isAnimating: %s",
this);
return false;
@@ -5081,7 +5090,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
boolean handleCompleteDeferredRemoval() {
- if (mRemoveOnExit && !isSelfAnimating(0 /* flags */, EXIT_ANIMATING_TYPES)) {
+ if (mRemoveOnExit && !isSelfAnimating(0 /* flags */, ANIMATION_TYPE_WINDOW_ANIMATION)) {
mRemoveOnExit = false;
removeImmediately();
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index 200b120843cc..ba00beea47cc 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -189,4 +189,9 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
public ParcelableResource getString(String stringId) {
return null;
}
+
+ @Override
+ public boolean shouldAllowBypassingDevicePolicyManagementRoleQualification() {
+ return false;
+ }
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 3d40f48f244d..850fdee0c733 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -18384,14 +18384,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
} else {
preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_DEFAULT);
}
- List<Integer> allowedUids = Arrays.stream(
- preferentialNetworkServiceConfig.getIncludedUids()).boxed().collect(
- Collectors.toList());
- List<Integer> excludedUids = Arrays.stream(
- preferentialNetworkServiceConfig.getExcludedUids()).boxed().collect(
- Collectors.toList());
- preferenceBuilder.setIncludedUids(allowedUids);
- preferenceBuilder.setExcludedUids(excludedUids);
+ preferenceBuilder.setIncludedUids(preferentialNetworkServiceConfig.getIncludedUids());
+ preferenceBuilder.setExcludedUids(preferentialNetworkServiceConfig.getExcludedUids());
preferenceBuilder.setPreferenceEnterpriseId(
preferentialNetworkServiceConfig.getNetworkId());
@@ -18790,4 +18784,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
mInjector.binderWithCleanCallingIdentity(() -> Settings.Secure.putInt(
mContext.getContentResolver(), MANAGED_PROVISIONING_DPC_DOWNLOADED, setTo));
}
+
+ @Override
+ public boolean shouldAllowBypassingDevicePolicyManagementRoleQualification() {
+ Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_ROLE_HOLDERS));
+ return mInjector.binderWithCleanCallingIdentity(() -> {
+ if (mUserManager.getUserCount() > 1) {
+ return false;
+ }
+ AccountManager am = AccountManager.get(mContext);
+ Account[] accounts = am.getAccounts();
+ return accounts.length == 0;
+ });
+ }
}
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 1ebcbe10fae6..8438afcfe5e4 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -4260,14 +4260,11 @@ public class DevicePolicyManagerTest extends DpmTestBase {
dpm.setPreferentialNetworkServiceConfigs(List.of(preferentialNetworkServiceConfigEnabled));
assertThat(dpm.getPreferentialNetworkServiceConfigs().get(0)
.isEnabled()).isTrue();
- List<Integer> includedList = new ArrayList<>();
- includedList.add(1);
- includedList.add(2);
ProfileNetworkPreference preferenceDetails =
new ProfileNetworkPreference.Builder()
.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK)
.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1)
- .setIncludedUids(includedList)
+ .setIncludedUids(new int[]{1, 2})
.build();
List<ProfileNetworkPreference> preferences = new ArrayList<>();
preferences.add(preferenceDetails);
@@ -4295,14 +4292,11 @@ public class DevicePolicyManagerTest extends DpmTestBase {
dpm.setPreferentialNetworkServiceConfigs(List.of(preferentialNetworkServiceConfigEnabled));
assertThat(dpm.getPreferentialNetworkServiceConfigs().get(0)
.isEnabled()).isTrue();
- List<Integer> excludedUids = new ArrayList<>();
- excludedUids.add(1);
- excludedUids.add(2);
ProfileNetworkPreference preferenceDetails =
new ProfileNetworkPreference.Builder()
.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK)
.setPreferenceEnterpriseId(NET_ENTERPRISE_ID_1)
- .setExcludedUids(excludedUids)
+ .setExcludedUids(new int[]{1, 2})
.build();
List<ProfileNetworkPreference> preferences = new ArrayList<>();
preferences.clear();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 25d7334a529c..b4d305bbe4d0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -932,7 +932,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
assertNotNull(o.mChangedInfo);
assertNotNull(o.mChangedInfo.pictureInPictureParams);
- final Rational ratio = o.mChangedInfo.pictureInPictureParams.getAspectRatioRational();
+ final Rational ratio = o.mChangedInfo.pictureInPictureParams.getAspectRatio();
assertEquals(3, ratio.getNumerator());
assertEquals(4, ratio.getDenominator());
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 837cf8b28ff8..cff90bb9b848 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -504,7 +504,12 @@ public class CarrierConfigManager {
/** Control whether users can choose a network operator. */
public static final String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
- /** Used in Cellular Network Settings for preferred network type. */
+ /**
+ * Used in the Preferred Network Types menu to determine if the 2G option is displayed.
+ * Value defaults to false as of Android T to discourage the use of insecure 2G protocols.
+ *
+ * @see #KEY_HIDE_ENABLE_2G
+ */
public static final String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
/**
@@ -8594,7 +8599,7 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL, false);
sDefaults.putBoolean(KEY_MDN_IS_ADDITIONAL_VOICEMAIL_NUMBER_BOOL, false);
sDefaults.putBoolean(KEY_OPERATOR_SELECTION_EXPAND_BOOL, true);
- sDefaults.putBoolean(KEY_PREFER_2G_BOOL, true);
+ sDefaults.putBoolean(KEY_PREFER_2G_BOOL, false);
sDefaults.putBoolean(KEY_4G_ONLY_BOOL, false);
sDefaults.putBoolean(KEY_SHOW_APN_SETTING_CDMA_BOOL, false);
sDefaults.putBoolean(KEY_SHOW_CDMA_CHOICES_BOOL, false);
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index d2a4c3e7197c..3a3b3632dc9b 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -1090,13 +1090,6 @@ public final class DataFailCause {
*/
public static final int NO_RETRY_FAILURE = 0x1000B;
- /**
- * Traffic descriptors in DataCallResponse is empty.
- *
- * @hide
- */
- public static final int NO_TRAFFIC_DESCRIPTORS = 0x1000C;
-
private static final Map<Integer, String> sFailCauseMap;
static {
sFailCauseMap = new HashMap<>();
@@ -1531,7 +1524,6 @@ public final class DataFailCause {
sFailCauseMap.put(SERVICE_TEMPORARILY_UNAVAILABLE, "SERVICE_TEMPORARILY_UNAVAILABLE");
sFailCauseMap.put(REQUEST_NOT_SUPPORTED, "REQUEST_NOT_SUPPORTED");
sFailCauseMap.put(NO_RETRY_FAILURE, "NO_RETRY_FAILURE");
- sFailCauseMap.put(NO_TRAFFIC_DESCRIPTORS, "NO_TRAFFIC_DESCRIPTORS");
}
private DataFailCause() {
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 532679cb6c43..8143da5ad431 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -549,7 +549,6 @@ public class ApnSetting implements Parcelable {
* Returns the profile id to which the APN saved in modem.
*
* @return the profile id of the APN
- * @hide
*/
public int getProfileId() {
return mProfileId;
@@ -558,8 +557,7 @@ public class ApnSetting implements Parcelable {
/**
* Returns if the APN setting is persistent on the modem.
*
- * @return is the APN setting to be set in modem
- * @hide
+ * @return {@code true} if the APN setting is persistent on the modem.
*/
public boolean isPersistent() {
return mPersistent;
diff --git a/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
index fe4453081362..5ffee5638cfa 100644
--- a/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
+++ b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
@@ -32,7 +32,12 @@ import java.util.List;
import java.util.Objects;
/**
- * Provides Qos attributes of an EPS bearer.
+ * Provides QOS attributes of an EPS bearer.
+ *
+ * <p> The dedicated EPS bearer along with QOS is allocated by the LTE network and notified to the
+ * device. The Telephony framework creates the {@link EpsBearerQosSessionAttributes} object which
+ * represents the QOS of the dedicated bearer and notifies the same to applications via
+ * {@link QosCallback}.
*
* {@hide}
*/