Merge "Less confusing error message."
diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
index fab5b5f..ad406a1 100644
--- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
+++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
@@ -158,17 +158,11 @@
boolean mForceAllAppStandbyForSmallBattery;
/**
- * True if the forced app standby feature is enabled in settings
- */
- @GuardedBy("mLock")
- boolean mForcedAppStandbyEnabled;
-
- /**
* A lock-free set of (uid, packageName) pairs in background restricted mode.
*
* <p>
- * It's bascially shadowing the {@link #mRunAnyRestrictedPackages} together with
- * the {@link #mForcedAppStandbyEnabled} - mutations on them would result in copy-on-write.
+ * It's basically shadowing the {@link #mRunAnyRestrictedPackages}, any mutations on it would
+ * result in copy-on-write.
* </p>
*/
volatile Set<Pair<Integer, String>> mBackgroundRestrictedUidPackages = Collections.emptySet();
@@ -200,10 +194,9 @@
int TEMP_EXEMPTION_LIST_CHANGED = 5;
int EXEMPTED_BUCKET_CHANGED = 6;
int FORCE_ALL_CHANGED = 7;
- int FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8;
- int IS_UID_ACTIVE_CACHED = 9;
- int IS_UID_ACTIVE_RAW = 10;
+ int IS_UID_ACTIVE_CACHED = 8;
+ int IS_UID_ACTIVE_RAW = 9;
}
private final StatLogger mStatLogger = new StatLogger(new String[] {
@@ -215,7 +208,6 @@
"TEMP_EXEMPTION_LIST_CHANGED",
"EXEMPTED_BUCKET_CHANGED",
"FORCE_ALL_CHANGED",
- "FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED",
"IS_UID_ACTIVE_CACHED",
"IS_UID_ACTIVE_RAW",
@@ -228,18 +220,10 @@
}
void register() {
- mContext.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED),
- false, this);
-
mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED), false, this);
}
- boolean isForcedAppStandbyEnabled() {
- return injectGetGlobalSettingInt(Settings.Global.FORCED_APP_STANDBY_ENABLED, 1) == 1;
- }
-
boolean isForcedAppStandbyForSmallBatteryEnabled() {
return injectGetGlobalSettingInt(
Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 0) == 1;
@@ -247,21 +231,7 @@
@Override
public void onChange(boolean selfChange, Uri uri) {
- if (Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED).equals(uri)) {
- final boolean enabled = isForcedAppStandbyEnabled();
- synchronized (mLock) {
- if (mForcedAppStandbyEnabled == enabled) {
- return;
- }
- mForcedAppStandbyEnabled = enabled;
- updateBackgroundRestrictedUidPackagesLocked();
- if (DEBUG) {
- Slog.d(TAG, "Forced app standby feature flag changed: "
- + mForcedAppStandbyEnabled);
- }
- }
- mHandler.notifyForcedAppStandbyFeatureFlagChanged();
- } else if (Settings.Global.getUriFor(
+ if (Settings.Global.getUriFor(
Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED).equals(uri)) {
final boolean enabled = isForcedAppStandbyForSmallBatteryEnabled();
synchronized (mLock) {
@@ -515,7 +485,6 @@
mFlagsObserver = new FeatureFlagsObserver();
mFlagsObserver.register();
- mForcedAppStandbyEnabled = mFlagsObserver.isForcedAppStandbyEnabled();
mForceAllAppStandbyForSmallBattery =
mFlagsObserver.isForcedAppStandbyForSmallBatteryEnabled();
mStandbyTracker = new StandbyTracker();
@@ -636,14 +605,10 @@
/**
* Update the {@link #mBackgroundRestrictedUidPackages} upon mutations on
- * {@link #mRunAnyRestrictedPackages} or {@link #mForcedAppStandbyEnabled}.
+ * {@link #mRunAnyRestrictedPackages}.
*/
@GuardedBy("mLock")
private void updateBackgroundRestrictedUidPackagesLocked() {
- if (!mForcedAppStandbyEnabled) {
- mBackgroundRestrictedUidPackages = Collections.emptySet();
- return;
- }
Set<Pair<Integer, String>> fasUidPkgs = new ArraySet<>();
for (int i = 0, size = mRunAnyRestrictedPackages.size(); i < size; i++) {
fasUidPkgs.add(mRunAnyRestrictedPackages.valueAt(i));
@@ -821,13 +786,14 @@
private class MyHandler extends Handler {
private static final int MSG_UID_ACTIVE_STATE_CHANGED = 0;
+ // Unused ids 1, 2.
private static final int MSG_RUN_ANY_CHANGED = 3;
private static final int MSG_ALL_UNEXEMPTED = 4;
private static final int MSG_ALL_EXEMPTION_LIST_CHANGED = 5;
private static final int MSG_TEMP_EXEMPTION_LIST_CHANGED = 6;
private static final int MSG_FORCE_ALL_CHANGED = 7;
private static final int MSG_USER_REMOVED = 8;
- private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 9;
+ // Unused id 9.
private static final int MSG_EXEMPTED_BUCKET_CHANGED = 10;
private static final int MSG_AUTO_RESTRICTED_BUCKET_FEATURE_FLAG_CHANGED = 11;
@@ -867,11 +833,6 @@
obtainMessage(MSG_FORCE_ALL_CHANGED).sendToTarget();
}
- public void notifyForcedAppStandbyFeatureFlagChanged() {
- removeMessages(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED);
- obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget();
- }
-
public void notifyExemptedBucketChanged() {
removeMessages(MSG_EXEMPTED_BUCKET_CHANGED);
obtainMessage(MSG_EXEMPTED_BUCKET_CHANGED).sendToTarget();
@@ -966,22 +927,6 @@
mStatLogger.logDurationStat(Stats.FORCE_ALL_CHANGED, start);
return;
- case MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED:
- // Feature flag for forced app standby changed.
- final boolean unblockAlarms;
- synchronized (mLock) {
- unblockAlarms = !mForcedAppStandbyEnabled;
- }
- for (Listener l : cloneListeners()) {
- l.updateAllJobs();
- if (unblockAlarms) {
- l.unblockAllUnrestrictedAlarms();
- }
- }
- mStatLogger.logDurationStat(
- Stats.FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED, start);
- return;
-
case MSG_USER_REMOVED:
handleUserRemoved(msg.arg1);
return;
@@ -1164,8 +1109,7 @@
// If apps will be put into restricted standby bucket automatically on user-forced
// app standby, instead of blocking alarms completely, let the restricted standby bucket
// policy take care of it.
- return (mForcedAppStandbyEnabled
- && !mActivityManagerInternal.isBgAutoRestrictedBucketFeatureFlagEnabled()
+ return (!mActivityManagerInternal.isBgAutoRestrictedBucketFeatureFlagEnabled()
&& isRunAnyRestrictedLocked(uid, packageName));
}
}
@@ -1210,8 +1154,7 @@
// If apps will be put into restricted standby bucket automatically on user-forced
// app standby, instead of blocking jobs completely, let the restricted standby bucket
// policy take care of it.
- if (mForcedAppStandbyEnabled
- && !mActivityManagerInternal.isBgAutoRestrictedBucketFeatureFlagEnabled()
+ if (!mActivityManagerInternal.isBgAutoRestrictedBucketFeatureFlagEnabled()
&& isRunAnyRestrictedLocked(uid, packageName)) {
return true;
}
@@ -1321,8 +1264,6 @@
pw.println("Current AppStateTracker State:");
pw.increaseIndent();
- pw.println("Forced App Standby Feature enabled: " + mForcedAppStandbyEnabled);
-
pw.print("Force all apps standby: ");
pw.println(isForceAllAppsStandbyEnabled());
@@ -1400,8 +1341,6 @@
synchronized (mLock) {
final long token = proto.start(fieldId);
- proto.write(AppStateTrackerProto.FORCED_APP_STANDBY_FEATURE_ENABLED,
- mForcedAppStandbyEnabled);
proto.write(AppStateTrackerProto.FORCE_ALL_APPS_STANDBY,
isForceAllAppsStandbyEnabled());
proto.write(AppStateTrackerProto.IS_SMALL_BATTERY_DEVICE, isSmallBatteryDevice());
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index e41eb00..37d190d 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -5379,9 +5379,7 @@
@Override
public void unblockAllUnrestrictedAlarms() {
- // Called when:
- // 1. Power exemption list changes,
- // 2. User FAS feature is disabled.
+ // Called when the power exemption list changes.
synchronized (mLock) {
sendAllUnrestrictedPendingBackgroundAlarmsLocked();
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index d99e151..50cafe8 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -8767,6 +8767,7 @@
field public static final int TYPE_DVBC = 4; // 0x4
field public static final int TYPE_DVBS = 5; // 0x5
field public static final int TYPE_DVBT = 6; // 0x6
+ field public static final int TYPE_IPTV = 11; // 0xb
field public static final int TYPE_ISDBS = 7; // 0x7
field public static final int TYPE_ISDBS3 = 8; // 0x8
field public static final int TYPE_ISDBT = 9; // 0x9
@@ -8789,6 +8790,11 @@
method public int getHierarchy();
method public long getInnerFec();
method @NonNull public int[] getInterleaving();
+ method @IntRange(from=0) public int getIptvAverageJitterMillis();
+ method @NonNull public String getIptvContentUrl();
+ method @IntRange(from=0) public long getIptvPacketsLost();
+ method @IntRange(from=0) public long getIptvPacketsReceived();
+ method @IntRange(from=0) public int getIptvWorstJitterMillis();
method public int getIsdbtMode();
method public int getIsdbtPartialReceptionFlag();
method @IntRange(from=0, to=255) @NonNull public int[] getIsdbtSegment();
@@ -8832,6 +8838,11 @@
field public static final int FRONTEND_STATUS_TYPE_GUARD_INTERVAL = 26; // 0x1a
field public static final int FRONTEND_STATUS_TYPE_HIERARCHY = 19; // 0x13
field public static final int FRONTEND_STATUS_TYPE_INTERLEAVINGS = 30; // 0x1e
+ field public static final int FRONTEND_STATUS_TYPE_IPTV_AVERAGE_JITTER_MS = 46; // 0x2e
+ field public static final int FRONTEND_STATUS_TYPE_IPTV_CONTENT_URL = 42; // 0x2a
+ field public static final int FRONTEND_STATUS_TYPE_IPTV_PACKETS_LOST = 43; // 0x2b
+ field public static final int FRONTEND_STATUS_TYPE_IPTV_PACKETS_RECEIVED = 44; // 0x2c
+ field public static final int FRONTEND_STATUS_TYPE_IPTV_WORST_JITTER_MS = 45; // 0x2d
field public static final int FRONTEND_STATUS_TYPE_ISDBT_MODE = 37; // 0x25
field public static final int FRONTEND_STATUS_TYPE_ISDBT_PARTIAL_RECEPTION_FLAG = 38; // 0x26
field public static final int FRONTEND_STATUS_TYPE_ISDBT_SEGMENTS = 31; // 0x1f
@@ -8877,6 +8888,60 @@
field public static final int FRONTEND_STATUS_READINESS_UNSUPPORTED = 4; // 0x4
}
+ public class IptvFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
+ ctor public IptvFrontendSettings(@NonNull byte[], @NonNull byte[], int, int, @NonNull android.media.tv.tuner.frontend.IptvFrontendSettingsFec, int, int, long, @NonNull String);
+ method @NonNull public static android.media.tv.tuner.frontend.IptvFrontendSettings.Builder builder();
+ method @IntRange(from=0) public long getBitrate();
+ method @NonNull public String getContentUrl();
+ method @NonNull @Size(min=4, max=16) public byte[] getDstIpAddress();
+ method public int getDstPort();
+ method @Nullable public android.media.tv.tuner.frontend.IptvFrontendSettingsFec getFec();
+ method public int getIgmp();
+ method public int getProtocol();
+ method @NonNull @Size(min=4, max=16) public byte[] getSrcIpAddress();
+ method public int getSrcPort();
+ method public int getType();
+ field public static final int IGMP_UNDEFINED = 0; // 0x0
+ field public static final int IGMP_V1 = 1; // 0x1
+ field public static final int IGMP_V2 = 2; // 0x2
+ field public static final int IGMP_V3 = 4; // 0x4
+ field public static final int PROTOCOL_RTP = 2; // 0x2
+ field public static final int PROTOCOL_UDP = 1; // 0x1
+ field public static final int PROTOCOL_UNDEFINED = 0; // 0x0
+ }
+
+ public static final class IptvFrontendSettings.Builder {
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings build();
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setBitrate(@IntRange(from=0) long);
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setContentUrl(@NonNull String);
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setDstIpAddress(@NonNull byte[]);
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setDstPort(int);
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setFec(@Nullable android.media.tv.tuner.frontend.IptvFrontendSettingsFec);
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setIgmp(int);
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setProtocol(int);
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setSrcIpAddress(@NonNull byte[]);
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setSrcPort(int);
+ }
+
+ public class IptvFrontendSettingsFec {
+ ctor public IptvFrontendSettingsFec(int, int, int);
+ method @NonNull public static android.media.tv.tuner.frontend.IptvFrontendSettingsFec.Builder builder();
+ method @IntRange(from=0) public int getFecColNum();
+ method @IntRange(from=0) public int getFecRowNum();
+ method public int getFecType();
+ field public static final int FEC_TYPE_COLUMN = 1; // 0x1
+ field public static final int FEC_TYPE_COLUMN_ROW = 4; // 0x4
+ field public static final int FEC_TYPE_ROW = 2; // 0x2
+ field public static final int FEC_TYPE_UNDEFINED = 0; // 0x0
+ }
+
+ public static final class IptvFrontendSettingsFec.Builder {
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettingsFec build();
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettingsFec.Builder setFecColNum(@IntRange(from=0) int);
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettingsFec.Builder setFecRowNum(@IntRange(from=0) int);
+ method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettingsFec.Builder setFecType(int);
+ }
+
public class Isdbs3FrontendCapabilities extends android.media.tv.tuner.frontend.FrontendCapabilities {
method public int getCodeRateCapability();
method public int getModulationCapability();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 70d8e5d..9de424f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -14568,15 +14568,6 @@
"app_auto_restriction_enabled";
/**
- * Feature flag to enable or disable the Forced App Standby feature.
- * Type: int (0 for false, 1 for true)
- * Default: 1
- * @hide
- */
- @Readable
- public static final String FORCED_APP_STANDBY_ENABLED = "forced_app_standby_enabled";
-
- /**
* Whether or not to enable Forced App Standby on small battery devices.
* Type: int (0 for false, 1 for true)
* Default: 0
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 27c2a98..ac920d2 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -1170,6 +1170,11 @@
* in Tuner 2.0 or higher version. Unsupported version will cause no-op. Use {@link
* TunerVersionChecker#getTunerVersion()} to get the version information.
*
+ * <p>Tuning with {@link
+ * android.media.tv.tuner.frontend.IptvFrontendSettings} is only supported
+ * in Tuner 3.0 or higher version. Unsupported version will cause no-op. Use {@link
+ * TunerVersionChecker#getTunerVersion()} to get the version information.
+ *
* @param settings Signal delivery information the frontend uses to
* search and lock the signal.
* @return result status of tune operation.
@@ -1198,6 +1203,12 @@
return RESULT_UNAVAILABLE;
}
}
+ if (mFrontendType == FrontendSettings.TYPE_IPTV) {
+ if (!TunerVersionChecker.checkHigherOrEqualVersionTo(
+ TunerVersionChecker.TUNER_VERSION_3_0, "Tuner with IPTV Frontend")) {
+ return RESULT_UNAVAILABLE;
+ }
+ }
if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, mFrontendLock)) {
mFrontendInfo = null;
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendSettings.java b/media/java/android/media/tv/tuner/frontend/FrontendSettings.java
index 2f45a70..0a1ecee 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/FrontendSettings.java
@@ -38,7 +38,7 @@
/** @hide */
@IntDef(prefix = "TYPE_",
value = {TYPE_UNDEFINED, TYPE_ANALOG, TYPE_ATSC, TYPE_ATSC3, TYPE_DVBC, TYPE_DVBS,
- TYPE_DVBT, TYPE_ISDBS, TYPE_ISDBS3, TYPE_ISDBT, TYPE_DTMB})
+ TYPE_DVBT, TYPE_ISDBS, TYPE_ISDBS3, TYPE_ISDBT, TYPE_DTMB, TYPE_IPTV})
@Retention(RetentionPolicy.SOURCE)
public @interface Type {}
@@ -86,7 +86,10 @@
* Digital Terrestrial Multimedia Broadcast standard (DTMB) frontend type.
*/
public static final int TYPE_DTMB = FrontendType.DTMB;
-
+ /**
+ * Internet Protocol (IPTV) frontend type.
+ */
+ public static final int TYPE_IPTV = FrontendType.IPTV;
/** @hide */
@LongDef(prefix = "FEC_",
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
index 9fbea72..fd677ac 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
+++ b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
@@ -23,6 +23,7 @@
import android.annotation.SystemApi;
import android.media.tv.tuner.Lnb;
import android.media.tv.tuner.TunerVersionChecker;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
@@ -57,7 +58,10 @@
FRONTEND_STATUS_TYPE_IS_MISO_ENABLED, FRONTEND_STATUS_TYPE_IS_LINEAR,
FRONTEND_STATUS_TYPE_IS_SHORT_FRAMES_ENABLED, FRONTEND_STATUS_TYPE_ISDBT_MODE,
FRONTEND_STATUS_TYPE_ISDBT_PARTIAL_RECEPTION_FLAG, FRONTEND_STATUS_TYPE_STREAM_IDS,
- FRONTEND_STATUS_TYPE_DVBT_CELL_IDS, FRONTEND_STATUS_TYPE_ATSC3_ALL_PLP_INFO})
+ FRONTEND_STATUS_TYPE_DVBT_CELL_IDS, FRONTEND_STATUS_TYPE_ATSC3_ALL_PLP_INFO,
+ FRONTEND_STATUS_TYPE_IPTV_CONTENT_URL, FRONTEND_STATUS_TYPE_IPTV_PACKETS_LOST,
+ FRONTEND_STATUS_TYPE_IPTV_PACKETS_RECEIVED, FRONTEND_STATUS_TYPE_IPTV_WORST_JITTER_MS,
+ FRONTEND_STATUS_TYPE_IPTV_AVERAGE_JITTER_MS})
@Retention(RetentionPolicy.SOURCE)
public @interface FrontendStatusType {}
@@ -271,6 +275,36 @@
android.hardware.tv.tuner.FrontendStatusType.DVBT_CELL_IDS;
/**
+ * IPTV content URL.
+ */
+ public static final int FRONTEND_STATUS_TYPE_IPTV_CONTENT_URL =
+ android.hardware.tv.tuner.FrontendStatusType.IPTV_CONTENT_URL;
+
+ /**
+ * IPTV packets lost.
+ */
+ public static final int FRONTEND_STATUS_TYPE_IPTV_PACKETS_LOST =
+ android.hardware.tv.tuner.FrontendStatusType.IPTV_PACKETS_LOST;
+
+ /**
+ * IPTV packets received.
+ */
+ public static final int FRONTEND_STATUS_TYPE_IPTV_PACKETS_RECEIVED =
+ android.hardware.tv.tuner.FrontendStatusType.IPTV_PACKETS_RECEIVED;
+
+ /**
+ * IPTV worst jitter.
+ */
+ public static final int FRONTEND_STATUS_TYPE_IPTV_WORST_JITTER_MS =
+ android.hardware.tv.tuner.FrontendStatusType.IPTV_WORST_JITTER_MS;
+
+ /**
+ * IPTV average jitter.
+ */
+ public static final int FRONTEND_STATUS_TYPE_IPTV_AVERAGE_JITTER_MS =
+ android.hardware.tv.tuner.FrontendStatusType.IPTV_AVERAGE_JITTER_MS;
+
+ /**
* All PLP information in a frequency band for ATSC-3.0 frontend, which includes both tuned and
* not tuned PLPs for currently watching service.
*/
@@ -519,6 +553,11 @@
private int[] mStreamIds;
private int[] mDvbtCellIds;
private Atsc3PlpInfo[] mAllPlpInfo;
+ private String mIptvContentUrl;
+ private Long mIptvPacketsLost;
+ private Long mIptvPacketsReceived;
+ private Integer mIptvWorstJitterMs;
+ private Integer mIptvAverageJitterMs;
// Constructed and fields set by JNI code.
private FrontendStatus() {
@@ -1144,4 +1183,94 @@
return mUec;
}
}
+
+ /**
+ * Gets the IPTV content URL.
+ *
+ * @return A String URL in the format protocol://ip:port (udp://127.0.0.1:3000).
+ *
+ * <p>This query is only supported by Tuner HAL 3.0 or higher. Use
+ * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+ */
+ @NonNull
+ public String getIptvContentUrl() {
+ TunerVersionChecker.checkHigherOrEqualVersionTo(
+ TunerVersionChecker.TUNER_VERSION_3_0, "IptvContentUrl status");
+ if (mIptvContentUrl == null) {
+ throw new IllegalStateException("IptvContentUrl status is empty");
+ }
+ return mIptvContentUrl;
+ }
+
+ /**
+ * Gets the number of packets lost.
+ *
+ * @return A long value representing the number of packets lost in transmission.
+ *
+ * <p>This query is only supported by Tuner HAL 3.0 or higher. Use
+ * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+ */
+ @IntRange(from = 0)
+ public long getIptvPacketsLost() {
+ TunerVersionChecker.checkHigherOrEqualVersionTo(
+ TunerVersionChecker.TUNER_VERSION_3_0, "IptvPacketsLost status");
+ if (mIptvPacketsLost == null) {
+ throw new IllegalStateException("IptvPacketsLost status is empty");
+ }
+ return mIptvPacketsLost;
+ }
+
+ /**
+ * Gets the number of packets received.
+ *
+ * @return A long value representing the number of packets received.
+ *
+ * <p>This query is only supported by Tuner HAL 3.0 or higher. Use
+ * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+ */
+ @IntRange(from = 0)
+ public long getIptvPacketsReceived() {
+ TunerVersionChecker.checkHigherOrEqualVersionTo(
+ TunerVersionChecker.TUNER_VERSION_3_0, "IptvPacketsReceived status");
+ if (mIptvPacketsReceived == null) {
+ throw new IllegalStateException("IptvPacketsReceived status is empty");
+ }
+ return mIptvPacketsReceived;
+ }
+
+ /**
+ * Gets the worst jitter.
+ *
+ * @return An integer representing worst jitter recorded (in milliseconds).
+ *
+ * <p>This query is only supported by Tuner HAL 3.0 or higher. Use
+ * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+ */
+ @IntRange(from = 0)
+ public int getIptvWorstJitterMillis() {
+ TunerVersionChecker.checkHigherOrEqualVersionTo(
+ TunerVersionChecker.TUNER_VERSION_3_0, "IptvWorstJitterMs status");
+ if (mIptvWorstJitterMs == null) {
+ throw new IllegalStateException("IptvWorstJitterMs status is empty");
+ }
+ return mIptvWorstJitterMs;
+ }
+
+ /**
+ * Gets the average jitter.
+ *
+ * @return An integer representing average jitter recorded (in milliseconds).
+ *
+ * <p>This query is only supported by Tuner HAL 3.0 or higher. Use
+ * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+ */
+ @IntRange(from = 0)
+ public int getIptvAverageJitterMillis() {
+ TunerVersionChecker.checkHigherOrEqualVersionTo(
+ TunerVersionChecker.TUNER_VERSION_3_0, "IptvAverageJitterMs status");
+ if (mIptvAverageJitterMs == null) {
+ throw new IllegalStateException("IptvAverageJitterMs status is empty");
+ }
+ return mIptvAverageJitterMs;
+ }
}
diff --git a/media/java/android/media/tv/tuner/frontend/IptvFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/IptvFrontendSettings.java
new file mode 100644
index 0000000..fb11ea9
--- /dev/null
+++ b/media/java/android/media/tv/tuner/frontend/IptvFrontendSettings.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2023 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.Size;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.FrontendIptvSettingsIgmp;
+import android.hardware.tv.tuner.FrontendIptvSettingsProtocol;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for IPTV.
+ *
+ * @hide
+ */
+@SystemApi
+public class IptvFrontendSettings extends FrontendSettings {
+ /** @hide */
+ @IntDef(prefix = "PROTOCOL_",
+ value = {PROTOCOL_UNDEFINED, PROTOCOL_UDP, PROTOCOL_RTP})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Protocol {}
+
+ /**
+ * IP protocol type UNDEFINED.
+ */
+ public static final int PROTOCOL_UNDEFINED = FrontendIptvSettingsProtocol.UNDEFINED;
+
+ /**
+ * IP protocol type UDP (User Datagram Protocol).
+ */
+ public static final int PROTOCOL_UDP = FrontendIptvSettingsProtocol.UDP;
+
+ /**
+ * IP protocol type RTP (Real-time Transport Protocol).
+ */
+ public static final int PROTOCOL_RTP = FrontendIptvSettingsProtocol.RTP;
+
+ /** @hide */
+ @IntDef(prefix = "IGMP_",
+ value = {IGMP_UNDEFINED, IGMP_V1, IGMP_V2, IGMP_V3})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Igmp {}
+
+ /**
+ * IGMP (Internet Group Management Protocol) UNDEFINED.
+ */
+ public static final int IGMP_UNDEFINED = FrontendIptvSettingsIgmp.UNDEFINED;
+
+ /**
+ * IGMP (Internet Group Management Protocol) V1.
+ */
+ public static final int IGMP_V1 = FrontendIptvSettingsIgmp.V1;
+
+ /**
+ * IGMP (Internet Group Management Protocol) V2.
+ */
+ public static final int IGMP_V2 = FrontendIptvSettingsIgmp.V2;
+
+ /**
+ * IGMP (Internet Group Management Protocol) V3.
+ */
+ public static final int IGMP_V3 = FrontendIptvSettingsIgmp.V3;
+
+ private final byte[] mSrcIpAddress;
+ private final byte[] mDstIpAddress;
+ private final int mSrcPort;
+ private final int mDstPort;
+ private final IptvFrontendSettingsFec mFec;
+ private final int mProtocol;
+ private final int mIgmp;
+ private final long mBitrate;
+ private final String mContentUrl;
+
+ public IptvFrontendSettings(@NonNull byte[] srcIpAddress, @NonNull byte[] dstIpAddress,
+ int srcPort, int dstPort, @NonNull IptvFrontendSettingsFec fec, int protocol, int igmp,
+ long bitrate, @NonNull String contentUrl) {
+ super(0);
+ mSrcIpAddress = srcIpAddress;
+ mDstIpAddress = dstIpAddress;
+ mSrcPort = srcPort;
+ mDstPort = dstPort;
+ mFec = fec;
+ mProtocol = protocol;
+ mIgmp = igmp;
+ mBitrate = bitrate;
+ mContentUrl = contentUrl;
+ }
+
+ /**
+ * Gets the source IP address.
+ */
+ @Size(min = 4, max = 16)
+ @NonNull
+ public byte[] getSrcIpAddress() {
+ return mSrcIpAddress;
+ }
+
+ /**
+ * Gets the destination IP address.
+ */
+ @Size(min = 4, max = 16)
+ @NonNull
+ public byte[] getDstIpAddress() {
+ return mDstIpAddress;
+ }
+
+ /**
+ * Gets the source port.
+ */
+ public int getSrcPort() {
+ return mSrcPort;
+ }
+
+ /**
+ * Gets the destination port.
+ */
+ public int getDstPort() {
+ return mDstPort;
+ }
+
+ /**
+ * Gets FEC (Forward Error Correction).
+ */
+ @Nullable
+ public IptvFrontendSettingsFec getFec() {
+ return mFec;
+ }
+
+ /**
+ * Gets the protocol.
+ */
+ @Protocol
+ public int getProtocol() {
+ return mProtocol;
+ }
+
+ /**
+ * Gets the IGMP (Internet Group Management Protocol).
+ */
+ @Igmp
+ public int getIgmp() {
+ return mIgmp;
+ }
+
+ /**
+ * Gets the bitrate.
+ */
+ @IntRange(from = 0)
+ public long getBitrate() {
+ return mBitrate;
+ }
+
+ /**
+ * Gets the contentUrl
+ * contentUrl is a source URL in the format protocol://ip:port containing data
+ */
+ @NonNull
+ public String getContentUrl() {
+ return mContentUrl;
+ }
+
+ /**
+ * Creates a builder for {@link IptvFrontendSettings}.
+ */
+ @NonNull
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder for {@link IptvFrontendSettings}.
+ */
+ public static final class Builder {
+ private byte[] mSrcIpAddress = {0, 0, 0, 0};
+ private byte[] mDstIpAddress = {0, 0, 0, 0};
+ private int mSrcPort = 0;
+ private int mDstPort = 0;
+ private IptvFrontendSettingsFec mFec = null;
+ private int mProtocol = FrontendIptvSettingsProtocol.UNDEFINED;
+ private int mIgmp = FrontendIptvSettingsIgmp.UNDEFINED;
+ private long mBitrate = 0;
+ private String mContentUrl = "";
+
+ private Builder() {
+ }
+
+ /**
+ * Sets the source IP address.
+ *
+ * <p>Default value is 0.0.0.0, an invalid IP address.
+ */
+ @NonNull
+ public Builder setSrcIpAddress(@NonNull byte[] srcIpAddress) {
+ mSrcIpAddress = srcIpAddress;
+ return this;
+ }
+
+ /**
+ * Sets the destination IP address.
+ *
+ * <p>Default value is 0.0.0.0, an invalid IP address.
+ */
+ @NonNull
+ public Builder setDstIpAddress(@NonNull byte[] dstIpAddress) {
+ mDstIpAddress = dstIpAddress;
+ return this;
+ }
+
+ /**
+ * Sets the source IP port.
+ *
+ * <p>Default value is 0.
+ */
+ @NonNull
+ public Builder setSrcPort(int srcPort) {
+ mSrcPort = srcPort;
+ return this;
+ }
+
+ /**
+ * Sets the destination IP port.
+ *
+ * <p>Default value is 0.
+ */
+ @NonNull
+ public Builder setDstPort(int dstPort) {
+ mDstPort = dstPort;
+ return this;
+ }
+
+ /**
+ * Sets the FEC (Forward Error Correction).
+ *
+ * <p>Default value is {@code null}.
+ */
+ @NonNull
+ public Builder setFec(@Nullable IptvFrontendSettingsFec fec) {
+ mFec = fec;
+ return this;
+ }
+
+ /**
+ * Sets the protocol.
+ *
+ * <p>Default value is {@link #PROTOCOL_UNDEFINED}.
+ */
+ @NonNull
+ public Builder setProtocol(@Protocol int protocol) {
+ mProtocol = protocol;
+ return this;
+ }
+
+ /**
+ * Sets the IGMP (Internet Group Management Protocol).
+ *
+ * <p>Default value is {@link #IGMP_UNDEFINED}.
+ */
+ @NonNull
+ public Builder setIgmp(@Igmp int igmp) {
+ mIgmp = igmp;
+ return this;
+ }
+
+ /**
+ * Sets the bitrate.
+ *
+ * <p>Default value is 0.
+ */
+ @NonNull
+ public Builder setBitrate(@IntRange(from = 0) long bitrate) {
+ mBitrate = bitrate;
+ return this;
+ }
+
+ /**
+ * Sets the contentUrl.
+ *
+ * <p>Default value is "".
+ */
+ @NonNull
+ public Builder setContentUrl(@NonNull String contentUrl) {
+ mContentUrl = contentUrl;
+ return this;
+ }
+
+ /**
+ * Builds a {@link IptvFrontendSettings} object.
+ */
+ @NonNull
+ public IptvFrontendSettings build() {
+ return new IptvFrontendSettings(mSrcIpAddress, mDstIpAddress, mSrcPort,
+ mDstPort, mFec, mProtocol, mIgmp, mBitrate, mContentUrl);
+ }
+ }
+
+ @Override
+ public int getType() {
+ return FrontendSettings.TYPE_IPTV;
+ }
+}
diff --git a/media/java/android/media/tv/tuner/frontend/IptvFrontendSettingsFec.java b/media/java/android/media/tv/tuner/frontend/IptvFrontendSettingsFec.java
new file mode 100644
index 0000000..699d615
--- /dev/null
+++ b/media/java/android/media/tv/tuner/frontend/IptvFrontendSettingsFec.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2023 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.FrontendIptvSettingsFecType;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * FEC (Forward Error Correction) for IPTV.
+ *
+ * @hide
+ */
+@SystemApi
+public class IptvFrontendSettingsFec {
+ /** @hide */
+ @IntDef(prefix = "FEC_TYPE_",
+ value = {FEC_TYPE_UNDEFINED, FEC_TYPE_COLUMN, FEC_TYPE_ROW, FEC_TYPE_COLUMN_ROW})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FecType {}
+
+ /**
+ * FEC (Forward Error Correction) type UNDEFINED.
+ */
+ public static final int FEC_TYPE_UNDEFINED = FrontendIptvSettingsFecType.UNDEFINED;
+
+ /**
+ * FEC (Forward Error Correction) type Column.
+ */
+ public static final int FEC_TYPE_COLUMN = FrontendIptvSettingsFecType.COLUMN;
+
+ /**
+ * FEC (Forward Error Correction) type ROW.
+ */
+ public static final int FEC_TYPE_ROW = FrontendIptvSettingsFecType.ROW;
+
+ /**
+ * FEC (Forward Error Correction) type Column Row.
+ */
+ public static final int FEC_TYPE_COLUMN_ROW = FrontendIptvSettingsFecType.COLUMN_ROW;
+
+ private final int mFecType;
+ private final int mFecRowNum;
+ private final int mFecColNum;
+
+ public IptvFrontendSettingsFec(@FecType int fecType, int fecRowNum, int fecColNum) {
+ mFecType = fecType;
+ mFecRowNum = fecRowNum;
+ mFecColNum = fecColNum;
+ }
+
+ /**
+ * Gets the FEC (Forward Error Correction) type.
+ */
+ @FecType
+ public int getFecType() {
+ return mFecType;
+ }
+
+ /**
+ * Get the FEC (Forward Error Correction) row number.
+ */
+ @IntRange(from = 0)
+ public int getFecRowNum() {
+ return mFecRowNum;
+ }
+
+ /**
+ * Gets the FEC (Forward Error Correction) column number.
+ */
+ @IntRange(from = 0)
+ public int getFecColNum() {
+ return mFecColNum;
+ }
+
+ /**
+ * Creates a builder for {@link IptvFrontendSettingsFec}.
+ */
+ @NonNull
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder for {@link IptvFrontendSettingsFec}.
+ */
+ public static final class Builder {
+ private int mFecType;
+ private int mFecRowNum;
+ private int mFecColNum;
+
+ private Builder() {
+ }
+
+ /**
+ * Sets the FEC (Forward Error Correction) type
+ */
+ @NonNull
+ public Builder setFecType(@FecType int fecType) {
+ mFecType = fecType;
+ return this;
+ }
+ /**
+ * Sets the FEC (Forward Error Correction) row number.
+ */
+ @NonNull
+ public Builder setFecRowNum(@IntRange(from = 0) int fecRowNum) {
+ mFecRowNum = fecRowNum;
+ return this;
+ }
+ /**
+ * Sets the FEC (Forward Error Correction) column number.
+ */
+ @NonNull
+ public Builder setFecColNum(@IntRange(from = 0) int fecColNum) {
+ mFecColNum = fecColNum;
+ return this;
+ }
+
+ /**
+ * Builds a {@link IptvFrontendSettingsFec} object.
+ */
+ @NonNull
+ public IptvFrontendSettingsFec build() {
+ return new IptvFrontendSettingsFec(mFecType, mFecRowNum, mFecColNum);
+ }
+ }
+}
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 1a41bc2..35ee3ee9 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -2827,6 +2827,52 @@
env->DeleteLocalRef(plpClazz);
break;
}
+ case FrontendStatus::Tag::iptvContentUrl: {
+ jfieldID field = env->GetFieldID(clazz, "mIptvContentUrl", "Ljava/lang/String;");
+ std::string iptvContentUrl = s.get<FrontendStatus::Tag::iptvContentUrl>();
+ jstring iptvContentUrlUtf8 = env->NewStringUTF(iptvContentUrl.c_str());
+ env->SetObjectField(statusObj, field, iptvContentUrlUtf8);
+ env->DeleteLocalRef(iptvContentUrlUtf8);
+ break;
+ }
+ case FrontendStatus::Tag::iptvPacketsLost: {
+ jfieldID field = env->GetFieldID(clazz, "mIptvPacketsLost", "Ljava/lang/Long;");
+ jobject newLongObj =
+ env->NewObject(longClazz, initLong,
+ s.get<FrontendStatus::Tag::iptvPacketsLost>());
+ env->SetObjectField(statusObj, field, newLongObj);
+ env->DeleteLocalRef(newLongObj);
+ break;
+ }
+ case FrontendStatus::Tag::iptvPacketsReceived: {
+ jfieldID field = env->GetFieldID(clazz, "mIptvPacketsReceived", "Ljava/lang/Long;");
+ jobject newLongObj =
+ env->NewObject(longClazz, initLong,
+ s.get<FrontendStatus::Tag::iptvPacketsReceived>());
+ env->SetObjectField(statusObj, field, newLongObj);
+ env->DeleteLocalRef(newLongObj);
+ break;
+ }
+ case FrontendStatus::Tag::iptvWorstJitterMs: {
+ jfieldID field = env->GetFieldID(clazz, "mIptvWorstJitterMs",
+ "Ljava/lang/Integer;");
+ jobject newIntegerObj =
+ env->NewObject(intClazz, initInt,
+ s.get<FrontendStatus::Tag::iptvWorstJitterMs>());
+ env->SetObjectField(statusObj, field, newIntegerObj);
+ env->DeleteLocalRef(newIntegerObj);
+ break;
+ }
+ case FrontendStatus::Tag::iptvAverageJitterMs: {
+ jfieldID field = env->GetFieldID(clazz, "mIptvAverageJitterMs",
+ "Ljava/lang/Integer;");
+ jobject newIntegerObj =
+ env->NewObject(intClazz, initInt,
+ s.get<FrontendStatus::Tag::iptvAverageJitterMs>());
+ env->SetObjectField(statusObj, field, newIntegerObj);
+ env->DeleteLocalRef(newIntegerObj);
+ break;
+ }
}
}
return statusObj;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index ede69be..75d28d5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -228,9 +228,6 @@
Settings.Global.APP_AUTO_RESTRICTION_ENABLED,
GlobalSettingsProto.App.AUTO_RESTRICTION_ENABLED);
dumpSetting(s, p,
- Settings.Global.FORCED_APP_STANDBY_ENABLED,
- GlobalSettingsProto.App.FORCED_APP_STANDBY_ENABLED);
- dumpSetting(s, p,
Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED,
GlobalSettingsProto.App.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED);
p.end(appToken);
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index db7032e..01740319 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -285,7 +285,6 @@
Settings.Global.FANCY_IME_ANIMATIONS,
Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
- Settings.Global.FORCED_APP_STANDBY_ENABLED,
Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED,
Settings.Global.WIFI_ON_WHEN_PROXY_DISCONNECTED,
Settings.Global.FSTRIM_MANDATORY_INTERVAL,
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index b76de5a..e182a6a 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -24,6 +24,7 @@
android:orientation="vertical">
<LinearLayout
+ android:id="@+id/media_metadata_section"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start|center_vertical"
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 a9e1a4d..4803371 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -95,6 +95,7 @@
private RecyclerView mDevicesRecyclerView;
private LinearLayout mDeviceListLayout;
private LinearLayout mCastAppLayout;
+ private LinearLayout mMediaMetadataSectionLayout;
private Button mDoneButton;
private Button mStopButton;
private Button mAppButton;
@@ -240,6 +241,7 @@
mHeaderSubtitle = mDialogView.requireViewById(R.id.header_subtitle);
mHeaderIcon = mDialogView.requireViewById(R.id.header_icon);
mDevicesRecyclerView = mDialogView.requireViewById(R.id.list_result);
+ mMediaMetadataSectionLayout = mDialogView.requireViewById(R.id.media_metadata_section);
mDeviceListLayout = mDialogView.requireViewById(R.id.device_list);
mDoneButton = mDialogView.requireViewById(R.id.done);
mStopButton = mDialogView.requireViewById(R.id.stop);
@@ -255,21 +257,17 @@
mDevicesRecyclerView.setLayoutManager(mLayoutManager);
mDevicesRecyclerView.setAdapter(mAdapter);
mDevicesRecyclerView.setHasFixedSize(false);
- // Init header icon
- mHeaderIcon.setOnClickListener(v -> onHeaderIconClick());
// Init bottom buttons
mDoneButton.setOnClickListener(v -> dismiss());
mStopButton.setOnClickListener(v -> {
mMediaOutputController.releaseSession();
dismiss();
});
- mAppButton.setOnClickListener(v -> {
- mBroadcastSender.closeSystemDialogs();
- if (mMediaOutputController.getAppLaunchIntent() != null) {
- mContext.startActivity(mMediaOutputController.getAppLaunchIntent());
- }
- dismiss();
- });
+ mAppButton.setOnClickListener(v -> mMediaOutputController.tryToLaunchMediaApplication());
+ if (mMediaOutputController.isAdvancedLayoutSupported()) {
+ mMediaMetadataSectionLayout.setOnClickListener(
+ v -> mMediaOutputController.tryToLaunchMediaApplication());
+ }
}
@Override
@@ -560,7 +558,7 @@
@Override
public void dismissDialog() {
- dismiss();
+ mBroadcastSender.closeSystemDialogs();
}
void onHeaderIconClick() {
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 9cf672b..1587e62 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -382,6 +382,15 @@
return mContext.getPackageManager().getLaunchIntentForPackage(mPackageName);
}
+ void tryToLaunchMediaApplication() {
+ Intent launchIntent = getAppLaunchIntent();
+ if (launchIntent != null) {
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mCallback.dismissDialog();
+ mContext.startActivity(launchIntent);
+ }
+ }
+
CharSequence getHeaderTitle() {
if (mMediaController != null) {
final MediaMetadata metadata = mMediaController.getMetadata();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 094d69a..9a0bd9e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -243,6 +243,13 @@
}
@Test
+ public void dismissDialog_closesDialogByBroadcastSender() {
+ mMediaOutputBaseDialogImpl.dismissDialog();
+
+ verify(mBroadcastSender).closeSystemDialogs();
+ }
+
+ @Test
public void whenBroadcasting_verifyLeBroadcastServiceCallBackIsRegisteredAndUnregistered() {
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
mLocalBluetoothLeBroadcast);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index f5432e2..117751c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -252,6 +252,13 @@
}
@Test
+ public void tryToLaunchMediaApplication_nullIntent_skip() {
+ mMediaOutputController.tryToLaunchMediaApplication();
+
+ verify(mCb, never()).dismissDialog();
+ }
+
+ @Test
public void onDevicesUpdated_unregistersNearbyDevicesCallback() throws RemoteException {
mMediaOutputController.start(mCb);
diff --git a/services/tests/servicestests/src/com/android/server/job/BackgroundRestrictionsTest.java b/services/tests/servicestests/src/com/android/server/job/BackgroundRestrictionsTest.java
index f2e03aa..e871fc5 100644
--- a/services/tests/servicestests/src/com/android/server/job/BackgroundRestrictionsTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/BackgroundRestrictionsTest.java
@@ -37,7 +37,6 @@
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.provider.Settings;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -165,18 +164,6 @@
awaitJobStart(DEFAULT_WAIT_TIMEOUT));
}
- @FlakyTest
- @Test
- public void testFeatureFlag() throws Exception {
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.FORCED_APP_STANDBY_ENABLED, 0);
- scheduleAndAssertJobStarted();
- setAppOpsModeAllowed(false);
- mIActivityManager.makePackageIdle(TEST_APP_PACKAGE, UserHandle.USER_CURRENT);
- assertFalse("Job stopped even when feature flag was disabled",
- awaitJobStop(DEFAULT_WAIT_TIMEOUT, JobParameters.STOP_REASON_UNDEFINED));
- }
-
@After
public void tearDown() throws Exception {
final Intent cancelJobsIntent = new Intent(TestJobActivity.ACTION_CANCEL_JOBS);
@@ -187,8 +174,6 @@
Thread.sleep(500); // To avoid race with register in the next setUp
setAppOpsModeAllowed(true);
setPowerExemption(false);
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.FORCED_APP_STANDBY_ENABLED, 1);
}
private void setPowerExemption(boolean exempt) throws RemoteException {