Merge "Extend ADataspace."
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 20bfe65..4a84884 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -14,10 +14,12 @@
libs/renderengine/
libs/ui/
libs/vr/
+ opengl/libs/
services/bufferhub/
services/inputflinger/
services/surfaceflinger/
services/vr/
+ vulkan/
[Hook Scripts]
owners_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "OWNERS$"
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index f8a68b4..6b14bee 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -639,10 +639,8 @@
if (delete_dir_contents(path, true) != 0) {
res = error("Failed to delete contents of " + path);
}
- path = StringPrintf("%s/Android/obb/%s", extPath.c_str(), pkgname);
- if (delete_dir_contents(path, true) != 0) {
- res = error("Failed to delete contents of " + path);
- }
+ // Note that we explicitly don't delete OBBs - those are only removed on
+ // app uninstall.
}
}
}
diff --git a/cmds/installd/QuotaUtils.cpp b/cmds/installd/QuotaUtils.cpp
index a71e01c..e080291 100644
--- a/cmds/installd/QuotaUtils.cpp
+++ b/cmds/installd/QuotaUtils.cpp
@@ -101,6 +101,26 @@
}
}
+int64_t GetOccupiedSpaceForProjectId(const std::string& uuid, int projectId) {
+ const std::string device = FindQuotaDeviceForUuid(uuid);
+ if (device == "") {
+ return -1;
+ }
+ struct dqblk dq;
+ if (quotactl(QCMD(Q_GETQUOTA, PRJQUOTA), device.c_str(), projectId,
+ reinterpret_cast<char*>(&dq)) != 0) {
+ if (errno != ESRCH) {
+ PLOG(ERROR) << "Failed to quotactl " << device << " for Project ID " << projectId;
+ }
+ return -1;
+ } else {
+#if MEASURE_DEBUG
+ LOG(DEBUG) << "quotactl() for Project ID " << projectId << " " << dq.dqb_curspace;
+#endif
+ return dq.dqb_curspace;
+ }
+}
+
int64_t GetOccupiedSpaceForGid(const std::string& uuid, gid_t gid) {
const std::string device = FindQuotaDeviceForUuid(uuid);
if (device == "") {
diff --git a/cmds/installd/QuotaUtils.h b/cmds/installd/QuotaUtils.h
index 9ad170f..96aca04 100644
--- a/cmds/installd/QuotaUtils.h
+++ b/cmds/installd/QuotaUtils.h
@@ -35,6 +35,8 @@
/* Get the current occupied space in bytes for a gid or -1 if fails */
int64_t GetOccupiedSpaceForGid(const std::string& uuid, gid_t gid);
+/* Get the current occupied space in bytes for a project id or -1 if fails */
+int64_t GetOccupiedSpaceForProjectId(const std::string& uuid, int projectId);
} // namespace installd
} // namespace android
diff --git a/data/etc/android.hardware.telephony.cdma.xml b/data/etc/android.hardware.telephony.cdma.xml
index 082378d..b598f68 100644
--- a/data/etc/android.hardware.telephony.cdma.xml
+++ b/data/etc/android.hardware.telephony.cdma.xml
@@ -18,4 +18,5 @@
<permissions>
<feature name="android.hardware.telephony" />
<feature name="android.hardware.telephony.cdma" />
+ <feature name="android.hardware.telephony.data" />
</permissions>
diff --git a/data/etc/android.hardware.telephony.gsm.xml b/data/etc/android.hardware.telephony.gsm.xml
index 7927fa8..fe8a5cf 100644
--- a/data/etc/android.hardware.telephony.gsm.xml
+++ b/data/etc/android.hardware.telephony.gsm.xml
@@ -18,4 +18,5 @@
<permissions>
<feature name="android.hardware.telephony" />
<feature name="android.hardware.telephony.gsm" />
+ <feature name="android.hardware.telephony.data" />
</permissions>
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 354703b..f07c231 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -145,6 +145,12 @@
void GraphicsEnv::hintActivityLaunch() {
ATRACE_CALL();
+ {
+ std::lock_guard<std::mutex> lock(mStatsLock);
+ if (mActivityLaunched) return;
+ mActivityLaunched = true;
+ }
+
std::thread trySendGpuStatsThread([this]() {
// If there's already graphics driver preloaded in the process, just send
// the stats info to GpuStats directly through async binder.
@@ -228,12 +234,11 @@
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mStatsLock);
- const bool doNotSend = mGpuStats.appPackageName.empty();
if (api == GpuStatsInfo::Api::API_GL) {
- if (doNotSend) mGpuStats.glDriverToSend = true;
+ mGpuStats.glDriverToSend = true;
mGpuStats.glDriverLoadingTime = driverLoadingTime;
} else {
- if (doNotSend) mGpuStats.vkDriverToSend = true;
+ mGpuStats.vkDriverToSend = true;
mGpuStats.vkDriverLoadingTime = driverLoadingTime;
}
@@ -250,10 +255,18 @@
return interface_cast<IGpuService>(binder);
}
+bool GraphicsEnv::readyToSendGpuStatsLocked() {
+ // Only send stats for processes having at least one activity launched and that process doesn't
+ // skip the GraphicsEnvironment setup.
+ return mActivityLaunched && !mGpuStats.appPackageName.empty();
+}
+
void GraphicsEnv::setTargetStats(const GpuStatsInfo::Stats stats, const uint64_t value) {
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mStatsLock);
+ if (!readyToSendGpuStatsLocked()) return;
+
const sp<IGpuService> gpuService = getGpuService();
if (gpuService) {
gpuService->setTargetStats(mGpuStats.appPackageName, mGpuStats.driverVersionCode, stats,
@@ -265,8 +278,7 @@
int64_t driverLoadingTime) {
ATRACE_CALL();
- // Do not sendGpuStats for those skipping the GraphicsEnvironment setup
- if (mGpuStats.appPackageName.empty()) return;
+ if (!readyToSendGpuStatsLocked()) return;
ALOGV("sendGpuStats:\n"
"\tdriverPackageName[%s]\n"
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index c6dc1f8..2219074 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -131,6 +131,8 @@
void updateUseAngle();
// Link updatable driver namespace with llndk and vndk-sp libs.
bool linkDriverNamespaceLocked(android_namespace_t* vndkNamespace);
+ // Check whether this process is ready to send stats.
+ bool readyToSendGpuStatsLocked();
// Send the initial complete GpuStats to GpuService.
void sendGpuStatsLocked(GpuStatsInfo::Api api, bool isDriverLoaded, int64_t driverLoadingTime);
@@ -141,6 +143,8 @@
std::string mSphalLibraries;
// This mutex protects mGpuStats and get gpuservice call.
std::mutex mStatsLock;
+ // Cache the activity launch info
+ bool mActivityLaunched = false;
// Information bookkept for GpuStats.
GpuStatsInfo mGpuStats;
// Path to ANGLE libs.
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index 208d729..8af1a1c 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -50,17 +50,20 @@
return result;
}
- int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL);
- if (rc < 0) {
- return UNKNOWN_ERROR;
+ if (mLooper != nullptr) {
+ int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL);
+ if (rc < 0) {
+ return UNKNOWN_ERROR;
+ }
}
+
return OK;
}
void DisplayEventDispatcher::dispose() {
ALOGV("dispatcher %p ~ Disposing display event dispatcher.", this);
- if (!mReceiver.initCheck()) {
+ if (!mReceiver.initCheck() && mLooper != nullptr) {
mLooper->removeFd(mReceiver.getFd());
}
}
@@ -101,6 +104,10 @@
mConfigChangeFlag = configChangeFlag;
}
+int DisplayEventDispatcher::getFd() {
+ return mReceiver.getFd();
+}
+
int DisplayEventDispatcher::handleEvent(int, int events, void*) {
if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
ALOGE("Display event receiver pipe was closed or an error occurred. "
diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h
index 0b71801..679d572 100644
--- a/libs/gui/include/gui/DisplayEventDispatcher.h
+++ b/libs/gui/include/gui/DisplayEventDispatcher.h
@@ -32,6 +32,8 @@
void dispose();
status_t scheduleVsync();
void toggleConfigEvents(ISurfaceComposer::ConfigChanged configChangeFlag);
+ int getFd();
+ virtual int handleEvent(int receiveFd, int events, void* data);
protected:
virtual ~DisplayEventDispatcher() = default;
@@ -48,7 +50,6 @@
virtual void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId,
int32_t configId, nsecs_t vsyncPeriod) = 0;
- virtual int handleEvent(int receiveFd, int events, void* data);
bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
uint32_t* outCount);
};
diff --git a/libs/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp
index 7e71ede..15d937e 100644
--- a/libs/nativedisplay/AChoreographer.cpp
+++ b/libs/nativedisplay/AChoreographer.cpp
@@ -56,6 +56,7 @@
class Choreographer : public DisplayEventDispatcher, public MessageHandler {
public:
+ explicit Choreographer(const sp<Looper>& looper);
void postFrameCallbackDelayed(AChoreographer_frameCallback cb,
AChoreographer_frameCallback64 cb64, void* data, nsecs_t delay);
void registerRefreshRateCallback(AChoreographer_refreshRateCallback cb, void* data);
@@ -68,12 +69,9 @@
virtual void handleMessage(const Message& message) override;
static Choreographer* getForThread();
-
-protected:
virtual ~Choreographer() = default;
private:
- explicit Choreographer(const sp<Looper>& looper);
Choreographer(const Choreographer&) = delete;
void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override;
@@ -132,14 +130,22 @@
}
if (callback.dueTime <= now) {
if (std::this_thread::get_id() != mThreadId) {
- Message m{MSG_SCHEDULE_VSYNC};
- mLooper->sendMessage(this, m);
+ if (mLooper != nullptr) {
+ Message m{MSG_SCHEDULE_VSYNC};
+ mLooper->sendMessage(this, m);
+ } else {
+ scheduleVsync();
+ }
} else {
scheduleVsync();
}
} else {
- Message m{MSG_SCHEDULE_CALLBACKS};
- mLooper->sendMessageDelayed(delay, this, m);
+ if (mLooper != nullptr) {
+ Message m{MSG_SCHEDULE_CALLBACKS};
+ mLooper->sendMessageDelayed(delay, this, m);
+ } else {
+ scheduleCallbacks();
+ }
}
}
@@ -154,10 +160,11 @@
void Choreographer::unregisterRefreshRateCallback(AChoreographer_refreshRateCallback cb) {
{
AutoMutex _l{mLock};
- std::remove_if(mRefreshRateCallbacks.begin(), mRefreshRateCallbacks.end(),
- [&](const RefreshRateCallback& callback) {
- return cb == callback.callback;
- });
+ mRefreshRateCallbacks.erase(std::remove_if(mRefreshRateCallbacks.begin(),
+ mRefreshRateCallbacks.end(),
+ [&](const RefreshRateCallback& callback) {
+ return cb == callback.callback;
+ }));
if (mRefreshRateCallbacks.empty()) {
toggleConfigEvents(ISurfaceComposer::ConfigChanged::eConfigChangedSuppress);
}
@@ -238,7 +245,7 @@
/* Glue for the NDK interface */
-using android::Choreographer;
+using namespace android;
static inline Choreographer* AChoreographer_to_Choreographer(AChoreographer* choreographer) {
return reinterpret_cast<Choreographer*>(choreographer);
@@ -281,3 +288,32 @@
AChoreographer_refreshRateCallback callback) {
AChoreographer_to_Choreographer(choreographer)->unregisterRefreshRateCallback(callback);
}
+
+AChoreographer* AChoreographer_create() {
+ Choreographer* choreographer = new Choreographer(nullptr);
+ status_t result = choreographer->initialize();
+ if (result != OK) {
+ ALOGW("Failed to initialize");
+ return nullptr;
+ }
+ return Choreographer_to_AChoreographer(choreographer);
+}
+
+void AChoreographer_destroy(AChoreographer* choreographer) {
+ if (choreographer == nullptr) {
+ return;
+ }
+
+ delete AChoreographer_to_Choreographer(choreographer);
+}
+
+int AChoreographer_getFd(AChoreographer* choreographer) {
+ return AChoreographer_to_Choreographer(choreographer)->getFd();
+}
+
+void AChoreographer_handlePendingEvents(AChoreographer* choreographer, void* data) {
+ // Pass dummy fd and events args to handleEvent, since the underlying
+ // DisplayEventDispatcher doesn't need them outside of validating that a
+ // Looper instance didn't break, but these args circumvent those checks.
+ AChoreographer_to_Choreographer(choreographer)->handleEvent(-1, Looper::EVENT_INPUT, data);
+}
diff --git a/libs/nativedisplay/Android.bp b/libs/nativedisplay/Android.bp
index 7a497ea..d37b9a1 100644
--- a/libs/nativedisplay/Android.bp
+++ b/libs/nativedisplay/Android.bp
@@ -13,7 +13,7 @@
// limitations under the License.
ndk_headers {
- name: "libachoreographer_ndk_headers",
+ name: "libnativedisplay_ndk_headers",
from: "include/android",
to: "android",
srcs: ["include/android/*.h"],
diff --git a/libs/nativedisplay/include/apex/choreographer.h b/libs/nativedisplay/include/apex/choreographer.h
index 352213e..5251fd3 100644
--- a/libs/nativedisplay/include/apex/choreographer.h
+++ b/libs/nativedisplay/include/apex/choreographer.h
@@ -40,4 +40,39 @@
void AChoreographer_unregisterRefreshRateCallback(AChoreographer* choreographer,
AChoreographer_refreshRateCallback);
+/**
+ * Creates an instance of AChoreographer.
+ *
+ * The key differences between this method and AChoreographer_getInstance are:
+ * 1. The returned AChoreographer instance is not a thread-local, and
+ * 2. This method does not require an existing ALooper attached to the thread.
+ */
+AChoreographer* AChoreographer_create();
+
+/**
+ * Destroys a choreographer instance created from AChoreographer_create.
+ */
+void AChoreographer_destroy(AChoreographer* choreographer);
+
+/**
+ * Returns the underlying file descriptor associated with this choreographer
+ * instance.
+ *
+ * The caller can listen to the file descriptor to respond to any AChoreographer
+ * events. One such way is registering the file descriptor to a Looper instance,
+ * although this is not a requirement.
+ */
+int AChoreographer_getFd(AChoreographer* choreographer);
+
+/**
+ * Provides a callback to handle all pending events emitted by this
+ * choreographer instance. Specifically, this delegates to the callbacks
+ * previously registered to choreographer.
+ *
+ * If the associated file descriptor is attached to a Looper instance, then the
+ * callback attached to that Looper is expected to handle exceptional Looper
+ * events.
+ */
+void AChoreographer_handlePendingEvents(AChoreographer* choreographer, void* data);
+
__END_DECLS
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 847e20c..692ded9 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -126,7 +126,7 @@
return BAD_VALUE;
}
const RefreshRate& refreshRate = mRefreshRates.at(defaultConfigId);
- if (refreshRate.fps < minRefreshRate || refreshRate.fps > maxRefreshRate) {
+ if (!refreshRate.inPolicy(minRefreshRate, maxRefreshRate)) {
return BAD_VALUE;
}
mDefaultConfig = defaultConfigId;
@@ -180,8 +180,8 @@
group.value(), mMinRefreshRateFps, mMaxRefreshRateFps);
getSortedRefreshRateList(
[&](const RefreshRate& refreshRate) REQUIRES(mLock) {
- return refreshRate.configGroup == group && refreshRate.fps >= mMinRefreshRateFps &&
- refreshRate.fps <= mMaxRefreshRateFps;
+ return refreshRate.configGroup == group &&
+ refreshRate.inPolicy(mMinRefreshRateFps, mMaxRefreshRateFps);
},
&mAvailableRefreshRates);
LOG_ALWAYS_FATAL_IF(mAvailableRefreshRates.empty(),
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 1e740ca..0c3369a 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -44,6 +44,9 @@
class RefreshRateConfigs {
public:
struct RefreshRate {
+ // The tolerance within which we consider FPS approximately equals.
+ static constexpr float FPS_EPSILON = 0.001f;
+
RefreshRate(HwcConfigIndexType configId, nsecs_t vsyncPeriod,
HwcConfigGroupType configGroup, std::string name, float fps)
: configId(configId),
@@ -63,6 +66,12 @@
// Refresh rate in frames per second
const float fps = 0;
+ // Checks whether the fps of this RefreshRate struct is within a given min and max refresh
+ // rate passed in. FPS_EPSILON is applied to the boundaries for approximation.
+ bool inPolicy(float minRefreshRate, float maxRefreshRate) const {
+ return (fps >= (minRefreshRate - FPS_EPSILON) && fps <= (maxRefreshRate + FPS_EPSILON));
+ }
+
bool operator!=(const RefreshRate& other) const {
return configId != other.configId || vsyncPeriod != other.vsyncPeriod ||
configGroup != other.configGroup;
diff --git a/services/surfaceflinger/surfaceflinger.rc b/services/surfaceflinger/surfaceflinger.rc
index aea602b..d3942e8 100644
--- a/services/surfaceflinger/surfaceflinger.rc
+++ b/services/surfaceflinger/surfaceflinger.rc
@@ -2,6 +2,7 @@
class core animation
user system
group graphics drmrpc readproc
+ capabilities SYS_NICE
onrestart restart zygote
writepid /dev/stune/foreground/tasks
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
diff --git a/services/surfaceflinger/tests/SurfaceFlinger_test.filter b/services/surfaceflinger/tests/SurfaceFlinger_test.filter
index 7786638..1df1ac2 100644
--- a/services/surfaceflinger/tests/SurfaceFlinger_test.filter
+++ b/services/surfaceflinger/tests/SurfaceFlinger_test.filter
@@ -1,5 +1,5 @@
{
"presubmit": {
- "filter": "*:-RefreshRateRangeTest.*:LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadius/2:LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadius/3:LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadiusChildCrop/2:LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadiusChildCrop/3"
+ "filter": "*:LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadius/2:LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadius/3:LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadiusChildCrop/2:LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadiusChildCrop/3"
}
}
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index ed620ef..cc3c985 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -39,6 +39,7 @@
static inline const HwcConfigGroupType HWC_GROUP_ID_0 = HwcConfigGroupType(0);
static inline const HwcConfigGroupType HWC_GROUP_ID_1 = HwcConfigGroupType(1);
static constexpr int64_t VSYNC_60 = 16666667;
+ static constexpr int64_t VSYNC_60_POINT_4 = 16666665;
static constexpr int64_t VSYNC_90 = 11111111;
RefreshRateConfigsTest();
@@ -238,6 +239,16 @@
ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(24.0f));
}
+TEST_F(RefreshRateConfigsTest, testInPolicy) {
+ RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60_POINT_4, HWC_GROUP_ID_0,
+ "60fps", 60};
+ ASSERT_TRUE(expectedDefaultConfig.inPolicy(60.000004, 60.000004));
+ ASSERT_TRUE(expectedDefaultConfig.inPolicy(59.0f, 60.1f));
+ ASSERT_FALSE(expectedDefaultConfig.inPolicy(75.0, 90.0));
+ ASSERT_FALSE(expectedDefaultConfig.inPolicy(60.0011, 90.0));
+ ASSERT_FALSE(expectedDefaultConfig.inPolicy(50.0, 59.998));
+}
+
} // namespace
} // namespace scheduler
} // namespace android