summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp1
-rw-r--r--core/api/current.txt5
-rw-r--r--core/api/system-current.txt1
-rw-r--r--core/java/android/app/supervision/SupervisionManager.java23
-rw-r--r--core/java/android/os/IHintManager.aidl34
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/res/AndroidManifest.xml10
-rw-r--r--media/java/android/media/MediaRoute2Info.java9
-rw-r--r--native/android/performance_hint.cpp114
-rw-r--r--native/android/tests/performance_hint/PerformanceHintNativeTest.cpp35
-rw-r--r--packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java4
-rw-r--r--packages/SettingsLib/res/values/arrays.xml21
-rw-r--r--packages/SettingsLib/res/values/strings.xml3
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt6
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java20
-rw-r--r--services/core/java/com/android/server/display/BrightnessRangeController.java29
-rw-r--r--services/core/java/com/android/server/display/color/ColorDisplayService.java25
-rw-r--r--services/core/java/com/android/server/display/color/DisplayTransformManager.java6
-rw-r--r--services/core/java/com/android/server/display/feature/DisplayManagerFlags.java10
-rw-r--r--services/core/java/com/android/server/display/feature/display_flags.aconfig8
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java4
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java11
-rw-r--r--services/core/java/com/android/server/media/SystemMediaRoute2Provider.java66
-rw-r--r--services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java137
-rw-r--r--services/core/java/com/android/server/power/hint/HintManagerService.java59
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java18
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java7
-rw-r--r--services/supervision/java/com/android/server/supervision/SupervisionService.java18
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/BrightnessRangeControllerTest.kt8
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java4
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java38
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/color/DisplayTransformManagerTest.java23
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java80
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java53
-rw-r--r--services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java98
38 files changed, 640 insertions, 377 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 45e33ce4b6e9..e40c78c494aa 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -401,6 +401,7 @@ java_aconfig_library {
min_sdk_version: "30",
apex_available: [
"//apex_available:platform",
+ "com.android.tethering",
"com.android.wifi",
],
defaults: ["framework-minus-apex-aconfig-java-defaults"],
diff --git a/core/api/current.txt b/core/api/current.txt
index cfbf9e55c7dc..ca4b2fae2f99 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -98,6 +98,7 @@ package android {
field public static final String DUMP = "android.permission.DUMP";
field public static final String ENFORCE_UPDATE_OWNERSHIP = "android.permission.ENFORCE_UPDATE_OWNERSHIP";
field public static final String EXECUTE_APP_ACTION = "android.permission.EXECUTE_APP_ACTION";
+ field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final String EXECUTE_APP_FUNCTIONS = "android.permission.EXECUTE_APP_FUNCTIONS";
field public static final String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
field public static final String FACTORY_TEST = "android.permission.FACTORY_TEST";
field public static final String FOREGROUND_SERVICE = "android.permission.FOREGROUND_SERVICE";
@@ -8892,8 +8893,8 @@ package android.app.appfunctions {
}
@FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public final class AppFunctionManager {
- method @RequiresPermission(anyOf={"android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED", "android.permission.EXECUTE_APP_FUNCTIONS"}, conditional=true) public void executeAppFunction(@NonNull android.app.appfunctions.ExecuteAppFunctionRequest, @NonNull java.util.concurrent.Executor, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<android.app.appfunctions.ExecuteAppFunctionResponse,android.app.appfunctions.AppFunctionException>);
- method @RequiresPermission(anyOf={"android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED", "android.permission.EXECUTE_APP_FUNCTIONS"}, conditional=true) public void isAppFunctionEnabled(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,java.lang.Exception>);
+ method @RequiresPermission(anyOf={"android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED", android.Manifest.permission.EXECUTE_APP_FUNCTIONS}, conditional=true) public void executeAppFunction(@NonNull android.app.appfunctions.ExecuteAppFunctionRequest, @NonNull java.util.concurrent.Executor, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<android.app.appfunctions.ExecuteAppFunctionResponse,android.app.appfunctions.AppFunctionException>);
+ method @RequiresPermission(anyOf={"android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED", android.Manifest.permission.EXECUTE_APP_FUNCTIONS}, conditional=true) public void isAppFunctionEnabled(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,java.lang.Exception>);
method public void isAppFunctionEnabled(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Boolean,java.lang.Exception>);
method public void setAppFunctionEnabled(@NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,java.lang.Exception>);
field public static final int APP_FUNCTION_STATE_DEFAULT = 0; // 0x0
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index e1d8fb11efb3..0ec438562558 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -150,7 +150,6 @@ package android {
field @FlaggedApi("com.android.window.flags.untrusted_embedding_any_app_permission") public static final String EMBED_ANY_APP_IN_UNTRUSTED_MODE = "android.permission.EMBED_ANY_APP_IN_UNTRUSTED_MODE";
field @FlaggedApi("android.content.pm.emergency_install_permission") public static final String EMERGENCY_INSTALL_PACKAGES = "android.permission.EMERGENCY_INSTALL_PACKAGES";
field public static final String ENTER_CAR_MODE_PRIORITIZED = "android.permission.ENTER_CAR_MODE_PRIORITIZED";
- field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final String EXECUTE_APP_FUNCTIONS = "android.permission.EXECUTE_APP_FUNCTIONS";
field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final String EXECUTE_APP_FUNCTIONS_TRUSTED = "android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED";
field public static final String EXEMPT_FROM_AUDIO_RECORD_RESTRICTIONS = "android.permission.EXEMPT_FROM_AUDIO_RECORD_RESTRICTIONS";
field public static final String FORCE_BACK = "android.permission.FORCE_BACK";
diff --git a/core/java/android/app/supervision/SupervisionManager.java b/core/java/android/app/supervision/SupervisionManager.java
index aee1cd9b4760..a5b58f968c27 100644
--- a/core/java/android/app/supervision/SupervisionManager.java
+++ b/core/java/android/app/supervision/SupervisionManager.java
@@ -16,8 +16,10 @@
package android.app.supervision;
+import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.annotation.UserHandleAware;
+import android.annotation.UserIdInt;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.RemoteException;
@@ -32,9 +34,7 @@ public class SupervisionManager {
private final Context mContext;
private final ISupervisionManager mService;
- /**
- * @hide
- */
+ /** @hide */
@UnsupportedAppUsage
public SupervisionManager(Context context, ISupervisionManager service) {
mContext = context;
@@ -48,8 +48,23 @@ public class SupervisionManager {
*/
@UserHandleAware
public boolean isSupervisionEnabled() {
+ return isSupervisionEnabledForUser(mContext.getUserId());
+ }
+
+ /**
+ * Returns whether the device is supervised.
+ *
+ * <p>The caller must be from the same user as the target or hold the {@link
+ * android.Manifest.permission#INTERACT_ACROSS_USERS} permission.
+ *
+ * @hide
+ */
+ @RequiresPermission(
+ value = android.Manifest.permission.INTERACT_ACROSS_USERS,
+ conditional = true)
+ public boolean isSupervisionEnabledForUser(@UserIdInt int userId) {
try {
- return mService.isSupervisionEnabledForUser(mContext.getUserId());
+ return mService.isSupervisionEnabledForUser(userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/os/IHintManager.aidl b/core/java/android/os/IHintManager.aidl
index 56a089aff78a..4a14a8d0faf8 100644
--- a/core/java/android/os/IHintManager.aidl
+++ b/core/java/android/os/IHintManager.aidl
@@ -21,13 +21,11 @@ import android.os.CpuHeadroomParamsInternal;
import android.os.GpuHeadroomParamsInternal;
import android.os.IHintSession;
import android.os.SessionCreationConfig;
-
-import android.hardware.power.ChannelConfig;
import android.hardware.power.CpuHeadroomResult;
+import android.hardware.power.ChannelConfig;
import android.hardware.power.GpuHeadroomResult;
import android.hardware.power.SessionConfig;
import android.hardware.power.SessionTag;
-import android.hardware.power.SupportInfo;
/** {@hide} */
interface IHintManager {
@@ -42,6 +40,11 @@ interface IHintManager {
IHintSession createHintSessionWithConfig(in IBinder token, in SessionTag tag,
in SessionCreationConfig creationConfig, out SessionConfig config);
+ /**
+ * Get preferred rate limit in nanoseconds.
+ */
+ long getHintSessionPreferredRate();
+
void setHintSessionThreads(in IHintSession hintSession, in int[] tids);
int[] getHintSessionThreadIds(in IHintSession hintSession);
@@ -58,28 +61,13 @@ interface IHintManager {
long getGpuHeadroomMinIntervalMillis();
/**
- * Used by the JNI to pass an interface to the SessionManager;
- * for internal use only.
+ * Get Maximum number of graphics pipeline threads allowed per-app.
*/
- oneway void passSessionManagerBinder(in IBinder sessionManager);
-
- parcelable HintManagerClientData {
- int powerHalVersion;
- int maxGraphicsPipelineThreads;
- long preferredRateNanos;
- SupportInfo supportInfo;
- }
-
- interface IHintManagerClient {
- /**
- * Returns FMQ channel information for the caller, which it associates to the callback binder lifespan.
- */
- oneway void receiveChannelConfig(in ChannelConfig config);
- }
+ int getMaxGraphicsPipelineThreadsCount();
/**
- * Set up an ADPF client, receiving a remote client binder interface and
- * passing back a bundle of support and configuration information.
+ * Used by the JNI to pass an interface to the SessionManager;
+ * for internal use only.
*/
- HintManagerClientData registerClient(in IHintManagerClient client);
+ oneway void passSessionManagerBinder(in IBinder sessionManager);
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c14854023b39..cf0e90fb43ce 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -13710,6 +13710,14 @@ public final class Settings {
"render_shadows_in_compositor";
/**
+ * Policy to be used for the display shade when connected to an external display.
+ * @hide
+ */
+ @Readable
+ public static final String DEVELOPMENT_SHADE_DISPLAY_AWARENESS =
+ "shade_display_awareness";
+
+ /**
* Path to the WindowManager display settings file. If unset, the default file path will
* be used.
*
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 82cad8b3a477..4a948dd91fb0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -8307,20 +8307,21 @@
android:featureFlag="android.app.appfunctions.flags.enable_app_function_manager"
android:protectionLevel="signature" />
- <!-- @SystemApi Allows a trusted application to perform actions on behalf of users inside of
+ <!-- Allows a trusted application to perform actions on behalf of users inside of
applications with privacy guarantees from the system.
<p>This permission is currently only granted to system packages in the
{@link android.app.role.SYSTEM_UI_INTELLIGENCE} role which complies with privacy
requirements outlined in the Android CDD section "9.8.6 Content Capture".
<p>Apps are not able to opt-out from caller having this permission.
<p>Protection level: internal|role
+ @SystemApi
@hide
- @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") -->
+ @FlaggedApi(android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER) -->
<permission android:name="android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED"
android:featureFlag="android.app.appfunctions.flags.enable_app_function_manager"
android:protectionLevel="internal|role" />
- <!-- @SystemApi Allows an application to perform actions on behalf of users inside of
+ <!-- Allows an application to perform actions on behalf of users inside of
applications.
<p>This permission is currently only granted to preinstalled / system apps having the
{@link android.app.role.ASSISTANT} role.
@@ -8328,8 +8329,7 @@
limiting to only callers with {@link android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED}
instead.
<p>Protection level: internal|role
- @hide
- @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") -->
+ @FlaggedApi(android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER) -->
<permission android:name="android.permission.EXECUTE_APP_FUNCTIONS"
android:featureFlag="android.app.appfunctions.flags.enable_app_function_manager"
android:protectionLevel="internal|role" />
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 248efde4902c..bbb03e77c8c9 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -934,6 +934,15 @@ public final class MediaRoute2Info implements Parcelable {
}
/**
+ * Returns whether this route supports {@link #FLAG_ROUTING_TYPE_REMOTE remote routing}.
+ *
+ * @hide
+ */
+ public boolean supportsRemoteRouting() {
+ return (mRoutingTypeFlags & MediaRoute2Info.FLAG_ROUTING_TYPE_REMOTE) != 0;
+ }
+
+ /**
* Returns true if the route info has all of the required field.
* A route is valid if and only if it is obtained from
* {@link com.android.server.media.MediaRouterService}.
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 9257901bcd1f..0db99ffd208a 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -22,7 +22,6 @@
#include <aidl/android/hardware/power/SessionHint.h>
#include <aidl/android/hardware/power/SessionMode.h>
#include <aidl/android/hardware/power/SessionTag.h>
-#include <aidl/android/hardware/power/SupportInfo.h>
#include <aidl/android/hardware/power/WorkDuration.h>
#include <aidl/android/hardware/power/WorkDurationFixedV1.h>
#include <aidl/android/os/IHintManager.h>
@@ -149,36 +148,10 @@ private:
std::future<bool> mChannelCreationFinished;
};
-class SupportInfoWrapper {
-public:
- SupportInfoWrapper(hal::SupportInfo& info);
- bool isSessionModeSupported(hal::SessionMode mode);
- bool isSessionHintSupported(hal::SessionHint hint);
-
-private:
- template <class T>
- bool getEnumSupportFromBitfield(T& enumValue, int64_t& supportBitfield) {
- // extract the bit corresponding to the enum by shifting the bitfield
- // over that much and cutting off any extra values
- return (supportBitfield >> static_cast<int>(enumValue)) % 2;
- }
- hal::SupportInfo mSupportInfo;
-};
-
-class HintManagerClient : public IHintManager::BnHintManagerClient {
-public:
- // Currently a no-op that exists for FMQ init to call in the future
- ndk::ScopedAStatus receiveChannelConfig(const hal::ChannelConfig&) {
- return ndk::ScopedAStatus::ok();
- }
-};
-
struct APerformanceHintManager {
public:
static APerformanceHintManager* getInstance();
- APerformanceHintManager(std::shared_ptr<IHintManager>& service,
- IHintManager::HintManagerClientData&& clientData,
- std::shared_ptr<HintManagerClient> callbackClient);
+ APerformanceHintManager(std::shared_ptr<IHintManager>& service, int64_t preferredRateNanos);
APerformanceHintManager() = delete;
~APerformanceHintManager();
@@ -196,21 +169,29 @@ public:
FMQWrapper& getFMQWrapper();
bool canSendLoadHints(std::vector<hal::SessionHint>& hints, int64_t now) REQUIRES(sHintMutex);
void initJava(JNIEnv* _Nonnull env);
+ ndk::ScopedAIBinder_Weak x;
template <class T>
static void layersFromNativeSurfaces(ANativeWindow** windows, int numWindows,
ASurfaceControl** controls, int numSurfaceControls,
std::vector<T>& out);
- ndk::SpAIBinder& getToken();
- SupportInfoWrapper& getSupportInfo();
private:
+ // Necessary to create an empty binder object
+ static void* tokenStubOnCreate(void*) {
+ return nullptr;
+ }
+ static void tokenStubOnDestroy(void*) {}
+ static binder_status_t tokenStubOnTransact(AIBinder*, transaction_code_t, const AParcel*,
+ AParcel*) {
+ return STATUS_OK;
+ }
+
static APerformanceHintManager* create(std::shared_ptr<IHintManager> iHintManager);
std::shared_ptr<IHintManager> mHintManager;
- std::shared_ptr<HintManagerClient> mCallbackClient;
- IHintManager::HintManagerClientData mClientData;
- SupportInfoWrapper mSupportInfoWrapper;
ndk::SpAIBinder mToken;
+ const int64_t mPreferredRateNanos;
+ std::optional<int32_t> mMaxGraphicsPipelineThreadsCount;
FMQWrapper mFMQWrapper;
double mHintBudget = kMaxLoadHintsPerInterval;
int64_t mLastBudgetReplenish = 0;
@@ -292,27 +273,14 @@ static FMQWrapper& getFMQ() {
return APerformanceHintManager::getInstance()->getFMQWrapper();
}
-// ===================================== SupportInfoWrapper implementation
-
-SupportInfoWrapper::SupportInfoWrapper(hal::SupportInfo& info) : mSupportInfo(info) {}
-
-bool SupportInfoWrapper::isSessionHintSupported(hal::SessionHint hint) {
- return getEnumSupportFromBitfield(hint, mSupportInfo.sessionHints);
-}
-
-bool SupportInfoWrapper::isSessionModeSupported(hal::SessionMode mode) {
- return getEnumSupportFromBitfield(mode, mSupportInfo.sessionModes);
-}
-
// ===================================== APerformanceHintManager implementation
APerformanceHintManager::APerformanceHintManager(std::shared_ptr<IHintManager>& manager,
- IHintManager::HintManagerClientData&& clientData,
- std::shared_ptr<HintManagerClient> callbackClient)
- : mHintManager(std::move(manager)),
- mCallbackClient(callbackClient),
- mClientData(clientData),
- mSupportInfoWrapper(clientData.supportInfo),
- mToken(callbackClient->asBinder()) {
+ int64_t preferredRateNanos)
+ : mHintManager(std::move(manager)), mPreferredRateNanos(preferredRateNanos) {
+ static AIBinder_Class* tokenBinderClass =
+ AIBinder_Class_define("phm_token", tokenStubOnCreate, tokenStubOnDestroy,
+ tokenStubOnTransact);
+ mToken = ndk::SpAIBinder(AIBinder_new(tokenBinderClass, nullptr));
if (mFMQWrapper.isSupported()) {
mFMQWrapper.setToken(mToken);
mFMQWrapper.startChannel(mHintManager.get());
@@ -347,17 +315,16 @@ APerformanceHintManager* APerformanceHintManager::create(std::shared_ptr<IHintMa
ALOGE("%s: PerformanceHint service is not ready ", __FUNCTION__);
return nullptr;
}
- std::shared_ptr<HintManagerClient> client = ndk::SharedRefBase::make<HintManagerClient>();
- IHintManager::HintManagerClientData clientData;
- ndk::ScopedAStatus ret = manager->registerClient(client, &clientData);
+ int64_t preferredRateNanos = -1L;
+ ndk::ScopedAStatus ret = manager->getHintSessionPreferredRate(&preferredRateNanos);
if (!ret.isOk()) {
- ALOGE("%s: PerformanceHint is not supported. %s", __FUNCTION__, ret.getMessage());
+ ALOGE("%s: PerformanceHint cannot get preferred rate. %s", __FUNCTION__, ret.getMessage());
return nullptr;
}
- if (clientData.preferredRateNanos <= 0) {
- clientData.preferredRateNanos = -1L;
+ if (preferredRateNanos <= 0) {
+ preferredRateNanos = -1L;
}
- return new APerformanceHintManager(manager, std::move(clientData), client);
+ return new APerformanceHintManager(manager, preferredRateNanos);
}
bool APerformanceHintManager::canSendLoadHints(std::vector<hal::SessionHint>& hints, int64_t now) {
@@ -422,9 +389,7 @@ APerformanceHintSession* APerformanceHintManager::createSessionUsingConfig(
ALOGE("%s: PerformanceHint cannot create session. %s", __FUNCTION__, ret.getMessage());
return nullptr;
}
-
- auto out = new APerformanceHintSession(mHintManager, std::move(session),
- mClientData.preferredRateNanos,
+ auto out = new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos,
sessionCreationConfig->targetWorkDurationNanos, isJava,
sessionConfig.id == -1
? std::nullopt
@@ -451,11 +416,24 @@ APerformanceHintSession* APerformanceHintManager::getSessionFromJava(JNIEnv* env
}
int64_t APerformanceHintManager::getPreferredRateNanos() const {
- return mClientData.preferredRateNanos;
+ return mPreferredRateNanos;
}
int32_t APerformanceHintManager::getMaxGraphicsPipelineThreadsCount() {
- return mClientData.maxGraphicsPipelineThreads;
+ if (!mMaxGraphicsPipelineThreadsCount.has_value()) {
+ int32_t threadsCount = -1;
+ ndk::ScopedAStatus ret = mHintManager->getMaxGraphicsPipelineThreadsCount(&threadsCount);
+ if (!ret.isOk()) {
+ ALOGE("%s: PerformanceHint cannot get max graphics pipeline threads count. %s",
+ __FUNCTION__, ret.getMessage());
+ return -1;
+ }
+ if (threadsCount <= 0) {
+ threadsCount = -1;
+ }
+ mMaxGraphicsPipelineThreadsCount.emplace(threadsCount);
+ }
+ return mMaxGraphicsPipelineThreadsCount.value();
}
FMQWrapper& APerformanceHintManager::getFMQWrapper() {
@@ -472,14 +450,6 @@ void APerformanceHintManager::initJava(JNIEnv* _Nonnull env) {
mJavaInitialized = true;
}
-ndk::SpAIBinder& APerformanceHintManager::getToken() {
- return mToken;
-}
-
-SupportInfoWrapper& APerformanceHintManager::getSupportInfo() {
- return mSupportInfoWrapper;
-}
-
// ===================================== APerformanceHintSession implementation
constexpr int kNumEnums = enum_size<hal::SessionHint>();
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index e3c10f63abb4..c166e738ffb2 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -56,6 +56,9 @@ public:
const SessionCreationConfig& creationConfig, hal::SessionConfig* config,
std::shared_ptr<IHintSession>* _aidl_return),
(override));
+ MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
+ MOCK_METHOD(ScopedAStatus, getMaxGraphicsPipelineThreadsCount, (int32_t* _aidl_return),
+ (override));
MOCK_METHOD(ScopedAStatus, setHintSessionThreads,
(const std::shared_ptr<IHintSession>& hintSession,
const ::std::vector<int32_t>& tids),
@@ -81,11 +84,6 @@ public:
MOCK_METHOD(ScopedAStatus, getGpuHeadroomMinIntervalMillis, (int64_t* _aidl_return),
(override));
MOCK_METHOD(ScopedAStatus, passSessionManagerBinder, (const SpAIBinder& sessionManager));
- MOCK_METHOD(ScopedAStatus, registerClient,
- (const std::shared_ptr<::aidl::android::os::IHintManager::IHintManagerClient>&
- clientDataIn,
- ::aidl::android::os::IHintManager::HintManagerClientData* _aidl_return),
- (override));
MOCK_METHOD(SpAIBinder, asBinder, (), (override));
MOCK_METHOD(bool, isRemote, (), (override));
};
@@ -127,9 +125,10 @@ public:
APerformanceHintManager* createManager() {
APerformanceHint_setUseFMQForTesting(mUsingFMQ);
- ON_CALL(*mMockIHintManager, registerClient(_, _))
- .WillByDefault(
- DoAll(SetArgPointee<1>(mClientData), [] { return ScopedAStatus::ok(); }));
+ ON_CALL(*mMockIHintManager, getHintSessionPreferredRate(_))
+ .WillByDefault(DoAll(SetArgPointee<0>(123L), [] { return ScopedAStatus::ok(); }));
+ ON_CALL(*mMockIHintManager, getMaxGraphicsPipelineThreadsCount(_))
+ .WillByDefault(DoAll(SetArgPointee<0>(5), [] { return ScopedAStatus::ok(); }));
return APerformanceHint_getManager();
}
@@ -239,20 +238,6 @@ public:
int kMockQueueSize = 20;
bool mUsingFMQ = false;
- IHintManager::HintManagerClientData mClientData{
- .powerHalVersion = 6,
- .maxGraphicsPipelineThreads = 5,
- .preferredRateNanos = 123L,
- .supportInfo{
- .usesSessions = true,
- .boosts = 0,
- .modes = 0,
- .sessionHints = -1,
- .sessionModes = -1,
- .sessionTags = -1,
- },
- };
-
int32_t mMaxLoadHintsPerInterval;
int64_t mLoadHintInterval;
@@ -271,6 +256,12 @@ bool equalsWithoutTimestamp(hal::WorkDuration lhs, hal::WorkDuration rhs) {
lhs.gpuDurationNanos == rhs.gpuDurationNanos && lhs.durationNanos == rhs.durationNanos;
}
+TEST_F(PerformanceHintTest, TestGetPreferredUpdateRateNanos) {
+ APerformanceHintManager* manager = createManager();
+ int64_t preferredUpdateRateNanos = APerformanceHint_getPreferredUpdateRateNanos(manager);
+ EXPECT_EQ(123L, preferredUpdateRateNanos);
+}
+
TEST_F(PerformanceHintTest, TestSession) {
APerformanceHintManager* manager = createManager();
APerformanceHintSession* session = createSession(manager);
diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java
index 63fe1b509751..e173c5e996df 100644
--- a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java
+++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java
@@ -25,13 +25,15 @@ import android.widget.Spinner;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceClickListener;
import androidx.preference.PreferenceViewHolder;
+
import com.android.settingslib.widget.spinner.R;
/**
* This preference uses Spinner & SettingsSpinnerAdapter which provide default layouts for
* both view and drop down view of the Spinner.
*/
-public class SettingsSpinnerPreference extends Preference implements OnPreferenceClickListener {
+public class SettingsSpinnerPreference extends Preference
+ implements OnPreferenceClickListener, GroupSectionDividerMixin {
private SettingsSpinnerAdapter mAdapter;
private AdapterView.OnItemSelectedListener mListener;
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index 5a4d3ce5661b..63c8929ef652 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -667,4 +667,25 @@
<item>3</item>
</string-array>
+ <!-- Options for showing shade on external display for developers -->
+ <string-array name="shade_display_awareness_entries" >
+ <item>Device display only (Default)</item>
+ <item>External display</item>
+ <item>Focus-based</item>
+ </string-array>
+
+ <!-- Options for showing shade on external display for developers -->
+ <string-array name="shade_display_awareness_summaries" >
+ <item>Show shade on device display only </item>
+ <item>Show device on single external display</item>
+ <item>Show device on last focused display</item>
+ </string-array>
+
+ <!-- Values for showing shade on external display for developers -->
+ <string-array name="shade_display_awareness_values" >
+ <item>device-display</item>
+ <item>external-display</item>
+ <item>focus-based</item>
+ </string-array>
+
</resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index eaf155df4785..e1929b725a58 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -990,6 +990,9 @@
<!-- UI debug setting: simulate secondary display devices using overlays [CHAR LIMIT=45] -->
<string name="overlay_display_devices_title">Simulate secondary displays</string>
+ <!-- UI debug setting: shade display awareness title [CHAR LIMIT=45] -->
+ <string name="shade_display_awareness_title">Shade display position</string>
+
<!-- Preference category for application debugging development settings. [CHAR LIMIT=25] -->
<string name="debug_applications_category">Apps</string>
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 9004488c2e12..c88a7fd834d6 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -182,6 +182,7 @@ public class SettingsBackupTest {
Settings.Global.DEVELOPMENT_FORCE_RTL,
Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR,
+ Settings.Global.DEVELOPMENT_SHADE_DISPLAY_AWARENESS,
Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH,
Settings.Global.DEVICE_DEMO_MODE,
Settings.Global.DEVICE_IDLE_CONSTANTS,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
index 5fb9416cf35b..e4f4df386583 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -37,6 +37,7 @@ import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotific
import com.android.systemui.qs.ui.composable.QuickSettings
import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaLandscapeTopOffset
import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaOffset.Default
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.viewmodel.GoneUserActionsViewModel
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
@@ -70,18 +71,22 @@ constructor(
@Composable
override fun SceneScope.Content(modifier: Modifier) {
- val isIdle by remember {
- derivedStateOf { layoutState.transitionState is TransitionState.Idle }
+ val isIdleAndNotOccluded by remember {
+ derivedStateOf {
+ layoutState.transitionState is TransitionState.Idle &&
+ Overlays.NotificationsShade !in layoutState.transitionState.currentOverlays
+ }
}
- LaunchedEffect(isIdle) {
+ LaunchedEffect(isIdleAndNotOccluded) {
// Wait for being Idle on this Scene, otherwise LaunchedEffect would fire too soon,
// and another transition could override the NSSL stack bounds.
- if (isIdle) {
+ if (isIdleAndNotOccluded) {
// Reset the stack bounds to avoid caching these values from the previous Scenes,
// and not to confuse the StackScrollAlgorithm when it displays a HUN over GONE.
notificationStackScrolLView.get().apply {
- setStackTop(0f)
+ // use -headsUpInset to allow HUN translation outside bounds for snoozing
+ setStackTop(-getHeadsUpInset().toFloat())
setStackCutoff(0f)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt
index c5bef99f9307..ef68b4de5291 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt
@@ -109,11 +109,6 @@ constructor(
}
}
launch {
- viewModel.shouldResetStackTop
- .filter { it }
- .collectTraced { view.setStackTop(-(view.getHeadsUpInset().toFloat())) }
- }
- launch {
viewModel.shouldCloseGuts
.filter { it }
.collectTraced { view.closeGutsOnSceneTouch() }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
index 56b335648138..1bb205cbcb61 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
@@ -192,12 +192,6 @@ constructor(
/** Whether we should close any open notification guts. */
val shouldCloseGuts: Flow<Boolean> = stackAppearanceInteractor.shouldCloseGuts
- val shouldResetStackTop: Flow<Boolean> =
- sceneInteractor.transitionState
- .mapNotNull { state -> state is Idle && state.currentScene == Scenes.Gone }
- .distinctUntilChanged()
- .dumpWhileCollecting("shouldResetStackTop")
-
/** Whether the Notification Stack is visibly on the lockscreen scene. */
val isShowingStackOnLockscreen: Flow<Boolean> =
sceneInteractor.transitionState
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index f42641ece09b..aadf6f61956c 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -2840,7 +2840,6 @@ public class OomAdjuster {
return true;
}
}
- capability |= PROCESS_CAPABILITY_CPU_TIME;
}
// Not doing bind OOM management, so treat
// this guy more like a started service.
@@ -3089,7 +3088,6 @@ public class OomAdjuster {
return true;
}
}
- capability |= PROCESS_CAPABILITY_CPU_TIME;
}
}
if (cr.hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)) {
@@ -4243,6 +4241,11 @@ public class OomAdjuster {
!= client.getSetCapability()) {
// The connection might elevate the importance of the service's capabilities.
needDryRun = true;
+ } else if (Flags.useCpuTimeCapability()
+ && (client.getSetCapability() & ~app.getSetCapability()
+ & PROCESS_CAPABILITY_CPU_TIME) != 0) {
+ // The connection might grant PROCESS_CAPABILITY_CPU_TIME to the service.
+ needDryRun = true;
} else if (Flags.unfreezeBindPolicyFix()
&& cr.hasFlag(Context.BIND_WAIVE_PRIORITY
| Context.BIND_ALLOW_OOM_MANAGEMENT)) {
@@ -4290,6 +4293,10 @@ public class OomAdjuster {
&& client.mOptRecord.shouldNotFreeze()) {
// Process has shouldNotFreeze and it could have gotten it from the client.
return true;
+ } else if (Flags.useCpuTimeCapability()
+ && (client.getSetCapability() & app.getSetCapability()
+ & PROCESS_CAPABILITY_CPU_TIME) != 0) {
+ return true;
}
return false;
}
@@ -4309,6 +4316,11 @@ public class OomAdjuster {
&& client.mOptRecord.shouldNotFreeze()
&& !app.mOptRecord.shouldNotFreeze()) {
needDryRun = true;
+ } else if (Flags.useCpuTimeCapability()
+ && (client.getSetCapability() & ~app.getSetCapability()
+ & PROCESS_CAPABILITY_CPU_TIME) != 0) {
+ // The connection might grant PROCESS_CAPABILITY_CPU_TIME to the provider.
+ needDryRun = true;
}
if (needDryRun) {
@@ -4335,6 +4347,10 @@ public class OomAdjuster {
&& client.mOptRecord.shouldNotFreeze()) {
// Process has shouldNotFreeze and it could have gotten it from the client.
return true;
+ } else if (Flags.useCpuTimeCapability()
+ && (client.getSetCapability() & app.getSetCapability()
+ & PROCESS_CAPABILITY_CPU_TIME) != 0) {
+ return true;
}
return false;
diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java
index 83b0801ce87f..50d650855b05 100644
--- a/services/core/java/com/android/server/display/BrightnessRangeController.java
+++ b/services/core/java/com/android/server/display/BrightnessRangeController.java
@@ -37,7 +37,6 @@ class BrightnessRangeController {
private final HdrClamper mHdrClamper;
private final Runnable mModeChangeCallback;
- private final boolean mUseNbmController;
private final boolean mUseHdrClamper;
@@ -62,11 +61,8 @@ class BrightnessRangeController {
mHdrClamper = hdrClamper;
mNormalBrightnessModeController = normalBrightnessModeController;
mUseHdrClamper = flags.isHdrClamperEnabled() && !flags.useNewHdrBrightnessModifier();
- mUseNbmController = flags.isNbmControllerEnabled();
- if (mUseNbmController) {
- mNormalBrightnessModeController.resetNbmData(
- displayDeviceConfig.getLuxThrottlingData());
- }
+ mNormalBrightnessModeController.resetNbmData(
+ displayDeviceConfig.getLuxThrottlingData());
if (flags.useNewHdrBrightnessModifier()) {
// HDR boost is handled by HdrBrightnessModifier and should be disabled in HbmController
mHbmController.disableHdrBoost();
@@ -76,7 +72,6 @@ class BrightnessRangeController {
void dump(PrintWriter pw) {
pw.println("BrightnessRangeController:");
- pw.println(" mUseNormalBrightnessController=" + mUseNbmController);
pw.println(" mUseHdrClamper=" + mUseHdrClamper);
mHbmController.dump(pw);
mNormalBrightnessModeController.dump(pw);
@@ -138,9 +133,7 @@ class BrightnessRangeController {
float getCurrentBrightnessMax() {
// nbmController might adjust maxBrightness only if device does not support HBM or
// hbm is currently not allowed
- if (mUseNbmController
- && (!mHbmController.deviceSupportsHbm()
- || !mHbmController.isHbmCurrentlyAllowed())) {
+ if (!mHbmController.deviceSupportsHbm() || !mHbmController.isHbmCurrentlyAllowed()) {
return Math.min(mHbmController.getCurrentBrightnessMax(),
mNormalBrightnessModeController.getCurrentBrightnessMax());
}
@@ -173,16 +166,12 @@ class BrightnessRangeController {
}
private void applyChanges(BooleanSupplier nbmChangesFunc, Runnable hbmChangesFunc) {
- if (mUseNbmController) {
- boolean nbmTransitionChanged = nbmChangesFunc.getAsBoolean();
- hbmChangesFunc.run();
- // if nbm transition changed - trigger callback
- // HighBrightnessModeController handles sending changes itself
- if (nbmTransitionChanged) {
- mModeChangeCallback.run();
- }
- } else {
- hbmChangesFunc.run();
+ boolean nbmTransitionChanged = nbmChangesFunc.getAsBoolean();
+ hbmChangesFunc.run();
+ // if nbm transition changed - trigger callback
+ // HighBrightnessModeController handles sending changes itself
+ if (nbmTransitionChanged) {
+ mModeChangeCallback.run();
}
}
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 7892639fc8ed..52e64905c984 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -168,8 +168,7 @@ public final class ColorDisplayService extends SystemService {
new NightDisplayTintController();
private final TintController mGlobalSaturationTintController =
new GlobalSaturationTintController();
- private final ReduceBrightColorsTintController mReduceBrightColorsTintController =
- new ReduceBrightColorsTintController();
+ private final ReduceBrightColorsTintController mReduceBrightColorsTintController;
@VisibleForTesting
final Handler mHandler;
@@ -201,7 +200,13 @@ public final class ColorDisplayService extends SystemService {
private boolean mEvenDimmerActivated;
public ColorDisplayService(Context context) {
+ this(context, new ReduceBrightColorsTintController());
+ }
+
+ @VisibleForTesting
+ public ColorDisplayService(Context context, ReduceBrightColorsTintController rbcController) {
super(context);
+ mReduceBrightColorsTintController = rbcController;
mHandler = new TintHandler(DisplayThread.get().getLooper());
mVisibleBackgroundUsersEnabled = isVisibleBackgroundUsersEnabled();
mUserManager = UserManagerService.getInstance();
@@ -571,27 +576,37 @@ public final class ColorDisplayService extends SystemService {
return mColorModeCompositionColorSpaces.get(mode, Display.COLOR_MODE_INVALID);
}
- private void onDisplayColorModeChanged(int mode) {
+ @VisibleForTesting
+ void onDisplayColorModeChanged(int mode) {
if (mode == NOT_SET) {
return;
}
+ mReduceBrightColorsTintController.cancelAnimator();
mNightDisplayTintController.cancelAnimator();
mDisplayWhiteBalanceTintController.cancelAnimator();
+ final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
+
if (mNightDisplayTintController.isAvailable(getContext())) {
- final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
mNightDisplayTintController.setUp(getContext(), dtm.needsLinearColorMatrix(mode));
mNightDisplayTintController
.setMatrix(mNightDisplayTintController.getColorTemperatureSetting());
}
+ if (mReduceBrightColorsTintController.isAvailable(getContext())) {
+ // Different color modes may require different coefficients to be loaded for RBC.
+ // Re-set up RBC so that it can recalculate its transform matrix with new values.
+ mReduceBrightColorsTintController.setUp(getContext(), dtm.needsLinearColorMatrix(mode));
+ onReduceBrightColorsStrengthLevelChanged(); // Trigger matrix recalc + updates
+ }
+
// dtm.setColorMode() needs to be called before
// updateDisplayWhiteBalanceStatus(), this is because the latter calls
// DisplayTransformManager.needsLinearColorMatrix(), therefore it is dependent
// on the state of DisplayTransformManager.
- final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
dtm.setColorMode(mode, mNightDisplayTintController.getMatrix(),
+ mReduceBrightColorsTintController.getMatrix(),
getCompositionColorSpace(mode));
if (mDisplayWhiteBalanceTintController.isAvailable(getContext())) {
diff --git a/services/core/java/com/android/server/display/color/DisplayTransformManager.java b/services/core/java/com/android/server/display/color/DisplayTransformManager.java
index a76c427bec0e..cb7b1773e47e 100644
--- a/services/core/java/com/android/server/display/color/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/color/DisplayTransformManager.java
@@ -265,7 +265,7 @@ public class DisplayTransformManager {
/**
* Sets color mode and updates night display transform values.
*/
- public boolean setColorMode(int colorMode, float[] nightDisplayMatrix,
+ public boolean setColorMode(int colorMode, float[] nightDisplayMatrix, float[] rbcMatrix,
int compositionColorMode) {
if (colorMode == ColorDisplayManager.COLOR_MODE_NATURAL) {
applySaturation(COLOR_SATURATION_NATURAL);
@@ -285,7 +285,11 @@ public class DisplayTransformManager {
setDisplayColor(colorMode, compositionColorMode);
}
+ // These are close to the setDisplayColor() call to reduce delay between
+ // setting these matrixes and updating the color mode. Without this proximity
+ // of calls, updates to color mode can result in flicker.
setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, nightDisplayMatrix);
+ setColorMatrix(LEVEL_COLOR_MATRIX_REDUCE_BRIGHT_COLORS, rbcMatrix);
updateConfiguration();
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index 78bd41bd2e11..85b6bbb40b91 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -46,10 +46,6 @@ public class DisplayManagerFlags {
Flags.FLAG_ENABLE_CONNECTED_DISPLAY_MANAGEMENT,
Flags::enableConnectedDisplayManagement);
- private final FlagState mNbmControllerFlagState = new FlagState(
- Flags.FLAG_ENABLE_NBM_CONTROLLER,
- Flags::enableNbmController);
-
private final FlagState mHdrClamperFlagState = new FlagState(
Flags.FLAG_ENABLE_HDR_CLAMPER,
Flags::enableHdrClamper);
@@ -282,11 +278,6 @@ public class DisplayManagerFlags {
return mConnectedDisplayManagementFlagState.isEnabled();
}
- /** Returns whether NBM Controller is enabled or not. */
- public boolean isNbmControllerEnabled() {
- return mNbmControllerFlagState.isEnabled();
- }
-
/** Returns whether hdr clamper is enabled on not. */
public boolean isHdrClamperEnabled() {
return mHdrClamperFlagState.isEnabled();
@@ -595,7 +586,6 @@ public class DisplayManagerFlags {
pw.println(" " + mExternalDisplayLimitModeState);
pw.println(" " + mDisplayTopology);
pw.println(" " + mHdrClamperFlagState);
- pw.println(" " + mNbmControllerFlagState);
pw.println(" " + mPowerThrottlingClamperFlagState);
pw.println(" " + mEvenDimmerFlagState);
pw.println(" " + mSmallAreaDetectionFlagState);
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 123b7dfbf843..3358f723709c 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -37,14 +37,6 @@ flag {
}
flag {
- name: "enable_nbm_controller"
- namespace: "display_manager"
- description: "Feature flag for Normal Brightness Mode Controller"
- bug: "299527549"
- is_fixed_read_only: true
-}
-
-flag {
name: "enable_hdr_clamper"
namespace: "display_manager"
description: "Feature flag for HDR Clamper"
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
index d8c35358102d..f09be2c15ee0 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
@@ -289,7 +289,9 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider {
// doesn't have any registered discovery preference, we should still be able to route their
// system media.
boolean bindDueToSystemMediaRoutingSupport =
- mIsManagerScanning && mSupportsSystemMediaRouting;
+ mLastDiscoveryPreference != null
+ && mLastDiscoveryPreference.shouldPerformActiveScan()
+ && mSupportsSystemMediaRouting;
if (!getSessionInfos().isEmpty()
|| bindDueToManagerScan
|| bindDueToSystemMediaRoutingSupport) {
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index e18ed410c045..58deffcbd4ba 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -848,7 +848,7 @@ class MediaRouter2ServiceImpl {
UserRecord userRecord = getOrCreateUserRecordLocked(userId);
List<RoutingSessionInfo> sessionInfos;
if (hasSystemRoutingPermissions) {
- if (setDeviceRouteSelected) {
+ if (setDeviceRouteSelected && !Flags.enableMirroringInMediaRouter2()) {
// Return a fake system session that shows the device route as selected and
// available bluetooth routes as transferable.
return userRecord.mHandler.getSystemProvider()
@@ -2733,6 +2733,15 @@ class MediaRouter2ServiceImpl {
newRoutes = Collections.emptySet();
}
+ if (Flags.enableMirroringInMediaRouter2()
+ && provider instanceof MediaRoute2ProviderServiceProxy proxyProvider) {
+ // We notify the system provider of service updates, so that it can update the
+ // system routing session by adding them as transferable routes. And we remove those
+ // that don't support remote routing.
+ mSystemProvider.updateSystemMediaRoutesFromProxy(proxyProvider);
+ newRoutes.removeIf(it -> !it.supportsRemoteRouting());
+ }
+
// Add new routes to the maps.
ArrayList<MediaRoute2Info> addedRoutes = new ArrayList<>();
boolean hasAddedOrModifiedRoutes = false;
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 8dfba39dcfd8..b93846bf9ee7 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -73,6 +73,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
// For apps without MODIFYING_AUDIO_ROUTING permission.
// This should be the currently selected route.
MediaRoute2Info mDefaultRoute;
+
+ @GuardedBy("mLock")
+ RoutingSessionInfo mSystemSessionInfo;
+
RoutingSessionInfo mDefaultSessionInfo;
private final AudioManagerBroadcastReceiver mAudioReceiver =
@@ -180,7 +184,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
if (TextUtils.equals(routeOriginalId, mSelectedRouteId)) {
RoutingSessionInfo currentSessionInfo;
synchronized (mLock) {
- currentSessionInfo = mSessionInfos.get(0);
+ currentSessionInfo =
+ Flags.enableMirroringInMediaRouter2()
+ ? mSystemSessionInfo
+ : mSessionInfos.get(0);
}
mCallback.onSessionCreated(this, requestId, currentSessionInfo);
return;
@@ -354,7 +361,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
}
if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) {
- RoutingSessionInfo oldSessionInfo = mSessionInfos.get(0);
+ var oldSessionInfo =
+ Flags.enableMirroringInMediaRouter2()
+ ? mSystemSessionInfo
+ : mSessionInfos.get(0);
builder.setTransferReason(oldSessionInfo.getTransferReason())
.setTransferInitiator(oldSessionInfo.getTransferInitiatorUserHandle(),
oldSessionInfo.getTransferInitiatorPackageName());
@@ -364,6 +374,31 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
}
}
+ /**
+ * Notifies the system provider of a {@link MediaRoute2ProviderServiceProxy} update.
+ *
+ * <p>To be overridden so as to generate system media routes for {@link
+ * MediaRoute2ProviderService} routes that {@link MediaRoute2Info#supportsSystemMediaRouting()
+ * support system media routing}).
+ *
+ * @param serviceProxy The proxy of the service that updated its state.
+ */
+ public void updateSystemMediaRoutesFromProxy(MediaRoute2ProviderServiceProxy serviceProxy) {
+ // Do nothing. This implementation doesn't support MR2ProviderService system media routes.
+ // The subclass overrides this method to implement app-managed system media routing (aka
+ // mirroring).
+ }
+
+ /**
+ * Called when the system provider state changes.
+ *
+ * <p>To be overridden by {@link SystemMediaRoute2Provider2}, so that app-provided system media
+ * routing routes are added before setting the provider state.
+ */
+ public void onSystemProviderRoutesChanged(MediaRoute2ProviderInfo providerInfo) {
+ setProviderState(providerInfo);
+ }
+
protected void updateProviderState() {
MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder();
@@ -373,7 +408,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
for (MediaRoute2Info route : deviceRoutes) {
builder.addRoute(route);
}
- setProviderState(builder.build());
+ if (!Flags.enableMirroringInMediaRouter2()) {
+ setProviderState(builder.build());
+ }
} else {
builder.addRoute(mDeviceRouteController.getSelectedRoute());
}
@@ -382,7 +419,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
builder.addRoute(route);
}
MediaRoute2ProviderInfo providerInfo = builder.build();
- setProviderState(providerInfo);
+ onSystemProviderRoutesChanged(providerInfo);
if (DEBUG) {
Slog.d(TAG, "Updating system provider info : " + providerInfo);
}
@@ -393,8 +430,12 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
*/
boolean updateSessionInfosIfNeeded() {
synchronized (mLock) {
- RoutingSessionInfo oldSessionInfo = mSessionInfos.isEmpty() ? null : mSessionInfos.get(
- 0);
+ RoutingSessionInfo oldSessionInfo;
+ if (Flags.enableMirroringInMediaRouter2()) {
+ oldSessionInfo = mSystemSessionInfo;
+ } else {
+ oldSessionInfo = mSessionInfos.isEmpty() ? null : mSessionInfos.get(0);
+ }
RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
SYSTEM_SESSION_ID, "" /* clientPackageName */)
@@ -483,8 +524,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
if (DEBUG) {
Slog.d(TAG, "Updating system routing session info : " + newSessionInfo);
}
- mSessionInfos.clear();
- mSessionInfos.add(newSessionInfo);
+ mSystemSessionInfo = newSessionInfo;
+ onSystemSessionInfoUpdated();
mDefaultSessionInfo =
new RoutingSessionInfo.Builder(
SYSTEM_SESSION_ID, "" /* clientPackageName */)
@@ -501,6 +542,12 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
}
}
+ @GuardedBy("mLock")
+ protected void onSystemSessionInfoUpdated() {
+ mSessionInfos.clear();
+ mSessionInfos.add(mSystemSessionInfo);
+ }
+
@GuardedBy("mRequestLock")
private void reportPendingSessionRequestResultLockedIfNeeded(
RoutingSessionInfo newSessionInfo) {
@@ -587,6 +634,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
RoutingSessionInfo sessionInfo;
synchronized (mLock) {
sessionInfo = mSessionInfos.get(0);
+ if (sessionInfo == null) {
+ return;
+ }
}
mCallback.onSessionUpdated(this, sessionInfo);
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java
index 85b30ad8cadb..7dc30ab66fd2 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java
@@ -16,11 +16,26 @@
package com.android.server.media;
+import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO;
+
+import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
+import android.media.MediaRoute2Info;
+import android.media.MediaRoute2ProviderInfo;
import android.media.MediaRoute2ProviderService;
+import android.media.RoutingSessionInfo;
import android.os.Looper;
import android.os.UserHandle;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Stream;
/**
* Extends {@link SystemMediaRoute2Provider} by adding system routes provided by {@link
@@ -30,6 +45,15 @@ import android.os.UserHandle;
*/
/* package */ class SystemMediaRoute2Provider2 extends SystemMediaRoute2Provider {
+ private static final String ROUTE_ID_PREFIX_SYSTEM = "SYSTEM";
+ private static final String ROUTE_ID_SYSTEM_SEPARATOR = ".";
+
+ @GuardedBy("mLock")
+ private MediaRoute2ProviderInfo mLastSystemProviderInfo;
+
+ @GuardedBy("mLock")
+ private final Map<String, ProviderProxyRecord> mProxyRecords = new HashMap<>();
+
private static final ComponentName COMPONENT_NAME =
new ComponentName(
SystemMediaRoute2Provider2.class.getPackage().getName(),
@@ -46,4 +70,117 @@ import android.os.UserHandle;
private SystemMediaRoute2Provider2(Context context, UserHandle user, Looper looper) {
super(context, COMPONENT_NAME, user, looper);
}
+
+ @Override
+ protected void onSystemSessionInfoUpdated() {
+ updateSessionInfo();
+ }
+
+ @Override
+ public void updateSystemMediaRoutesFromProxy(MediaRoute2ProviderServiceProxy serviceProxy) {
+ var proxyRecord = ProviderProxyRecord.createFor(serviceProxy);
+ synchronized (mLock) {
+ if (proxyRecord == null) {
+ mProxyRecords.remove(serviceProxy.mUniqueId);
+ } else {
+ mProxyRecords.put(serviceProxy.mUniqueId, proxyRecord);
+ }
+ setProviderState(buildProviderInfo());
+ }
+ updateSessionInfo();
+ notifyProviderState();
+ notifySessionInfoUpdated();
+ }
+
+ @Override
+ public void onSystemProviderRoutesChanged(MediaRoute2ProviderInfo providerInfo) {
+ synchronized (mLock) {
+ mLastSystemProviderInfo = providerInfo;
+ setProviderState(buildProviderInfo());
+ }
+ updateSessionInfo();
+ notifySessionInfoUpdated();
+ }
+
+ /**
+ * Updates the {@link #mSessionInfos} by expanding the {@link SystemMediaRoute2Provider} session
+ * with information from the {@link MediaRoute2ProviderService provider services}.
+ */
+ private void updateSessionInfo() {
+ synchronized (mLock) {
+ var systemSessionInfo = mSystemSessionInfo;
+ if (systemSessionInfo == null) {
+ // The system session info hasn't been initialized yet. Do nothing.
+ return;
+ }
+ var builder = new RoutingSessionInfo.Builder(systemSessionInfo);
+ mProxyRecords.values().stream()
+ .flatMap(ProviderProxyRecord::getRoutesStream)
+ .map(MediaRoute2Info::getId)
+ .forEach(builder::addTransferableRoute);
+ mSessionInfos.clear();
+ mSessionInfos.add(builder.build());
+ }
+ }
+
+ /**
+ * Returns a new a provider info that includes all routes from the system provider {@link
+ * SystemMediaRoute2Provider}, along with system routes from {@link MediaRoute2ProviderService
+ * provider services}.
+ */
+ @GuardedBy("mLock")
+ private MediaRoute2ProviderInfo buildProviderInfo() {
+ MediaRoute2ProviderInfo.Builder builder =
+ new MediaRoute2ProviderInfo.Builder(mLastSystemProviderInfo);
+ mProxyRecords.values().stream()
+ .flatMap(ProviderProxyRecord::getRoutesStream)
+ .forEach(builder::addRoute);
+ return builder.build();
+ }
+
+ /**
+ * Holds information about {@link MediaRoute2ProviderService provider services} registered in
+ * the system.
+ *
+ * @param mProxy The corresponding {@link MediaRoute2ProviderServiceProxy}.
+ * @param mSystemMediaRoutes The last snapshot of routes from the service that support system
+ * media routing, as defined by {@link MediaRoute2Info#supportsSystemMediaRouting()}.
+ */
+ private record ProviderProxyRecord(
+ MediaRoute2ProviderServiceProxy mProxy,
+ Collection<MediaRoute2Info> mSystemMediaRoutes) {
+
+ /** Returns a stream representation of the {@link #mSystemMediaRoutes}. */
+ public Stream<MediaRoute2Info> getRoutesStream() {
+ return mSystemMediaRoutes.stream();
+ }
+
+ /**
+ * Returns a new instance, or null if the given {@code serviceProxy} doesn't have an
+ * associated {@link MediaRoute2ProviderInfo}.
+ */
+ @Nullable
+ public static ProviderProxyRecord createFor(MediaRoute2ProviderServiceProxy serviceProxy) {
+ MediaRoute2ProviderInfo providerInfo = serviceProxy.getProviderInfo();
+ if (providerInfo == null) {
+ return null;
+ }
+ ArraySet<MediaRoute2Info> routes = new ArraySet<>();
+ providerInfo.getRoutes().stream()
+ .filter(MediaRoute2Info::supportsSystemMediaRouting)
+ .forEach(
+ route -> {
+ String id =
+ ROUTE_ID_PREFIX_SYSTEM
+ + route.getProviderId()
+ + ROUTE_ID_SYSTEM_SEPARATOR
+ + route.getOriginalId();
+ routes.add(
+ new MediaRoute2Info.Builder(id, route.getName())
+ .addFeature(FEATURE_LIVE_AUDIO)
+ .build());
+ });
+ return new ProviderProxyRecord(serviceProxy, Collections.unmodifiableSet(routes));
+ }
+ }
}
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index 51e0195f13fc..7c7504dccf94 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -297,11 +297,7 @@ public final class HintManagerService extends SystemService {
mPowerHalVersion = 0;
mUsesFmq = false;
if (mPowerHal != null) {
- try {
- mSupportInfo = getSupportInfo();
- } catch (RemoteException e) {
- throw new IllegalStateException("Could not contact PowerHAL!", e);
- }
+ mSupportInfo = getSupportInfo();
}
mDefaultCpuHeadroomCalculationWindowMillis =
new CpuHeadroomParamsInternal().calculationWindowMillis;
@@ -319,7 +315,7 @@ public final class HintManagerService extends SystemService {
}
}
- SupportInfo getSupportInfo() throws RemoteException {
+ SupportInfo getSupportInfo() {
try {
mPowerHalVersion = mPowerHal.getInterfaceVersion();
if (mPowerHalVersion >= 6) {
@@ -330,40 +326,9 @@ public final class HintManagerService extends SystemService {
}
SupportInfo supportInfo = new SupportInfo();
- supportInfo.usesSessions = isHintSessionSupported();
- // Global boosts & modes aren't currently relevant for HMS clients
- supportInfo.boosts = 0;
- supportInfo.modes = 0;
- supportInfo.sessionHints = 0;
- supportInfo.sessionModes = 0;
- supportInfo.sessionTags = 0;
-
supportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
supportInfo.headroom.isCpuSupported = false;
supportInfo.headroom.isGpuSupported = false;
- if (isHintSessionSupported()) {
- if (mPowerHalVersion == 4) {
- // Assume we support the V4 hints & modes unless specified
- // otherwise; this is to avoid breaking backwards compat
- // since we historically just assumed they were.
- supportInfo.sessionHints = 31; // first 5 bits are ones
- }
- if (mPowerHalVersion == 5) {
- // Assume we support the V5 hints & modes unless specified
- // otherwise; this is to avoid breaking backwards compat
- // since we historically just assumed they were.
-
- // Hal V5 has 8 modes, all of which it assumes are supported,
- // so we represent that by having the first 8 bits set
- supportInfo.sessionHints = 255; // first 8 bits are ones
- // Hal V5 has 1 mode which it assumes is supported, so we
- // represent that by having the first bit set
- supportInfo.sessionModes = 1;
- // Hal V5 has 5 tags, all of which it assumes are supported,
- // so we represent that by having the first 5 bits set
- supportInfo.sessionTags = 31;
- }
- }
return supportInfo;
}
@@ -1264,7 +1229,7 @@ public final class HintManagerService extends SystemService {
@SessionTag int tag, SessionCreationConfig creationConfig,
SessionConfig config) {
if (!isHintSessionSupported()) {
- throw new UnsupportedOperationException("PowerHintSessions are not supported!");
+ throw new UnsupportedOperationException("PowerHAL is not supported!");
}
java.util.Objects.requireNonNull(token);
@@ -1460,6 +1425,12 @@ public final class HintManagerService extends SystemService {
removeChannelItem(callingTgid, callingUid);
};
+ @Override
+ public long getHintSessionPreferredRate() {
+ return mHintSessionPreferredRate;
+ }
+
+ @Override
public int getMaxGraphicsPipelineThreadsCount() {
return MAX_GRAPHICS_PIPELINE_THREADS_COUNT;
}
@@ -1649,16 +1620,6 @@ public final class HintManagerService extends SystemService {
mSessionManager = ISessionManager.Stub.asInterface(sessionManager);
}
- public IHintManager.HintManagerClientData
- registerClient(@NonNull IHintManager.IHintManagerClient clientBinder) {
- IHintManager.HintManagerClientData out = new IHintManager.HintManagerClientData();
- out.preferredRateNanos = mHintSessionPreferredRate;
- out.maxGraphicsPipelineThreads = getMaxGraphicsPipelineThreadsCount();
- out.powerHalVersion = mPowerHalVersion;
- out.supportInfo = mSupportInfo;
- return out;
- }
-
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
@@ -1666,7 +1627,7 @@ public final class HintManagerService extends SystemService {
}
pw.println("HintSessionPreferredRate: " + mHintSessionPreferredRate);
pw.println("MaxGraphicsPipelineThreadsCount: " + MAX_GRAPHICS_PIPELINE_THREADS_COUNT);
- pw.println("Hint Session Support: " + isHintSessionSupported());
+ pw.println("HAL Support: " + isHintSessionSupported());
pw.println("Active Sessions:");
synchronized (mLock) {
for (int i = 0; i < mActiveSessions.size(); i++) {
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 24a6f118ad04..4bcba13448e9 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -258,16 +258,13 @@ class InsetsPolicy {
* We also need to exclude certain types of insets source for client within specific windowing
* modes.
*
- * @param attrs the LayoutParams of the target
- * @param windowingMode the windowing mode of the target
- * @param isAlwaysOnTop is the target always on top
+ * @param target the target on which the policy is applied
* @param state the input inset state containing all the sources
* @return The state stripped of the necessary information.
*/
- InsetsState enforceInsetsPolicyForTarget(WindowManager.LayoutParams attrs,
- @WindowConfiguration.WindowingMode int windowingMode, boolean isAlwaysOnTop,
- InsetsState state) {
+ InsetsState enforceInsetsPolicyForTarget(WindowState target, InsetsState state) {
final InsetsState originalState = state;
+ final WindowManager.LayoutParams attrs = target.getAttrs();
// The caller should not receive the visible insets provided by itself.
if (attrs.type == TYPE_INPUT_METHOD) {
@@ -316,12 +313,17 @@ class InsetsPolicy {
}
}
+ final @WindowConfiguration.WindowingMode int windowingMode = target.getWindowingMode();
if (WindowConfiguration.isFloating(windowingMode)
- || (windowingMode == WINDOWING_MODE_MULTI_WINDOW && isAlwaysOnTop)) {
+ || (windowingMode == WINDOWING_MODE_MULTI_WINDOW && target.isAlwaysOnTop())) {
// Keep frames, caption, and IME.
int types = WindowInsets.Type.captionBar();
if (windowingMode != WINDOWING_MODE_PINNED) {
- types |= WindowInsets.Type.ime();
+ if (!Flags.refactorInsetsController() || (mDisplayContent != null
+ && target == mDisplayContent.getImeInputTarget()
+ && (WindowInsets.Type.ime() & target.getRequestedVisibleTypes()) != 0)) {
+ types |= WindowInsets.Type.ime();
+ }
}
final InsetsState newState = new InsetsState();
newState.set(state, types);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 90bf053dfbef..68b4b6f0ae91 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1631,8 +1631,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
final InsetsState rawInsetsState =
mFrozenInsetsState != null ? mFrozenInsetsState : getMergedInsetsState();
- final InsetsState insetsStateForWindow = insetsPolicy.enforceInsetsPolicyForTarget(
- mAttrs, getWindowingMode(), isAlwaysOnTop(), rawInsetsState);
+ final InsetsState insetsStateForWindow = insetsPolicy.enforceInsetsPolicyForTarget(this,
+ rawInsetsState);
return insetsPolicy.adjustInsetsForWindow(this, insetsStateForWindow,
includeTransient);
}
@@ -3303,7 +3303,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// just kill it. And if it is a window of foreground activity, the activity can be
// restarted automatically if needed.
Slog.w(TAG, "Exception thrown during dispatchAppVisibility " + this, e);
- if (android.os.Process.getUidForPid(mSession.mPid) == mSession.mUid) {
+ if (android.os.Process.getUidForPid(mSession.mPid) == mSession.mUid
+ && android.os.Process.getThreadGroupLeader(mSession.mPid) == mSession.mPid) {
android.os.Process.killProcess(mSession.mPid);
}
}
diff --git a/services/supervision/java/com/android/server/supervision/SupervisionService.java b/services/supervision/java/com/android/server/supervision/SupervisionService.java
index 0ccaa6043f5f..073ee31ddd60 100644
--- a/services/supervision/java/com/android/server/supervision/SupervisionService.java
+++ b/services/supervision/java/com/android/server/supervision/SupervisionService.java
@@ -16,6 +16,11 @@
package com.android.server.supervision;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import static com.android.internal.util.Preconditions.checkCallAuthorization;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
@@ -31,6 +36,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.os.Binder;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -78,6 +84,9 @@ public class SupervisionService extends ISupervisionManager.Stub {
@Override
public boolean isSupervisionEnabledForUser(@UserIdInt int userId) {
+ if (UserHandle.getUserId(Binder.getCallingUid()) != userId) {
+ enforcePermission(INTERACT_ACROSS_USERS);
+ }
synchronized (getLockObject()) {
return getUserDataLocked(userId).supervisionEnabled;
}
@@ -151,7 +160,8 @@ public class SupervisionService extends ISupervisionManager.Stub {
/** Returns whether the supervision app has profile owner status. */
private boolean isProfileOwner(@UserIdInt int userId) {
- ComponentName profileOwner = mDpmInternal.getProfileOwnerAsUser(userId);
+ ComponentName profileOwner =
+ mDpmInternal != null ? mDpmInternal.getProfileOwnerAsUser(userId) : null;
return profileOwner != null && isSupervisionAppPackage(profileOwner.getPackageName());
}
@@ -161,6 +171,12 @@ public class SupervisionService extends ISupervisionManager.Stub {
mContext.getResources().getString(R.string.config_systemSupervision));
}
+ /** Enforces that the caller has the given permission. */
+ private void enforcePermission(String permission) {
+ checkCallAuthorization(
+ mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED);
+ }
+
public static class Lifecycle extends SystemService {
private final SupervisionService mSupervisionService;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/BrightnessRangeControllerTest.kt b/services/tests/displayservicetests/src/com/android/server/display/BrightnessRangeControllerTest.kt
index f589a2c9385c..7db6ea0bf86d 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/BrightnessRangeControllerTest.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/BrightnessRangeControllerTest.kt
@@ -60,12 +60,6 @@ class BrightnessRangeControllerTest {
}
@Test
- fun testMaxBrightness_HbmDisabledAndNotAllowed() {
- val controller = createController(nbmEnabled = false, hbmAllowed = false)
- assertThat(controller.currentBrightnessMax).isEqualTo(MAX_BRIGHTNESS)
- }
-
- @Test
fun testMaxBrightness_transitionPointLessThanCurrentNbmLimit() {
val controller = createController(
hbmAllowed = false,
@@ -76,13 +70,11 @@ class BrightnessRangeControllerTest {
}
private fun createController(
- nbmEnabled: Boolean = true,
hbmSupported: Boolean = true,
hbmAllowed: Boolean = true,
hbmMaxBrightness: Float = MAX_BRIGHTNESS,
nbmMaxBrightness: Float = NORMAL_BRIGHTNESS_LOW
): BrightnessRangeController {
- whenever(mockFlags.isNbmControllerEnabled).thenReturn(nbmEnabled)
whenever(mockHbmController.deviceSupportsHbm()).thenReturn(hbmSupported)
whenever(mockHbmController.isHbmCurrentlyAllowed).thenReturn(hbmAllowed)
whenever(mockHbmController.currentBrightnessMax).thenReturn(hbmMaxBrightness)
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index 8ca39194de3b..a4dfecb8ed96 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -2626,8 +2626,8 @@ public final class DisplayPowerControllerTest {
mock(ScreenOffBrightnessSensorController.class);
final HighBrightnessModeController hbmController = mock(HighBrightnessModeController.class);
final HdrClamper hdrClamper = mock(HdrClamper.class);
- final NormalBrightnessModeController normalBrightnessModeController = mock(
- NormalBrightnessModeController.class);
+ final NormalBrightnessModeController normalBrightnessModeController =
+ new NormalBrightnessModeController();
BrightnessClamperController clamperController = mock(BrightnessClamperController.class);
when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java
index f391e409a717..4e81b3530b62 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java
@@ -20,10 +20,13 @@ import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -89,6 +92,7 @@ public class ColorDisplayServiceTest {
private ColorDisplayService.BinderService mBinderService;
private Resources mResourcesSpy;
+ private ReduceBrightColorsTintController mRbcSpy;
private static final int[] MINIMAL_COLOR_MODES = new int[] {
ColorDisplayManager.COLOR_MODE_NATURAL,
@@ -135,7 +139,8 @@ public class ColorDisplayServiceTest {
mLocalServiceKeeperRule.overrideLocalService(
DisplayManagerInternal.class, mDisplayManagerInternal);
- mCds = new ColorDisplayService(mContext);
+ mRbcSpy = Mockito.spy(new ReduceBrightColorsTintController());
+ mCds = new ColorDisplayService(mContext, mRbcSpy);
mBinderService = mCds.new BinderService();
mLocalServiceKeeperRule.overrideLocalService(
ColorDisplayService.ColorDisplayServiceInternal.class,
@@ -1106,7 +1111,8 @@ public class ColorDisplayServiceTest {
setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
startService();
verify(mDisplayTransformManager).setColorMode(
- eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(), eq(Display.COLOR_MODE_INVALID));
+ eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(), any(),
+ eq(Display.COLOR_MODE_INVALID));
}
@Test
@@ -1124,7 +1130,8 @@ public class ColorDisplayServiceTest {
setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
startService();
verify(mDisplayTransformManager).setColorMode(
- eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(), eq(Display.COLOR_MODE_INVALID));
+ eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(), any(),
+ eq(Display.COLOR_MODE_INVALID));
}
@Test
@@ -1140,7 +1147,8 @@ public class ColorDisplayServiceTest {
setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
startService();
verify(mDisplayTransformManager).setColorMode(
- eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(), eq(Display.COLOR_MODE_SRGB));
+ eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(), any(),
+ eq(Display.COLOR_MODE_SRGB));
}
@Test
@@ -1156,7 +1164,8 @@ public class ColorDisplayServiceTest {
setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED);
startService();
verify(mDisplayTransformManager).setColorMode(
- eq(ColorDisplayManager.COLOR_MODE_BOOSTED), any(), eq(Display.COLOR_MODE_INVALID));
+ eq(ColorDisplayManager.COLOR_MODE_BOOSTED), any(), any(),
+ eq(Display.COLOR_MODE_INVALID));
}
@Test
@@ -1164,10 +1173,27 @@ public class ColorDisplayServiceTest {
when(mResourcesSpy.getIntArray(R.array.config_availableColorModes))
.thenReturn(new int[] {});
startService();
- verify(mDisplayTransformManager, never()).setColorMode(anyInt(), any(), anyInt());
+ verify(mDisplayTransformManager, never()).setColorMode(anyInt(), any(), any(), anyInt());
assertThat(mBinderService.getColorMode()).isEqualTo(-1);
}
+ @Test
+ public void ensureColorModeChangeTriggersRbcReload() {
+ // should set up RBC once at startup
+ startService();
+ reset(mRbcSpy);
+
+ // Make sure RBC is enabled and available for this test
+ doReturn(true).when(mRbcSpy).isAvailable(mContext);
+
+ // When Color Mode changes, RBC needs to re-setup
+ // onDisplayColorModeChanged cancels animations, and should be called in handler thread
+ mCds.mHandler.runWithScissors(
+ () -> mCds.onDisplayColorModeChanged(ColorDisplayManager.COLOR_MODE_NATURAL),
+ 1000);
+ verify(mRbcSpy, times(1)).setUp(eq(mContext), anyBoolean());
+ }
+
/**
* Configures Night display to use a custom schedule.
*
diff --git a/services/tests/displayservicetests/src/com/android/server/display/color/DisplayTransformManagerTest.java b/services/tests/displayservicetests/src/com/android/server/display/color/DisplayTransformManagerTest.java
index 27f87aae35bb..a7ef5e0afc0e 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/color/DisplayTransformManagerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/color/DisplayTransformManagerTest.java
@@ -19,6 +19,7 @@ package com.android.server.display.color;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
+import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_REDUCE_BRIGHT_COLORS;
import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE;
import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_DISPLAY_COLOR;
import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_SATURATION;
@@ -51,12 +52,14 @@ public class DisplayTransformManagerTest {
private MockitoSession mSession;
private DisplayTransformManager mDtm;
private float[] mNightDisplayMatrix;
+ private float[] mRbcMatrix;
private HashMap<String, String> mSystemProperties;
@Before
public void setUp() {
mDtm = new DisplayTransformManager();
mNightDisplayMatrix = mDtm.getColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY);
+ mRbcMatrix = mDtm.getColorMatrix(LEVEL_COLOR_MATRIX_REDUCE_BRIGHT_COLORS);
mSession = ExtendedMockito.mockitoSession()
.initMocks(this)
@@ -81,7 +84,8 @@ public class DisplayTransformManagerTest {
@Test
public void setColorMode_natural() {
- mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix, -1);
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix, mRbcMatrix,
+ Display.COLOR_MODE_INVALID);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo("0" /* managed */);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -90,7 +94,8 @@ public class DisplayTransformManagerTest {
@Test
public void setColorMode_boosted() {
- mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED, mNightDisplayMatrix, -1);
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED, mNightDisplayMatrix, mRbcMatrix,
+ Display.COLOR_MODE_INVALID);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo("0" /* managed */);
@@ -100,7 +105,8 @@ public class DisplayTransformManagerTest {
@Test
public void setColorMode_saturated() {
- mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED, mNightDisplayMatrix, -1);
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED, mNightDisplayMatrix, mRbcMatrix,
+ Display.COLOR_MODE_INVALID);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo("1" /* unmanaged */);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -109,7 +115,8 @@ public class DisplayTransformManagerTest {
@Test
public void setColorMode_automatic() {
- mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC, mNightDisplayMatrix, -1);
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC, mNightDisplayMatrix, mRbcMatrix,
+ Display.COLOR_MODE_INVALID);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo("2" /* enhanced */);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -118,7 +125,7 @@ public class DisplayTransformManagerTest {
@Test
public void setColorMode_vendor() {
- mDtm.setColorMode(0x100, mNightDisplayMatrix, -1);
+ mDtm.setColorMode(0x100, mNightDisplayMatrix, mRbcMatrix, Display.COLOR_MODE_INVALID);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo(Integer.toString(0x100) /* pass-through */);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -127,7 +134,7 @@ public class DisplayTransformManagerTest {
@Test
public void setColorMode_outOfBounds() {
- mDtm.setColorMode(0x50, mNightDisplayMatrix, -1);
+ mDtm.setColorMode(0x50, mNightDisplayMatrix, mRbcMatrix, Display.COLOR_MODE_INVALID);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
.isEqualTo(null);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -141,7 +148,7 @@ public class DisplayTransformManagerTest {
// Start with a known state, which we expect to remain unmodified
SystemProperties.set(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE, magicPropertyValue);
- mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix,
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix, mRbcMatrix,
Display.COLOR_MODE_INVALID);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE))
.isEqualTo(magicPropertyValue);
@@ -155,7 +162,7 @@ public class DisplayTransformManagerTest {
// Start with a known state, which we expect to get modified
SystemProperties.set(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE, magicPropertyValue);
- mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix,
+ mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix, mRbcMatrix,
testPropertyValue);
assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE))
.isEqualTo(Integer.toString(testPropertyValue));
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 1efe4707fc11..9e96800ca2e9 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -18,6 +18,7 @@ package com.android.server.am;
import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_CPU_TIME;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
@@ -40,6 +41,7 @@ import static android.app.ActivityManager.PROCESS_STATE_TOP_SLEEPING;
import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ACTIVITY;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_NONE;
+import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SHORT_FGS_TIMEOUT;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
@@ -283,6 +285,15 @@ public class MockingOomAdjusterTests {
}
}
+ private static void assertNoCpuTime(ProcessRecord app) {
+ assertEquals(0, app.mState.getSetCapability() & PROCESS_CAPABILITY_CPU_TIME);
+ }
+
+ private static void assertCpuTime(ProcessRecord app) {
+ assertEquals(PROCESS_CAPABILITY_CPU_TIME,
+ app.mState.getSetCapability() & PROCESS_CAPABILITY_CPU_TIME);
+ }
+
private static void assertBfsl(ProcessRecord app) {
assertEquals(PROCESS_CAPABILITY_BFSL,
app.mState.getSetCapability() & PROCESS_CAPABILITY_BFSL);
@@ -661,6 +672,7 @@ public class MockingOomAdjusterTests {
// SHORT_SERVICE, timed out already.
s = ServiceRecord.newEmptyInstanceForTest(mService);
s.appInfo = new ApplicationInfo();
+
mProcessStateController.setStartRequested(s, true);
s.isForeground = true;
s.foregroundServiceType = FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
@@ -687,6 +699,51 @@ public class MockingOomAdjusterTests {
@SuppressWarnings("GuardedBy")
@Test
+ @EnableFlags(Flags.FLAG_USE_CPU_TIME_CAPABILITY)
+ public void testUpdateOomAdjFreezeState_bindingFromShortFgs() {
+ // Setting up a started short FGS within app1.
+ final ServiceRecord s = ServiceRecord.newEmptyInstanceForTest(mService);
+ s.appInfo = new ApplicationInfo();
+ mProcessStateController.setStartRequested(s, true);
+ s.isForeground = true;
+ s.foregroundServiceType = FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
+ mProcessStateController.setShortFgsInfo(s, SystemClock.uptimeMillis());
+
+ final ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ mProcessStateController.setHostProcess(s, app);
+ mProcessStateController.setHasForegroundServices(app.mServices, true,
+ FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false);
+ mProcessStateController.startService(app.mServices, s);
+ app.mState.setLastTopTime(SystemClock.uptimeMillis()
+ - mService.mConstants.TOP_TO_FGS_GRACE_DURATION);
+
+ final ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+ // App1 with short service binds to app2
+ bindService(app2, app, null, null, 0, mock(IBinder.class));
+
+ setProcessesToLru(app, app2);
+ updateOomAdj(app);
+
+ assertCpuTime(app);
+ assertCpuTime(app2);
+
+ // Timeout the short FGS.
+ mProcessStateController.setShortFgsInfo(s, SystemClock.uptimeMillis()
+ - mService.mConstants.mShortFgsTimeoutDuration
+ - mService.mConstants.mShortFgsProcStateExtraWaitDuration);
+ mService.mServices.onShortFgsProcstateTimeout(s);
+ // mService is a mock, but this verifies that the timeout would trigger an update.
+ verify(mService).updateOomAdjLocked(app, OOM_ADJ_REASON_SHORT_FGS_TIMEOUT);
+ updateOomAdj(app);
+
+ assertNoCpuTime(app);
+ assertNoCpuTime(app2);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_DoOne_OverlayUi() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
@@ -3142,11 +3199,19 @@ public class MockingOomAdjusterTests {
assertEquals(true, app.getUidRecord().isSetAllowListed());
assertFreezeState(app, false);
assertFreezeState(app2, false);
+ if (Flags.useCpuTimeCapability()) {
+ assertCpuTime(app);
+ assertCpuTime(app2);
+ }
mProcessStateController.setUidTempAllowlistStateLSP(MOCKAPP_UID, false);
assertEquals(false, app.getUidRecord().isSetAllowListed());
assertFreezeState(app, true);
assertFreezeState(app2, true);
+ if (Flags.useCpuTimeCapability()) {
+ assertNoCpuTime(app);
+ assertNoCpuTime(app2);
+ }
}
@SuppressWarnings("GuardedBy")
@@ -3171,6 +3236,11 @@ public class MockingOomAdjusterTests {
assertFreezeState(app, false);
assertFreezeState(app2, false);
assertFreezeState(app3, false);
+ if (Flags.useCpuTimeCapability()) {
+ assertCpuTime(app);
+ assertCpuTime(app2);
+ assertCpuTime(app3);
+ }
// Remove app1 from allowlist.
mProcessStateController.setUidTempAllowlistStateLSP(MOCKAPP_UID, false);
@@ -3179,6 +3249,11 @@ public class MockingOomAdjusterTests {
assertFreezeState(app, true);
assertFreezeState(app2, false);
assertFreezeState(app3, false);
+ if (Flags.useCpuTimeCapability()) {
+ assertNoCpuTime(app);
+ assertCpuTime(app2);
+ assertCpuTime(app3);
+ }
// Now remove app2 from allowlist.
mProcessStateController.setUidTempAllowlistStateLSP(MOCKAPP2_UID, false);
@@ -3187,6 +3262,11 @@ public class MockingOomAdjusterTests {
assertFreezeState(app, true);
assertFreezeState(app2, true);
assertFreezeState(app3, true);
+ if (Flags.useCpuTimeCapability()) {
+ assertNoCpuTime(app);
+ assertNoCpuTime(app2);
+ assertNoCpuTime(app3);
+ }
}
@SuppressWarnings("GuardedBy")
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java
index 2988c77703b7..7e052dcba3fd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_CPU_TIME;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
@@ -64,6 +65,8 @@ import android.content.pm.ServiceInfo;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
@@ -326,6 +329,7 @@ public final class ServiceBindingOomAdjPolicyTest {
@Test
@RequiresFlagsEnabled(com.android.server.am.Flags.FLAG_UNFREEZE_BIND_POLICY_FIX)
+ @DisableFlags(Flags.FLAG_USE_CPU_TIME_CAPABILITY)
public void testServiceDistinctBindingOomAdjShouldNotFreeze() throws Exception {
// Enable the flags.
mSetFlagsRule.enableFlags(Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY);
@@ -418,6 +422,7 @@ public final class ServiceBindingOomAdjPolicyTest {
@Test
@RequiresFlagsEnabled(com.android.server.am.Flags.FLAG_UNFREEZE_BIND_POLICY_FIX)
+ @DisableFlags(Flags.FLAG_USE_CPU_TIME_CAPABILITY)
public void testServiceDistinctBindingOomAdjAllowOomManagement() throws Exception {
// Enable the flags.
mSetFlagsRule.enableFlags(Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY);
@@ -497,6 +502,7 @@ public final class ServiceBindingOomAdjPolicyTest {
@Test
@RequiresFlagsEnabled(com.android.server.am.Flags.FLAG_UNFREEZE_BIND_POLICY_FIX)
+ @DisableFlags(Flags.FLAG_USE_CPU_TIME_CAPABILITY)
public void testServiceDistinctBindingOomAdjWaivePriority_propagateUnfreeze() throws Exception {
// Enable the flags.
mSetFlagsRule.enableFlags(Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY);
@@ -574,6 +580,50 @@ public final class ServiceBindingOomAdjPolicyTest {
}
@Test
+ @RequiresFlagsEnabled({
+ Flags.FLAG_UNFREEZE_BIND_POLICY_FIX,
+ Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY
+ })
+ @EnableFlags(Flags.FLAG_USE_CPU_TIME_CAPABILITY)
+ public void testServiceDistinctBindingOomAdj_propagateCpuTimeCapability() throws Exception {
+ // Note that PROCESS_CAPABILITY_CPU_TIME is special and should be propagated even when
+ // BIND_INCLUDE_CAPABILITIES is not present.
+ performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
+ PROCESS_STATE_HOME, HOME_APP_ADJ, PROCESS_CAPABILITY_CPU_TIME, TEST_APP1_NAME,
+ this::setHomeProcess,
+ TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_FOREGROUND_SERVICE,
+ PERCEPTIBLE_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
+ this::setHasForegroundServices,
+ BIND_AUTO_CREATE,
+ atLeastOnce(), atLeastOnce());
+
+ // BIND_WAIVE_PRIORITY should not affect propagation of capability CPU_TIME
+ performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
+ PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ, PROCESS_CAPABILITY_CPU_TIME,
+ TEST_APP1_NAME,
+ this::setHasForegroundServices,
+ TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_HOME, HOME_APP_ADJ,
+ PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
+ this::setHomeProcess,
+ BIND_AUTO_CREATE | BIND_WAIVE_PRIORITY,
+ atLeastOnce(), atLeastOnce());
+
+ // If both process have the capability, the bind should not need an update but the unbind
+ // is not safe to skip.
+ // Note that this check can fail on future changes that are not related to
+ // PROCESS_CAPABILITY_CPU_TIME and trigger updates but this is important to ensure
+ // efficiency of OomAdjuster.
+ performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
+ PROCESS_STATE_HOME, HOME_APP_ADJ, PROCESS_CAPABILITY_CPU_TIME, TEST_APP1_NAME,
+ this::setHomeProcess,
+ TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_HOME, HOME_APP_ADJ,
+ PROCESS_CAPABILITY_CPU_TIME, TEST_APP2_NAME, TEST_SERVICE2_NAME,
+ this::setHomeProcess,
+ BIND_AUTO_CREATE,
+ never(), atLeastOnce());
+ }
+
+ @Test
@RequiresFlagsDisabled(com.android.server.am.Flags.FLAG_UNFREEZE_BIND_POLICY_FIX)
public void testServiceDistinctBindingOomAdjWaivePriority() throws Exception {
// Enable the flags.
@@ -624,6 +674,9 @@ public final class ServiceBindingOomAdjPolicyTest {
// Enable the flags.
mSetFlagsRule.enableFlags(Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY);
+ // Note that some capabilities like PROCESS_CAPABILITY_CPU_TIME are special and propagated
+ // regardless of BIND_INCLUDE_CAPABILITIES. We don't test for them here.
+
// Verify that there should be 0 oom adj update
// because we didn't specify the "BIND_INCLUDE_CAPABILITIES"
performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
diff --git a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
index 428e438443cd..5c73fd33f46f 100644
--- a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
+++ b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
@@ -64,7 +64,6 @@ import android.os.Binder;
import android.os.CpuHeadroomParamsInternal;
import android.os.GpuHeadroomParamsInternal;
import android.os.IBinder;
-import android.os.IHintManager;
import android.os.IHintSession;
import android.os.PerformanceHintManager;
import android.os.Process;
@@ -155,8 +154,6 @@ public class HintManagerServiceTest {
private ActivityManagerInternal mAmInternalMock;
@Mock
private PackageManager mMockPackageManager;
- @Mock
- private IHintManager.IHintManagerClient mClientCallback;
@Rule
public final CheckFlagsRule mCheckFlagsRule =
DeviceFlagsValueProvider.createCheckFlagsRule();
@@ -174,23 +171,6 @@ public class HintManagerServiceTest {
};
}
- private SupportInfo makeDefaultSupportInfo() {
- mSupportInfo = new SupportInfo();
- mSupportInfo.usesSessions = true;
- // By default, mark everything as fully supported
- mSupportInfo.sessionHints = -1;
- mSupportInfo.sessionModes = -1;
- mSupportInfo.modes = -1;
- mSupportInfo.boosts = -1;
- mSupportInfo.sessionTags = -1;
- mSupportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
- mSupportInfo.headroom.isCpuSupported = true;
- mSupportInfo.headroom.cpuMinIntervalMillis = 2000;
- mSupportInfo.headroom.isGpuSupported = true;
- mSupportInfo.headroom.gpuMinIntervalMillis = 2000;
- return mSupportInfo;
- }
-
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -201,7 +181,12 @@ public class HintManagerServiceTest {
mConfig.eventFlagDescriptor = new MQDescriptor<Byte, Byte>();
ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.category = ApplicationInfo.CATEGORY_GAME;
- mSupportInfo = makeDefaultSupportInfo();
+ mSupportInfo = new SupportInfo();
+ mSupportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
+ mSupportInfo.headroom.isCpuSupported = true;
+ mSupportInfo.headroom.cpuMinIntervalMillis = 2000;
+ mSupportInfo.headroom.isGpuSupported = true;
+ mSupportInfo.headroom.gpuMinIntervalMillis = 2000;
when(mContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getNameForUid(anyInt())).thenReturn(TEST_APP_NAME);
when(mMockPackageManager.getApplicationInfo(eq(TEST_APP_NAME), anyInt()))
@@ -230,7 +215,6 @@ public class HintManagerServiceTest {
when(mIPowerMock.getInterfaceVersion()).thenReturn(6);
when(mIPowerMock.getSupportInfo()).thenReturn(mSupportInfo);
when(mIPowerMock.getSessionChannel(anyInt(), anyInt())).thenReturn(mConfig);
- when(mIPowerMock.getSupportInfo()).thenReturn(mSupportInfo);
LocalServices.removeServiceForTest(ActivityManagerInternal.class);
LocalServices.addService(ActivityManagerInternal.class, mAmInternalMock);
}
@@ -425,11 +409,8 @@ public class HintManagerServiceTest {
HintManagerService service = createService();
IBinder token = new Binder();
- IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
- .registerClient(mClientCallback);
-
- final int threadCount = data.maxGraphicsPipelineThreads;
-
+ final int threadCount =
+ service.getBinderServiceInstance().getMaxGraphicsPipelineThreadsCount();
long sessionPtr1 = 1111L;
long sessionId1 = 11111L;
CountDownLatch stopLatch1 = new CountDownLatch(1);
@@ -1466,67 +1447,4 @@ public class HintManagerServiceTest {
verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams1));
verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams2));
}
-
- @Test
- public void testRegisteringClient() throws Exception {
- HintManagerService service = createService();
- IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
- .registerClient(mClientCallback);
- assertNotNull(data);
- assertEquals(data.supportInfo, mSupportInfo);
- }
-
- @Test
- public void testRegisteringClientOnV4() throws Exception {
- when(mIPowerMock.getInterfaceVersion()).thenReturn(4);
- HintManagerService service = createService();
- IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
- .registerClient(mClientCallback);
- assertNotNull(data);
- assertEquals(data.supportInfo.usesSessions, true);
- assertEquals(data.supportInfo.boosts, 0);
- assertEquals(data.supportInfo.modes, 0);
- assertEquals(data.supportInfo.sessionHints, 31);
- assertEquals(data.supportInfo.sessionModes, 0);
- assertEquals(data.supportInfo.sessionTags, 0);
- assertEquals(data.powerHalVersion, 4);
- assertEquals(data.preferredRateNanos, DEFAULT_HINT_PREFERRED_RATE);
- }
-
- @Test
- public void testRegisteringClientOnV5() throws Exception {
- when(mIPowerMock.getInterfaceVersion()).thenReturn(5);
- HintManagerService service = createService();
- IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
- .registerClient(mClientCallback);
- assertNotNull(data);
- assertEquals(data.supportInfo.usesSessions, true);
- assertEquals(data.supportInfo.boosts, 0);
- assertEquals(data.supportInfo.modes, 0);
- assertEquals(data.supportInfo.sessionHints, 255);
- assertEquals(data.supportInfo.sessionModes, 1);
- assertEquals(data.supportInfo.sessionTags, 31);
- assertEquals(data.powerHalVersion, 5);
- assertEquals(data.preferredRateNanos, DEFAULT_HINT_PREFERRED_RATE);
- }
-
- @Test
- public void testSettingUpOldClientWhenUnsupported() throws Exception {
- when(mIPowerMock.getInterfaceVersion()).thenReturn(5);
- // Mock unsupported to modify the default support behavior
- when(mNativeWrapperMock.halGetHintSessionPreferredRate())
- .thenReturn(-1L);
- HintManagerService service = createService();
- IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
- .registerClient(mClientCallback);
- assertNotNull(data);
- assertEquals(data.supportInfo.usesSessions, false);
- assertEquals(data.supportInfo.boosts, 0);
- assertEquals(data.supportInfo.modes, 0);
- assertEquals(data.supportInfo.sessionHints, 0);
- assertEquals(data.supportInfo.sessionModes, 0);
- assertEquals(data.supportInfo.sessionTags, 0);
- assertEquals(data.powerHalVersion, 5);
- assertEquals(data.preferredRateNanos, -1);
- }
}