Merge "Change exact alarm permission to be denied by default"
This commit is contained in:
committed by
Android (Google) Code Review
commit
2da4d09093
@@ -27,7 +27,6 @@ import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
import android.annotation.TestApi;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.Disabled;
|
||||
import android.compat.annotation.EnabledSince;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
@@ -285,11 +284,10 @@ public class AlarmManager {
|
||||
* The permission {@link Manifest.permission#SCHEDULE_EXACT_ALARM} will be denied, unless the
|
||||
* user explicitly allows it from Settings.
|
||||
*
|
||||
* TODO (b/226439802): Either enable it in the next SDK or replace it with a better alternative.
|
||||
* @hide
|
||||
*/
|
||||
@ChangeId
|
||||
@Disabled
|
||||
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
|
||||
public static final long SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = 226439802L;
|
||||
|
||||
@UnsupportedAppUsage
|
||||
|
||||
@@ -44,6 +44,7 @@ import static android.app.AppOpsManager.OP_PLAY_AUDIO;
|
||||
import static android.app.AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO;
|
||||
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
|
||||
import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD;
|
||||
import static android.app.AppOpsManager.OP_SCHEDULE_EXACT_ALARM;
|
||||
import static android.app.AppOpsManager.OP_VIBRATE;
|
||||
import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_FAILED;
|
||||
import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_STARTED;
|
||||
@@ -130,6 +131,8 @@ import com.android.modules.utils.TypedXmlSerializer;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.LockGuard;
|
||||
import com.android.server.SystemServerInitThreadPool;
|
||||
import com.android.server.pm.UserManagerInternal;
|
||||
import com.android.server.pm.permission.PermissionManagerServiceInternal;
|
||||
import com.android.server.pm.pkg.AndroidPackage;
|
||||
import com.android.server.pm.pkg.component.ParsedAttribution;
|
||||
|
||||
@@ -163,12 +166,30 @@ class AppOpsServiceImpl implements AppOpsServiceInterface {
|
||||
static final String TAG = "AppOps";
|
||||
static final boolean DEBUG = false;
|
||||
|
||||
/**
|
||||
* Sentinel integer version to denote that there was no appops.xml found on boot.
|
||||
* This will happen when a device boots with no existing userdata.
|
||||
*/
|
||||
private static final int NO_FILE_VERSION = -2;
|
||||
|
||||
/**
|
||||
* Sentinel integer version to denote that there was no version in the appops.xml found on boot.
|
||||
* This means the file is coming from a build before versioning was added.
|
||||
*/
|
||||
private static final int NO_VERSION = -1;
|
||||
|
||||
/**
|
||||
* Increment by one every time and add the corresponding upgrade logic in
|
||||
* {@link #upgradeLocked(int)} below. The first version was 1
|
||||
* {@link #upgradeLocked(int)} below. The first version was 1.
|
||||
*/
|
||||
private static final int CURRENT_VERSION = 1;
|
||||
@VisibleForTesting
|
||||
static final int CURRENT_VERSION = 2;
|
||||
|
||||
/**
|
||||
* This stores the version of appops.xml seen at boot. If this is smaller than
|
||||
* {@link #CURRENT_VERSION}, then we will run {@link #upgradeLocked(int)} on startup.
|
||||
*/
|
||||
private int mVersionAtBoot = NO_FILE_VERSION;
|
||||
|
||||
// Write at most every 30 minutes.
|
||||
static final long WRITE_DELAY = DEBUG ? 1000 : 30 * 60 * 1000;
|
||||
@@ -936,6 +957,10 @@ class AppOpsServiceImpl implements AppOpsServiceInterface {
|
||||
|
||||
@Override
|
||||
public void systemReady() {
|
||||
synchronized (this) {
|
||||
upgradeLocked(mVersionAtBoot);
|
||||
}
|
||||
|
||||
mConstants.startMonitoring(mContext.getContentResolver());
|
||||
mHistoricalRegistry.systemReady(mContext.getContentResolver());
|
||||
|
||||
@@ -3191,7 +3216,6 @@ class AppOpsServiceImpl implements AppOpsServiceInterface {
|
||||
|
||||
@Override
|
||||
public void readState() {
|
||||
int oldVersion = NO_VERSION;
|
||||
synchronized (mFile) {
|
||||
synchronized (this) {
|
||||
FileInputStream stream;
|
||||
@@ -3216,7 +3240,7 @@ class AppOpsServiceImpl implements AppOpsServiceInterface {
|
||||
throw new IllegalStateException("no start tag found");
|
||||
}
|
||||
|
||||
oldVersion = parser.getAttributeInt(null, "v", NO_VERSION);
|
||||
mVersionAtBoot = parser.getAttributeInt(null, "v", NO_VERSION);
|
||||
|
||||
int outerDepth = parser.getDepth();
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
@@ -3261,12 +3285,11 @@ class AppOpsServiceImpl implements AppOpsServiceInterface {
|
||||
}
|
||||
}
|
||||
}
|
||||
synchronized (this) {
|
||||
upgradeLocked(oldVersion);
|
||||
}
|
||||
}
|
||||
|
||||
private void upgradeRunAnyInBackgroundLocked() {
|
||||
@VisibleForTesting
|
||||
@GuardedBy("this")
|
||||
void upgradeRunAnyInBackgroundLocked() {
|
||||
for (int i = 0; i < mUidStates.size(); i++) {
|
||||
final UidState uidState = mUidStates.valueAt(i);
|
||||
if (uidState == null) {
|
||||
@@ -3303,8 +3326,45 @@ class AppOpsServiceImpl implements AppOpsServiceInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The interpretation of the default mode - MODE_DEFAULT - for OP_SCHEDULE_EXACT_ALARM is
|
||||
* changing. Simultaneously, we want to change this op's mode from MODE_DEFAULT to MODE_ALLOWED
|
||||
* for already installed apps. For newer apps, it will stay as MODE_DEFAULT.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
@GuardedBy("this")
|
||||
void upgradeScheduleExactAlarmLocked() {
|
||||
final PermissionManagerServiceInternal pmsi = LocalServices.getService(
|
||||
PermissionManagerServiceInternal.class);
|
||||
final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
|
||||
final PackageManagerInternal pmi = getPackageManagerInternal();
|
||||
|
||||
final String[] packagesDeclaringPermission = pmsi.getAppOpPermissionPackages(
|
||||
AppOpsManager.opToPermission(OP_SCHEDULE_EXACT_ALARM));
|
||||
final int[] userIds = umi.getUserIds();
|
||||
|
||||
for (final String pkg : packagesDeclaringPermission) {
|
||||
for (int userId : userIds) {
|
||||
final int uid = pmi.getPackageUid(pkg, 0, userId);
|
||||
|
||||
UidState uidState = mUidStates.get(uid);
|
||||
if (uidState == null) {
|
||||
uidState = new UidState(uid);
|
||||
mUidStates.put(uid, uidState);
|
||||
}
|
||||
final int oldMode = uidState.getUidMode(OP_SCHEDULE_EXACT_ALARM);
|
||||
if (oldMode == AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM)) {
|
||||
uidState.setUidMode(OP_SCHEDULE_EXACT_ALARM, MODE_ALLOWED);
|
||||
}
|
||||
}
|
||||
// This appop is meant to be controlled at a uid level. So we leave package modes as
|
||||
// they are.
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
private void upgradeLocked(int oldVersion) {
|
||||
if (oldVersion >= CURRENT_VERSION) {
|
||||
if (oldVersion == NO_FILE_VERSION || oldVersion >= CURRENT_VERSION) {
|
||||
return;
|
||||
}
|
||||
Slog.d(TAG, "Upgrading app-ops xml from version " + oldVersion + " to " + CURRENT_VERSION);
|
||||
@@ -3313,6 +3373,9 @@ class AppOpsServiceImpl implements AppOpsServiceInterface {
|
||||
upgradeRunAnyInBackgroundLocked();
|
||||
// fall through
|
||||
case 1:
|
||||
upgradeScheduleExactAlarmLocked();
|
||||
// fall through
|
||||
case 2:
|
||||
// for future upgrades
|
||||
}
|
||||
scheduleFastWriteLocked();
|
||||
|
||||
@@ -0,0 +1,781 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
|
||||
<app-ops v="1">
|
||||
<uid n="1001">
|
||||
<op n="0" m="4" />
|
||||
<op n="1" m="4" />
|
||||
<op n="15" m="0" />
|
||||
<op n="27" m="4" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="1002">
|
||||
<op n="0" m="4" />
|
||||
<op n="1" m="4" />
|
||||
<op n="15" m="0" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10077">
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10079">
|
||||
<op n="116" m="1" />
|
||||
</uid>
|
||||
<uid n="10080">
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10081">
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10086">
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10087">
|
||||
<op n="59" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10090">
|
||||
<op n="0" m="4" />
|
||||
<op n="1" m="4" />
|
||||
</uid>
|
||||
<uid n="10096">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
</uid>
|
||||
<uid n="10112">
|
||||
<op n="11" m="1" />
|
||||
<op n="51" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="62" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10113">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="51" m="1" />
|
||||
<op n="62" m="1" />
|
||||
</uid>
|
||||
<uid n="10114">
|
||||
<op n="4" m="1" />
|
||||
</uid>
|
||||
<uid n="10115">
|
||||
<op n="0" m="1" />
|
||||
</uid>
|
||||
<uid n="10116">
|
||||
<op n="0" m="1" />
|
||||
</uid>
|
||||
<uid n="10117">
|
||||
<op n="0" m="4" />
|
||||
<op n="1" m="4" />
|
||||
<op n="13" m="1" />
|
||||
<op n="14" m="1" />
|
||||
<op n="16" m="1" />
|
||||
<op n="26" m="4" />
|
||||
<op n="27" m="4" />
|
||||
</uid>
|
||||
<uid n="10118">
|
||||
<op n="51" m="1" />
|
||||
</uid>
|
||||
<uid n="10119">
|
||||
<op n="11" m="1" />
|
||||
<op n="77" m="1" />
|
||||
<op n="111" m="1" />
|
||||
</uid>
|
||||
<uid n="10120">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="4" m="1" />
|
||||
<op n="6" m="1" />
|
||||
<op n="7" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="13" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="54" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10121">
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10122">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="51" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10123">
|
||||
<op n="0" m="4" />
|
||||
<op n="1" m="4" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10124">
|
||||
<op n="11" m="1" />
|
||||
<op n="26" m="1" />
|
||||
</uid>
|
||||
<uid n="10125">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10127">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="26" m="4" />
|
||||
<op n="27" m="4" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="65" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
<op n="111" m="1" />
|
||||
</uid>
|
||||
<uid n="10129">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
</uid>
|
||||
<uid n="10130">
|
||||
<op n="51" m="1" />
|
||||
</uid>
|
||||
<uid n="10131">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10132">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="69" m="1" />
|
||||
<op n="79" m="1" />
|
||||
</uid>
|
||||
<uid n="10133">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10136">
|
||||
<op n="0" m="1" />
|
||||
<op n="4" m="1" />
|
||||
<op n="77" m="1" />
|
||||
<op n="87" m="1" />
|
||||
<op n="111" m="1" />
|
||||
<op n="114" m="1" />
|
||||
</uid>
|
||||
<uid n="10137">
|
||||
<op n="62" m="1" />
|
||||
</uid>
|
||||
<uid n="10138">
|
||||
<op n="26" m="4" />
|
||||
</uid>
|
||||
<uid n="10140">
|
||||
<op n="26" m="4" />
|
||||
<op n="27" m="4" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10141">
|
||||
<op n="11" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="111" m="1" />
|
||||
</uid>
|
||||
<uid n="10142">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10144">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="4" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="27" m="4" />
|
||||
<op n="111" m="1" />
|
||||
</uid>
|
||||
<uid n="10145">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10149">
|
||||
<op n="11" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10150">
|
||||
<op n="51" m="1" />
|
||||
</uid>
|
||||
<uid n="10151">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10152">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10154">
|
||||
<op n="0" m="4" />
|
||||
<op n="1" m="4" />
|
||||
<op n="27" m="4" />
|
||||
</uid>
|
||||
<uid n="10155">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
</uid>
|
||||
<uid n="10157">
|
||||
<op n="13" m="1" />
|
||||
</uid>
|
||||
<uid n="10158">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10160">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="26" m="4" />
|
||||
<op n="27" m="4" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10161">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="51" m="1" />
|
||||
<op n="77" m="1" />
|
||||
<op n="87" m="1" />
|
||||
<op n="111" m="1" />
|
||||
<op n="114" m="1" />
|
||||
</uid>
|
||||
<uid n="10162">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="15" m="0" />
|
||||
<op n="26" m="4" />
|
||||
<op n="27" m="4" />
|
||||
<op n="87" m="1" />
|
||||
<op n="89" m="0" />
|
||||
</uid>
|
||||
<uid n="10163">
|
||||
<op n="26" m="4" />
|
||||
<op n="27" m="4" />
|
||||
<op n="56" m="4" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10164">
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="4" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="69" m="1" />
|
||||
<op n="79" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10169">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10170">
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10171">
|
||||
<op n="26" m="1" />
|
||||
<op n="51" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10172">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10173">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="23" m="0" />
|
||||
<op n="26" m="1" />
|
||||
<op n="51" m="1" />
|
||||
<op n="62" m="1" />
|
||||
<op n="65" m="1" />
|
||||
</uid>
|
||||
<uid n="10175">
|
||||
<op n="0" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="1" />
|
||||
</uid>
|
||||
<uid n="10178">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10179">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="4" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="51" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="62" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10180">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10181">
|
||||
<op n="4" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="62" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="1110181">
|
||||
<op n="4" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
<op n="107" m="2" />
|
||||
</uid>
|
||||
<uid n="10182">
|
||||
<op n="27" m="4" />
|
||||
</uid>
|
||||
<uid n="10183">
|
||||
<op n="11" m="1" />
|
||||
<op n="26" m="4" />
|
||||
</uid>
|
||||
<uid n="10184">
|
||||
<op n="4" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="13" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="4" />
|
||||
</uid>
|
||||
<uid n="10185">
|
||||
<op n="8" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10187">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10189">
|
||||
<op n="11" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="51" m="1" />
|
||||
</uid>
|
||||
<uid n="10190">
|
||||
<op n="0" m="1" />
|
||||
<op n="13" m="1" />
|
||||
</uid>
|
||||
<uid n="10191">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10192">
|
||||
<op n="11" m="1" />
|
||||
<op n="13" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="51" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10193">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10197">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10198">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="4" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="77" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
<op n="90" m="1" />
|
||||
<op n="107" m="0" />
|
||||
<op n="111" m="1" />
|
||||
</uid>
|
||||
<uid n="10199">
|
||||
<op n="4" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="62" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10200">
|
||||
<op n="11" m="1" />
|
||||
<op n="65" m="1" />
|
||||
<op n="107" m="1" />
|
||||
</uid>
|
||||
<uid n="1110200">
|
||||
<op n="11" m="1" />
|
||||
<op n="65" m="1" />
|
||||
<op n="107" m="2" />
|
||||
</uid>
|
||||
<uid n="10201">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="4" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="51" m="1" />
|
||||
<op n="62" m="1" />
|
||||
<op n="84" m="0" />
|
||||
<op n="86" m="0" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10206">
|
||||
<op n="0" m="4" />
|
||||
<op n="1" m="4" />
|
||||
<op n="26" m="4" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10209">
|
||||
<op n="11" m="1" />
|
||||
<op n="51" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10210">
|
||||
<op n="51" m="1" />
|
||||
</uid>
|
||||
<uid n="10212">
|
||||
<op n="11" m="1" />
|
||||
<op n="62" m="1" />
|
||||
</uid>
|
||||
<uid n="10214">
|
||||
<op n="26" m="4" />
|
||||
</uid>
|
||||
<uid n="10216">
|
||||
<op n="51" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10225">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="51" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10229">
|
||||
<op n="11" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="62" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10231">
|
||||
<op n="51" m="1" />
|
||||
</uid>
|
||||
<uid n="10232">
|
||||
<op n="51" m="1" />
|
||||
</uid>
|
||||
<uid n="10234">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="13" m="1" />
|
||||
<op n="20" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10235">
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10237">
|
||||
<op n="0" m="4" />
|
||||
<op n="1" m="4" />
|
||||
</uid>
|
||||
<uid n="10238">
|
||||
<op n="26" m="4" />
|
||||
<op n="27" m="4" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10240">
|
||||
<op n="112" m="1" />
|
||||
</uid>
|
||||
<uid n="10241">
|
||||
<op n="59" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10245">
|
||||
<op n="13" m="1" />
|
||||
<op n="51" m="1" />
|
||||
</uid>
|
||||
<uid n="10247">
|
||||
<op n="0" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="0" />
|
||||
<op n="90" m="1" />
|
||||
</uid>
|
||||
<uid n="10254">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10255">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10256">
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10258">
|
||||
<op n="11" m="1" />
|
||||
</uid>
|
||||
<uid n="10260">
|
||||
<op n="51" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<uid n="10262">
|
||||
<op n="15" m="0" />
|
||||
</uid>
|
||||
<uid n="10266">
|
||||
<op n="0" m="4" />
|
||||
</uid>
|
||||
<uid n="10267">
|
||||
<op n="0" m="1" />
|
||||
<op n="1" m="1" />
|
||||
<op n="4" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="62" m="1" />
|
||||
<op n="77" m="1" />
|
||||
<op n="81" m="1" />
|
||||
<op n="83" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
<op n="107" m="2" />
|
||||
<op n="111" m="1" />
|
||||
</uid>
|
||||
<uid n="10268">
|
||||
<op n="4" m="1" />
|
||||
<op n="11" m="1" />
|
||||
<op n="62" m="1" />
|
||||
</uid>
|
||||
<uid n="10269">
|
||||
<op n="11" m="1" />
|
||||
<op n="26" m="1" />
|
||||
<op n="27" m="1" />
|
||||
<op n="59" m="1" />
|
||||
<op n="60" m="1" />
|
||||
<op n="85" m="1" />
|
||||
<op n="87" m="1" />
|
||||
</uid>
|
||||
<pkg n="com.google.android.iwlan">
|
||||
<uid n="0">
|
||||
<op n="1" />
|
||||
<op n="75" m="0" />
|
||||
</uid>
|
||||
</pkg>
|
||||
<pkg n="com.android.phone">
|
||||
<uid n="0">
|
||||
<op n="1" />
|
||||
<op n="75" m="0" />
|
||||
</uid>
|
||||
</pkg>
|
||||
<pkg n="android">
|
||||
<uid n="1000">
|
||||
<op n="0">
|
||||
<st n="214748364801" t="1670287941040" />
|
||||
</op>
|
||||
<op n="4">
|
||||
<st n="214748364801" t="1670289665522" />
|
||||
</op>
|
||||
<op n="6">
|
||||
<st n="214748364801" t="1670287946650" />
|
||||
</op>
|
||||
<op n="8">
|
||||
<st n="214748364801" t="1670289624396" />
|
||||
</op>
|
||||
<op n="14">
|
||||
<st n="214748364801" t="1670287951031" />
|
||||
</op>
|
||||
<op n="40">
|
||||
<st n="214748364801" t="1670291786337" d="156" />
|
||||
</op>
|
||||
<op n="41">
|
||||
<st id="SensorNotificationService" n="214748364801" t="1670287585567" d="4251183" />
|
||||
<st id="CountryDetector" n="214748364801" t="1670287583306" d="6700" />
|
||||
</op>
|
||||
<op n="43">
|
||||
<st n="214748364801" r="1670291755062" />
|
||||
</op>
|
||||
<op n="61">
|
||||
<st n="214748364801" r="1670291754997" />
|
||||
</op>
|
||||
<op n="105">
|
||||
<st n="214748364801" r="1670291473903" />
|
||||
<st id="GnssService" n="214748364801" r="1670288044920" />
|
||||
</op>
|
||||
<op n="111">
|
||||
<st n="214748364801" t="1670291441554" />
|
||||
</op>
|
||||
</uid>
|
||||
</pkg>
|
||||
<pkg n="com.android.server.telecom">
|
||||
<uid n="1000">
|
||||
<op n="6">
|
||||
<st n="214748364801" t="1670287609092" />
|
||||
</op>
|
||||
<op n="111">
|
||||
<st n="214748364801" t="1670287583728" />
|
||||
</op>
|
||||
</uid>
|
||||
</pkg>
|
||||
<pkg n="com.android.settings">
|
||||
<uid n="1000">
|
||||
<op n="43">
|
||||
<st n="214748364801" r="1670291447349" />
|
||||
</op>
|
||||
<op n="105">
|
||||
<st n="214748364801" r="1670291399231" />
|
||||
</op>
|
||||
<op n="111">
|
||||
<st n="214748364801" t="1670291756910" />
|
||||
</op>
|
||||
</uid>
|
||||
</pkg>
|
||||
<pkg n="com.android.phone">
|
||||
<uid n="1001">
|
||||
<op n="15">
|
||||
<st n="214748364801" t="1670287951022" />
|
||||
</op>
|
||||
<op n="40">
|
||||
<st n="214748364801" t="1670291786177" />
|
||||
</op>
|
||||
<op n="105">
|
||||
<st n="214748364801" r="1670291756403" />
|
||||
</op>
|
||||
</uid>
|
||||
</pkg>
|
||||
<pkg n="com.android.bluetooth">
|
||||
<uid n="1002">
|
||||
<op n="4">
|
||||
<st n="214748364801" t="1670289671076" />
|
||||
</op>
|
||||
<op n="40">
|
||||
<st n="214748364801" t="1670287585676" d="8" />
|
||||
</op>
|
||||
<op n="43">
|
||||
<st n="214748364801" r="1670287585818" />
|
||||
</op>
|
||||
<op n="77">
|
||||
<st n="214748364801" t="1670288037629" />
|
||||
</op>
|
||||
<op n="111">
|
||||
<st n="214748364801" t="1670287592081" />
|
||||
</op>
|
||||
</uid>
|
||||
</pkg>
|
||||
<pkg n="com.android.vending">
|
||||
<uid n="10136">
|
||||
<op n="40">
|
||||
<st n="429496729601" t="1670289621210" d="114" />
|
||||
<st n="858993459201" t="1670289879730" d="349" />
|
||||
<st n="1288490188801" t="1670287942622" d="937" />
|
||||
</op>
|
||||
<op n="43">
|
||||
<st n="429496729601" r="1670289755305" />
|
||||
<st n="858993459201" r="1670288019246" />
|
||||
<st n="1073741824001" r="1670289571783" />
|
||||
<st n="1288490188801" r="1670289373336" />
|
||||
</op>
|
||||
<op n="76">
|
||||
<st n="429496729601" t="1670289748735" d="15991" />
|
||||
<st n="858993459201" t="1670291395180" d="79201" />
|
||||
<st n="1073741824001" t="1670291395168" d="12" />
|
||||
<st n="1288490188801" t="1670291526029" d="3" />
|
||||
<st n="1503238553601" t="1670291526032" d="310718" />
|
||||
</op>
|
||||
<op n="105">
|
||||
<st n="429496729601" r="1670289538910" />
|
||||
<st n="858993459201" r="1670288054519" />
|
||||
<st n="1073741824001" r="1670287599379" />
|
||||
<st n="1288490188801" r="1670289526854" />
|
||||
<st n="1503238553601" r="1670289528242" />
|
||||
</op>
|
||||
</uid>
|
||||
</pkg>
|
||||
<pkg n="com.android.nfc">
|
||||
<uid n="1027">
|
||||
<op n="40">
|
||||
<st n="214748364801" t="1670291786330" d="22" />
|
||||
</op>
|
||||
</uid>
|
||||
</pkg>
|
||||
</app-ops>
|
||||
@@ -16,23 +16,32 @@
|
||||
|
||||
package com.android.server.appop;
|
||||
|
||||
import static android.app.AppOpsManager.OP_SCHEDULE_EXACT_ALARM;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
@@ -42,11 +51,20 @@ import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.modules.utils.TypedXmlPullParser;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemServerInitThreadPool;
|
||||
import com.android.server.pm.UserManagerInternal;
|
||||
import com.android.server.pm.permission.PermissionManagerServiceInternal;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoSession;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.io.File;
|
||||
@@ -64,29 +82,39 @@ public class AppOpsUpgradeTest {
|
||||
private static final String TAG = AppOpsUpgradeTest.class.getSimpleName();
|
||||
private static final String APP_OPS_UNVERSIONED_ASSET_PATH =
|
||||
"AppOpsUpgradeTest/appops-unversioned.xml";
|
||||
private static final String APP_OPS_VERSION_1_ASSET_PATH =
|
||||
"AppOpsUpgradeTest/appops-version-1.xml";
|
||||
private static final String APP_OPS_FILENAME = "appops-test.xml";
|
||||
private static final int NON_DEFAULT_OPS_IN_FILE = 4;
|
||||
private static final int CURRENT_VERSION = 1;
|
||||
|
||||
private File mAppOpsFile;
|
||||
private Context mContext;
|
||||
private static final Context sContext = InstrumentationRegistry.getTargetContext();
|
||||
private static final File sAppOpsFile = new File(sContext.getFilesDir(), APP_OPS_FILENAME);
|
||||
|
||||
private Context mTestContext;
|
||||
private MockitoSession mMockitoSession;
|
||||
|
||||
@Mock
|
||||
private PackageManagerInternal mPackageManagerInternal;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private UserManagerInternal mUserManagerInternal;
|
||||
@Mock
|
||||
private PermissionManagerServiceInternal mPermissionManagerInternal;
|
||||
@Mock
|
||||
private Handler mHandler;
|
||||
|
||||
private void extractAppOpsFile() {
|
||||
mAppOpsFile.getParentFile().mkdirs();
|
||||
if (mAppOpsFile.exists()) {
|
||||
mAppOpsFile.delete();
|
||||
}
|
||||
try (FileOutputStream out = new FileOutputStream(mAppOpsFile);
|
||||
InputStream in = mContext.getAssets().open(APP_OPS_UNVERSIONED_ASSET_PATH,
|
||||
AssetManager.ACCESS_BUFFER)) {
|
||||
private static void extractAppOpsFile(String assetPath) {
|
||||
sAppOpsFile.getParentFile().mkdirs();
|
||||
try (FileOutputStream out = new FileOutputStream(sAppOpsFile);
|
||||
InputStream in = sContext.getAssets().open(assetPath, AssetManager.ACCESS_BUFFER)) {
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(buffer)) >= 0) {
|
||||
out.write(buffer, 0, bytesRead);
|
||||
}
|
||||
out.flush();
|
||||
Log.d(TAG, "Successfully copied xml to " + mAppOpsFile.getAbsolutePath());
|
||||
Log.d(TAG, "Successfully copied xml to " + sAppOpsFile.getAbsolutePath());
|
||||
} catch (IOException exc) {
|
||||
Log.e(TAG, "Exception while copying appops xml", exc);
|
||||
fail();
|
||||
@@ -98,7 +126,7 @@ public class AppOpsUpgradeTest {
|
||||
int numberOfNonDefaultOps = 0;
|
||||
final int defaultModeOp1 = AppOpsManager.opToDefaultMode(op1);
|
||||
final int defaultModeOp2 = AppOpsManager.opToDefaultMode(op2);
|
||||
for(int i = 0; i < uidStates.size(); i++) {
|
||||
for (int i = 0; i < uidStates.size(); i++) {
|
||||
final AppOpsServiceImpl.UidState uidState = uidStates.valueAt(i);
|
||||
SparseIntArray opModes = uidState.getNonDefaultUidModes();
|
||||
if (opModes != null) {
|
||||
@@ -132,41 +160,191 @@ public class AppOpsUpgradeTest {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
mAppOpsFile = new File(mContext.getFilesDir(), APP_OPS_FILENAME);
|
||||
extractAppOpsFile();
|
||||
HandlerThread handlerThread = new HandlerThread(TAG);
|
||||
handlerThread.start();
|
||||
mHandler = new Handler(handlerThread.getLooper());
|
||||
if (sAppOpsFile.exists()) {
|
||||
sAppOpsFile.delete();
|
||||
}
|
||||
|
||||
mMockitoSession = mockitoSession()
|
||||
.initMocks(this)
|
||||
.spyStatic(LocalServices.class)
|
||||
.mockStatic(SystemServerInitThreadPool.class)
|
||||
.strictness(Strictness.LENIENT)
|
||||
.startMocking();
|
||||
|
||||
doReturn(mPermissionManagerInternal).when(
|
||||
() -> LocalServices.getService(PermissionManagerServiceInternal.class));
|
||||
doReturn(mUserManagerInternal).when(
|
||||
() -> LocalServices.getService(UserManagerInternal.class));
|
||||
doReturn(mPackageManagerInternal).when(
|
||||
() -> LocalServices.getService(PackageManagerInternal.class));
|
||||
|
||||
mTestContext = spy(sContext);
|
||||
|
||||
// Pretend everybody has all permissions
|
||||
doNothing().when(mTestContext).enforcePermission(anyString(), anyInt(), anyInt(),
|
||||
nullable(String.class));
|
||||
|
||||
doReturn(mPackageManager).when(mTestContext).getPackageManager();
|
||||
|
||||
// Stub out package calls to disable AppOpsService#updatePermissionRevokedCompat
|
||||
doReturn(null).when(mPackageManager).getPackagesForUid(anyInt());
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mMockitoSession.finishMocking();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpgradeFromNoVersion() throws Exception {
|
||||
AppOpsDataParser parser = new AppOpsDataParser(mAppOpsFile);
|
||||
public void upgradeRunAnyInBackground() {
|
||||
extractAppOpsFile(APP_OPS_UNVERSIONED_ASSET_PATH);
|
||||
|
||||
AppOpsServiceImpl testService = new AppOpsServiceImpl(sAppOpsFile, mHandler, mTestContext);
|
||||
|
||||
testService.upgradeRunAnyInBackgroundLocked();
|
||||
assertSameModes(testService.mUidStates, AppOpsManager.OP_RUN_IN_BACKGROUND,
|
||||
AppOpsManager.OP_RUN_ANY_IN_BACKGROUND);
|
||||
}
|
||||
|
||||
private static int getModeInFile(int uid) {
|
||||
switch (uid) {
|
||||
case 10198:
|
||||
return 0;
|
||||
case 10200:
|
||||
return 1;
|
||||
case 1110200:
|
||||
case 10267:
|
||||
case 1110181:
|
||||
return 2;
|
||||
default:
|
||||
return AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upgradeScheduleExactAlarm() {
|
||||
extractAppOpsFile(APP_OPS_VERSION_1_ASSET_PATH);
|
||||
|
||||
String[] packageNames = {"p1", "package2", "pkg3", "package.4", "pkg-5", "pkg.6"};
|
||||
int[] appIds = {10267, 10181, 10198, 10199, 10200, 4213};
|
||||
int[] userIds = {0, 10, 11};
|
||||
|
||||
doReturn(userIds).when(mUserManagerInternal).getUserIds();
|
||||
|
||||
doReturn(packageNames).when(mPermissionManagerInternal).getAppOpPermissionPackages(
|
||||
AppOpsManager.opToPermission(OP_SCHEDULE_EXACT_ALARM));
|
||||
|
||||
doAnswer(invocation -> {
|
||||
String pkg = invocation.getArgument(0);
|
||||
int index = ArrayUtils.indexOf(packageNames, pkg);
|
||||
if (index < 0) {
|
||||
return index;
|
||||
}
|
||||
int userId = invocation.getArgument(2);
|
||||
return UserHandle.getUid(userId, appIds[index]);
|
||||
}).when(mPackageManagerInternal).getPackageUid(anyString(), anyLong(), anyInt());
|
||||
|
||||
AppOpsServiceImpl testService = new AppOpsServiceImpl(sAppOpsFile, mHandler, mTestContext);
|
||||
|
||||
testService.upgradeScheduleExactAlarmLocked();
|
||||
|
||||
for (int userId : userIds) {
|
||||
for (int appId : appIds) {
|
||||
final int uid = UserHandle.getUid(userId, appId);
|
||||
final int previousMode = getModeInFile(uid);
|
||||
|
||||
final int expectedMode;
|
||||
if (previousMode == AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM)) {
|
||||
expectedMode = AppOpsManager.MODE_ALLOWED;
|
||||
} else {
|
||||
expectedMode = previousMode;
|
||||
}
|
||||
final AppOpsServiceImpl.UidState uidState = testService.mUidStates.get(uid);
|
||||
assertEquals(expectedMode, uidState.getUidMode(OP_SCHEDULE_EXACT_ALARM));
|
||||
}
|
||||
}
|
||||
|
||||
// These uids don't even declare the permission. So should stay as default / empty.
|
||||
int[] unrelatedUidsInFile = {10225, 10178};
|
||||
|
||||
for (int uid : unrelatedUidsInFile) {
|
||||
final AppOpsServiceImpl.UidState uidState = testService.mUidStates.get(uid);
|
||||
assertEquals(AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM),
|
||||
uidState.getUidMode(OP_SCHEDULE_EXACT_ALARM));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upgradeFromNoFile() {
|
||||
assertFalse(sAppOpsFile.exists());
|
||||
|
||||
AppOpsServiceImpl testService = spy(
|
||||
new AppOpsServiceImpl(sAppOpsFile, mHandler, mTestContext));
|
||||
|
||||
doNothing().when(testService).upgradeRunAnyInBackgroundLocked();
|
||||
doNothing().when(testService).upgradeScheduleExactAlarmLocked();
|
||||
|
||||
// trigger upgrade
|
||||
testService.systemReady();
|
||||
|
||||
verify(testService, never()).upgradeRunAnyInBackgroundLocked();
|
||||
verify(testService, never()).upgradeScheduleExactAlarmLocked();
|
||||
|
||||
testService.writeState();
|
||||
|
||||
assertTrue(sAppOpsFile.exists());
|
||||
|
||||
AppOpsDataParser parser = new AppOpsDataParser(sAppOpsFile);
|
||||
assertTrue(parser.parse());
|
||||
assertEquals(AppOpsServiceImpl.CURRENT_VERSION, parser.mVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upgradeFromNoVersion() {
|
||||
extractAppOpsFile(APP_OPS_UNVERSIONED_ASSET_PATH);
|
||||
AppOpsDataParser parser = new AppOpsDataParser(sAppOpsFile);
|
||||
assertTrue(parser.parse());
|
||||
assertEquals(AppOpsDataParser.NO_VERSION, parser.mVersion);
|
||||
|
||||
// Use mock context and package manager to fake permision package manager calls.
|
||||
Context testContext = spy(mContext);
|
||||
|
||||
// Pretent everybody has all permissions
|
||||
doNothing().when(testContext).enforcePermission(anyString(), anyInt(), anyInt(),
|
||||
nullable(String.class));
|
||||
|
||||
PackageManager testPM = mock(PackageManager.class);
|
||||
when(testContext.getPackageManager()).thenReturn(testPM);
|
||||
|
||||
// Stub out package calls to disable AppOpsService#updatePermissionRevokedCompat
|
||||
when(testPM.getPackagesForUid(anyInt())).thenReturn(null);
|
||||
|
||||
AppOpsServiceImpl testService = spy(
|
||||
new AppOpsServiceImpl(mAppOpsFile, mHandler, testContext)); // trigger upgrade
|
||||
assertSameModes(testService.mUidStates, AppOpsManager.OP_RUN_IN_BACKGROUND,
|
||||
AppOpsManager.OP_RUN_ANY_IN_BACKGROUND);
|
||||
mHandler.removeCallbacks(testService.mWriteRunner);
|
||||
new AppOpsServiceImpl(sAppOpsFile, mHandler, mTestContext));
|
||||
|
||||
doNothing().when(testService).upgradeRunAnyInBackgroundLocked();
|
||||
doNothing().when(testService).upgradeScheduleExactAlarmLocked();
|
||||
|
||||
// trigger upgrade
|
||||
testService.systemReady();
|
||||
|
||||
verify(testService).upgradeRunAnyInBackgroundLocked();
|
||||
verify(testService).upgradeScheduleExactAlarmLocked();
|
||||
|
||||
testService.writeState();
|
||||
assertTrue(parser.parse());
|
||||
assertEquals(CURRENT_VERSION, parser.mVersion);
|
||||
assertEquals(AppOpsServiceImpl.CURRENT_VERSION, parser.mVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upgradeFromVersion1() {
|
||||
extractAppOpsFile(APP_OPS_VERSION_1_ASSET_PATH);
|
||||
AppOpsDataParser parser = new AppOpsDataParser(sAppOpsFile);
|
||||
assertTrue(parser.parse());
|
||||
assertEquals(1, parser.mVersion);
|
||||
|
||||
AppOpsServiceImpl testService = spy(
|
||||
new AppOpsServiceImpl(sAppOpsFile, mHandler, mTestContext));
|
||||
|
||||
doNothing().when(testService).upgradeRunAnyInBackgroundLocked();
|
||||
doNothing().when(testService).upgradeScheduleExactAlarmLocked();
|
||||
|
||||
// trigger upgrade
|
||||
testService.systemReady();
|
||||
|
||||
verify(testService, never()).upgradeRunAnyInBackgroundLocked();
|
||||
verify(testService).upgradeScheduleExactAlarmLocked();
|
||||
|
||||
testService.writeState();
|
||||
assertTrue(parser.parse());
|
||||
assertEquals(AppOpsServiceImpl.CURRENT_VERSION, parser.mVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,7 +352,7 @@ public class AppOpsUpgradeTest {
|
||||
* Other fields may be added as and when required for testing.
|
||||
*/
|
||||
private static final class AppOpsDataParser {
|
||||
static final int NO_VERSION = -1;
|
||||
static final int NO_VERSION = -123;
|
||||
int mVersion;
|
||||
private File mFile;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user