Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8348851b authored by Sam Mortimer's avatar Sam Mortimer Committed by Steve Kondik
Browse files

[2/2] AppOps: Add alarm wakeup op

Port from cm-10.2 / cm-11.0

Author: Sam Mortimer <sam@mortimer.me.uk>
Date:   Fri Sep 27 21:30:34 2013 -0700
[2/2] AppOps: Add alarm wakeup op
When alarm wakeups are denied/ignored,
the alarm types are remapped as follows:
RTC_WAKEUP -> RTC
ELAPSED_REALTIME_WAKEUP -> ELAPSED_REALTIME
Change-Id: I3a5023e1f6260004319290e776bdb2daf73e9fdf

Author: Ricardo Cerqueira <cyanogenmod@cerqueira.org>
Date:   Thu May 22 19:54:01 2014 +0100
AppOps: Don't apply OP_ALARM_WAKEUP to system components
System can freely invoke and manage alarms. Preventing it from doing
so interferes with remote components like the backupmanager (backing up alarms)
due to the mismatched uids between the invoking app and the running
service that takes the action.
Change-Id: I079df8d2522642d6d9194781207df7dd67b715b2

Change-Id: I399a7f0d0b20c562b94ec978976d5d8ebff12eac
parent a60d5cd3
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -243,7 +243,9 @@ public class AppOpsManager {
    /** @hide */
    public static final int OP_DATA_CONNECT_CHANGE = 59;
    /** @hide */
    public static final int _NUM_OP = 60;
    public static final int OP_ALARM_WAKEUP = 60;
    /** @hide */
    public static final int _NUM_OP = 61;

    /** Access to coarse location information. */
    public static final String OPSTR_COARSE_LOCATION =
@@ -372,6 +374,8 @@ public class AppOpsManager {
            "android:delete_call_log";
    private static final String OPSTR_DATA_CONNECT_CHANGE =
            "android:data_connect_change";
    private static final String OPSTR_ALARM_WAKEUP =
            "android:alarm_wakeup";

    /**
     * This maps each operation to the operation that serves as the
@@ -442,6 +446,7 @@ public class AppOpsManager {
            OP_DELETE_CONTACTS,
            OP_DELETE_CALL_LOG,
            OP_DATA_CONNECT_CHANGE,
            OP_ALARM_WAKEUP,
    };

    /**
@@ -509,6 +514,7 @@ public class AppOpsManager {
            null,
            null,
            null,
            null,
    };

    /**
@@ -576,6 +582,7 @@ public class AppOpsManager {
        OPSTR_DELETE_CONTACTS,
        OPSTR_DELETE_CALL_LOG,
        OPSTR_DATA_CONNECT_CHANGE,
        OPSTR_ALARM_WAKEUP,
    };

    /**
@@ -643,6 +650,7 @@ public class AppOpsManager {
            "DELETE_CONTACTS",
            "DELETE_CALL_LOG",
            "DATA_CONNECT_CHANGE",
            "ALARM_WAKEUP",
    };

    /**
@@ -710,6 +718,7 @@ public class AppOpsManager {
            android.Manifest.permission.WRITE_CONTACTS,
            android.Manifest.permission.WRITE_CALL_LOG,
            android.Manifest.permission.MODIFY_PHONE_STATE,
            null, // OP_ALARM_WAKEUP
    };

    /**
@@ -778,6 +787,7 @@ public class AppOpsManager {
            null, //DELETE_CONTACTS
            null, //DELETE_CALL_LOG
            null, //DATA_CONNECT_CHANGE
            null, //ALARM_WAKEUP
    };

    /**
@@ -845,6 +855,7 @@ public class AppOpsManager {
            false, //DELETE_CONTACTS
            false, //DELETE_CALL_LOG
            false, //DATA_CONNECT_CHANGE
            true, //ALARM_WAKEUP
    };

    /**
@@ -911,6 +922,7 @@ public class AppOpsManager {
            AppOpsManager.MODE_ALLOWED,
            AppOpsManager.MODE_ALLOWED,
            AppOpsManager.MODE_ALLOWED,
            AppOpsManager.MODE_ALLOWED, // OP_ALARM_WAKEUP
    };

    /**
@@ -978,6 +990,7 @@ public class AppOpsManager {
            AppOpsManager.MODE_ASK,     // OP_DELETE_CONTACTS
            AppOpsManager.MODE_ASK,     // OP_DELETE_CALL_LOG
            AppOpsManager.MODE_ASK,     // OP_DATA_CONNECT_CHANGE
            AppOpsManager.MODE_ALLOWED, // OP_ALARM_WAKEUP
    };

    /**
@@ -1044,6 +1057,7 @@ public class AppOpsManager {
        true,     // OP_DELETE_CONTACTS
        true,     // OP_DELETE_CALL_LOG
        true,     // OP_DATA_CONNECT_CHANGE
        false,    // OP_ALARM_WAKEUP
    };

    /**
@@ -1114,6 +1128,7 @@ public class AppOpsManager {
            false,     // OP_DELETE_CONTACTS
            false,     // OP_DELETE_CALL_LOG
            false,     // OP_DATA_CONNECT_CHANGE
            false,     // OP_ALARM_WAKEUP
    };

    private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>();
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@
        <item>@string/app_ops_delete_contacts</item>
        <item>@string/app_ops_delete_call_log</item>
        <item>@string/app_ops_toggle_mobile_data</item>
        <item>@string/app_ops_alarm_wakeup</item>
    </string-array>

</resources>
+1 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@
    <string name="app_ops_access_location">access your location</string>
    <string name="app_ops_access_notifications">read your notifications</string>
    <string name="app_ops_activate_vpn">activate a VPN</string>
    <string name="app_ops_alarm_wakeup">wake up the device</string>
    <string name="app_ops_auto_start">start at power up</string>
    <string name="app_ops_delete_call_log">delete your call log</string>
    <string name="app_ops_delete_contacts">delete your contacts</string>
+49 −5
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.IAlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -156,6 +157,8 @@ class AlarmManagerService extends SystemService {
    private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray =
            new SparseArray<>();

    private AppOpsManager mAppOps;

    // Alarm delivery ordering bookkeeping
    static final int PRIO_TICK = 0;
    static final int PRIO_WAKEUP = 1;
@@ -553,7 +556,7 @@ class AlarmManagerService extends SystemService {
                }
                setImplLocked(a.type, a.when, whenElapsed, a.windowLength, maxElapsed,
                        a.repeatInterval, a.operation, batch.standalone, doValidate, a.workSource,
                        a.alarmClock, a.userId);
                        a.alarmClock, a.userId, false);
            }
        }
    }
@@ -661,6 +664,8 @@ class AlarmManagerService extends SystemService {
            Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler.");
        }

        mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);

        publishBinderService(Context.ALARM_SERVICE, mService);
    }

@@ -758,6 +763,24 @@ class AlarmManagerService extends SystemService {

        final int userId = UserHandle.getCallingUserId();

        boolean wakeupFiltered = false;
        if (operation.getCreatorUid() >= Process.FIRST_APPLICATION_UID &&
                (type == AlarmManager.RTC_WAKEUP
                        || type == AlarmManager.ELAPSED_REALTIME_WAKEUP)
                && mAppOps.checkOpNoThrow(AppOpsManager.OP_ALARM_WAKEUP,
                        operation.getCreatorUid(),
                        operation.getCreatorPackage())
                != AppOpsManager.MODE_ALLOWED) {

            if (type == AlarmManager.RTC_WAKEUP) {
                type = AlarmManager.RTC;
            } else {
                type = AlarmManager.ELAPSED_REALTIME;
            }

            wakeupFiltered = true;
        }

        synchronized (mLock) {
            if (DEBUG_BATCH) {
                Slog.v(TAG, "set(" + operation + ") : type=" + type
@@ -766,17 +789,28 @@ class AlarmManagerService extends SystemService {
                        + " interval=" + interval + " standalone=" + isStandalone);
            }
            setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, maxElapsed,
                    interval, operation, isStandalone, true, workSource, alarmClock, userId);
                    interval, operation, isStandalone, true, workSource, alarmClock, userId,
                    wakeupFiltered);
        }
    }

    private void setImplLocked(int type, long when, long whenElapsed, long windowLength,
            long maxWhen, long interval, PendingIntent operation, boolean isStandalone,
            boolean doValidate, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock,
            int userId) {
            int userId, boolean wakeupFiltered) {
        Alarm a = new Alarm(type, when, whenElapsed, windowLength, maxWhen, interval,
                operation, workSource, alarmClock, userId);
        removeLocked(operation);

        // Remove this alarm if already scheduled.
        final boolean foundExistingWakeup = removeWithStatusLocked(operation);

        // note AppOp for accounting purposes
        // skip if the alarm already existed
        if (!foundExistingWakeup && wakeupFiltered) {
            mAppOps.noteOpNoThrow(AppOpsManager.OP_ALARM_WAKEUP,
                    operation.getCreatorUid(),
                    operation.getCreatorPackage());
        }

        int whichBatch = (isStandalone) ? -1 : attemptCoalesceLocked(whenElapsed, maxWhen);
        if (whichBatch < 0) {
@@ -1334,6 +1368,10 @@ class AlarmManagerService extends SystemService {
    }

    private void removeLocked(PendingIntent operation) {
        removeWithStatusLocked(operation);
    }

    private boolean removeWithStatusLocked(PendingIntent operation) {
        boolean didRemove = false;
        for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
            Batch b = mAlarmBatches.get(i);
@@ -1365,6 +1403,8 @@ class AlarmManagerService extends SystemService {
            rescheduleKernelAlarmsLocked();
            updateNextAlarmClockLocked();
        }

        return didRemove;
    }

    void removeLocked(String packageName) {
@@ -1544,7 +1584,7 @@ class AlarmManagerService extends SystemService {
                    setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength,
                            maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
                            alarm.repeatInterval, alarm.operation, batch.standalone, true,
                            alarm.workSource, alarm.alarmClock, alarm.userId);
                            alarm.workSource, alarm.alarmClock, alarm.userId, false);

                    // For now we count this as a wakeup alarm, meaning it needs to be
                    // delivered immediately.  In the future we should change this, but
@@ -1779,6 +1819,10 @@ class AlarmManagerService extends SystemService {
                        ActivityManagerNative.noteWakeupAlarm(
                                alarm.operation, -1, null);
                    }
                    // AppOps accounting
                    mAppOps.noteOpNoThrow(AppOpsManager.OP_ALARM_WAKEUP,
                            alarm.operation.getCreatorUid(),
                            alarm.operation.getCreatorPackage());
                }
            } catch (PendingIntent.CanceledException e) {
                if (alarm.repeatInterval > 0) {