Merge "DO NOT MERGE - Merge pie-platform-release (PPRL.190605.003) into master"
This commit is contained in:
@@ -156,8 +156,9 @@ static struct thread_dispatch_offsets_t
|
||||
static constexpr int32_t PROXY_WARN_INTERVAL = 5000;
|
||||
static constexpr uint32_t GC_INTERVAL = 1000;
|
||||
|
||||
static std::atomic<uint32_t> gNumProxies(0);
|
||||
static std::atomic<uint32_t> gProxiesWarned(0);
|
||||
// Protected by gProxyLock. We warn if this gets too large.
|
||||
static int32_t gNumProxies = 0;
|
||||
static int32_t gProxiesWarned = 0;
|
||||
|
||||
// Number of GlobalRefs held by JavaBBinders.
|
||||
static std::atomic<uint32_t> gNumLocalRefsCreated(0);
|
||||
@@ -659,6 +660,12 @@ BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
|
||||
return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
|
||||
}
|
||||
|
||||
static Mutex gProxyLock;
|
||||
|
||||
// We may cache a single BinderProxyNativeData node to avoid repeat allocation.
|
||||
// All fields are null. Protected by gProxyLock.
|
||||
static BinderProxyNativeData *gNativeDataCache;
|
||||
|
||||
// If the argument is a JavaBBinder, return the Java object that was used to create it.
|
||||
// Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
|
||||
// same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
|
||||
@@ -673,31 +680,36 @@ jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
|
||||
return object;
|
||||
}
|
||||
|
||||
BinderProxyNativeData* nativeData = new BinderProxyNativeData();
|
||||
nativeData->mOrgue = new DeathRecipientList;
|
||||
nativeData->mObject = val;
|
||||
// For the rest of the function we will hold this lock, to serialize
|
||||
// looking/creation/destruction of Java proxies for native Binder proxies.
|
||||
AutoMutex _l(gProxyLock);
|
||||
|
||||
BinderProxyNativeData* nativeData = gNativeDataCache;
|
||||
if (nativeData == nullptr) {
|
||||
nativeData = new BinderProxyNativeData();
|
||||
}
|
||||
// gNativeDataCache is now logically empty.
|
||||
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
|
||||
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
|
||||
if (env->ExceptionCheck()) {
|
||||
// In the exception case, getInstance still took ownership of nativeData.
|
||||
gNativeDataCache = nullptr;
|
||||
return NULL;
|
||||
}
|
||||
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
|
||||
if (actualNativeData == nativeData) {
|
||||
// Created a new Proxy
|
||||
uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
|
||||
uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
|
||||
if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
|
||||
// Multiple threads can get here, make sure only one of them gets to
|
||||
// update the warn counter.
|
||||
if (gProxiesWarned.compare_exchange_strong(numLastWarned,
|
||||
numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
|
||||
ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
|
||||
}
|
||||
// New BinderProxy; we still have exclusive access.
|
||||
nativeData->mOrgue = new DeathRecipientList;
|
||||
nativeData->mObject = val;
|
||||
gNativeDataCache = nullptr;
|
||||
++gNumProxies;
|
||||
if (gNumProxies >= gProxiesWarned + PROXY_WARN_INTERVAL) {
|
||||
ALOGW("Unexpectedly many live BinderProxies: %d\n", gNumProxies);
|
||||
gProxiesWarned = gNumProxies;
|
||||
}
|
||||
} else {
|
||||
delete nativeData;
|
||||
// nativeData wasn't used. Reuse it the next time.
|
||||
gNativeDataCache = nativeData;
|
||||
}
|
||||
|
||||
return object;
|
||||
@@ -977,7 +989,8 @@ jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz)
|
||||
|
||||
jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
|
||||
{
|
||||
return gNumProxies.load();
|
||||
AutoMutex _l(gProxyLock);
|
||||
return gNumProxies;
|
||||
}
|
||||
|
||||
jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
|
||||
@@ -1372,6 +1385,9 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
|
||||
|
||||
static void BinderProxy_destroy(void* rawNativeData)
|
||||
{
|
||||
// Don't race with construction/initialization
|
||||
AutoMutex _l(gProxyLock);
|
||||
|
||||
BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
|
||||
LOGDEATH("Destroying BinderProxy: binder=%p drl=%p\n",
|
||||
nativeData->mObject.get(), nativeData->mOrgue.get());
|
||||
|
||||
@@ -2189,6 +2189,11 @@ public class NotificationManagerService extends SystemService {
|
||||
@Override
|
||||
public boolean areNotificationsEnabledForPackage(String pkg, int uid) {
|
||||
checkCallerIsSystemOrSameApp(pkg);
|
||||
if (UserHandle.getCallingUserId() != UserHandle.getUserId(uid)) {
|
||||
getContext().enforceCallingPermission(
|
||||
android.Manifest.permission.INTERACT_ACROSS_USERS,
|
||||
"canNotifyAsPackage for uid " + uid);
|
||||
}
|
||||
|
||||
return mRankingHelper.getImportance(pkg, uid) != IMPORTANCE_NONE;
|
||||
}
|
||||
|
||||
@@ -18305,6 +18305,12 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
@Override
|
||||
public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
|
||||
!= PERMISSION_GRANTED) {
|
||||
EventLog.writeEvent(0x534e4554, "128599183", -1, "");
|
||||
throw new SecurityException(android.Manifest.permission.MANAGE_USERS
|
||||
+ " permission is required to call this API");
|
||||
}
|
||||
if (getInstantAppPackageName(callingUid) != null
|
||||
&& !isCallerSameApp(packageName, callingUid)) {
|
||||
return false;
|
||||
|
||||
@@ -3934,6 +3934,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
|
||||
@Override
|
||||
public boolean isSeparateProfileChallengeAllowed(int userHandle) {
|
||||
if (!isCallerWithSystemUid()) {
|
||||
throw new SecurityException("Caller must be system");
|
||||
}
|
||||
ComponentName profileOwner = getProfileOwner(userHandle);
|
||||
// Profile challenge is supported on N or newer release.
|
||||
return profileOwner != null &&
|
||||
|
||||
@@ -34,6 +34,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
|
||||
import static android.content.pm.PackageManager.FEATURE_WATCH;
|
||||
import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.os.Build.VERSION_CODES.O_MR1;
|
||||
import static android.os.Build.VERSION_CODES.P;
|
||||
|
||||
@@ -106,6 +107,7 @@ import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableContext;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
import android.testing.TestablePermissions;
|
||||
import android.text.Html;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.AtomicFile;
|
||||
@@ -3145,4 +3147,21 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
|
||||
assertEquals(0, captor.getValue().getNotification().flags);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAreNotificationsEnabledForPackage_crossUser() throws Exception {
|
||||
try {
|
||||
mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
|
||||
mUid + UserHandle.PER_USER_RANGE);
|
||||
fail("Cannot call cross user without permission");
|
||||
} catch (SecurityException e) {
|
||||
// pass
|
||||
}
|
||||
|
||||
// cross user, with permission, no problem
|
||||
TestablePermissions perms = mContext.getTestablePermissions();
|
||||
perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED);
|
||||
mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
|
||||
mUid + UserHandle.PER_USER_RANGE);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user