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

Commit 6037ec56 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by The Android Automerger
Browse files

Add new app ops method to reset all op modes.

Change-Id: I5ee6764de8dc31d812e5a788914ab0099bbef4c0
parent 990b8e2a
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -422,6 +422,14 @@ public class AppOpsManager {
        }
    }

    /** @hide */
    public void resetAllModes() {
        try {
            mService.resetAllModes();
        } catch (RemoteException e) {
        }
    }

    public void startWatchingMode(int op, String packageName, final Callback callback) {
        synchronized (mModeWatchers) {
            IAppOpsCallback cb = mModeWatchers.get(callback);
+1 −0
Original line number Diff line number Diff line
@@ -33,4 +33,5 @@ interface IAppOpsService {
    List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
    List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
    void setMode(int code, int uid, String packageName, int mode);
    void resetAllModes();
}
+87 −15
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import android.app.AppOpsManager;
import android.content.Context;
@@ -42,6 +43,7 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.util.AtomicFile;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
@@ -288,6 +290,24 @@ public class AppOpsService extends IAppOpsService.Stub {
        }
    }

    private void pruneOp(Op op, int uid, String packageName) {
        if (op.time == 0 && op.rejectTime == 0) {
            Ops ops = getOpsLocked(uid, packageName, false);
            if (ops != null) {
                ops.remove(op.op);
                if (ops.size() <= 0) {
                    HashMap<String, Ops> pkgOps = mUidOps.get(uid);
                    if (pkgOps != null) {
                        pkgOps.remove(ops.packageName);
                        if (pkgOps.size() <= 0) {
                            mUidOps.remove(uid);
                        }
                    }
                }
            }
        }
    }

    @Override
    public void setMode(int code, int uid, String packageName, int mode) {
        verifyIncomingUid(uid);
@@ -316,35 +336,87 @@ public class AppOpsService extends IAppOpsService.Stub {
                    if (mode == AppOpsManager.MODE_ALLOWED) {
                        // If going into the default mode, prune this op
                        // if there is nothing else interesting in it.
                        if (op.time == 0 && op.rejectTime == 0) {
                            Ops ops = getOpsLocked(uid, packageName, false);
                            if (ops != null) {
                                ops.remove(op.op);
                                if (ops.size() <= 0) {
                                    HashMap<String, Ops> pkgOps = mUidOps.get(uid);
                                    if (pkgOps != null) {
                                        pkgOps.remove(ops.packageName);
                                        if (pkgOps.size() <= 0) {
                                            mUidOps.remove(uid);
                        pruneOp(op, uid, packageName);
                    }
                    scheduleWriteNowLocked();
                }
            }
        }
        if (repCbs != null) {
            for (int i=0; i<repCbs.size(); i++) {
                try {
                    repCbs.get(i).mCallback.opChanged(code, packageName);
                } catch (RemoteException e) {
                }
            }
                    scheduleWriteNowLocked();
        }
    }

    private static HashMap<Callback, ArrayList<Pair<String, Integer>>> addCallbacks(
            HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks,
            String packageName, int op, ArrayList<Callback> cbs) {
        if (cbs == null) {
            return callbacks;
        }
        if (callbacks == null) {
            callbacks = new HashMap<Callback, ArrayList<Pair<String, Integer>>>();
        }
        for (int i=0; i<cbs.size(); i++) {
            Callback cb = cbs.get(i);
            ArrayList<Pair<String, Integer>> reports = callbacks.get(cb);
            if (reports == null) {
                reports = new ArrayList<Pair<String, Integer>>();
                callbacks.put(cb, reports);
            }
        if (repCbs != null) {
            for (int i=0; i<repCbs.size(); i++) {
            reports.add(new Pair<String, Integer>(packageName, op));
        }
        return callbacks;
    }

    @Override
    public void resetAllModes() {
        mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
                Binder.getCallingPid(), Binder.getCallingUid(), null);
        HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks = null;
        synchronized (this) {
            boolean changed = false;
            for (int i=0; i<mUidOps.size(); i++) {
                HashMap<String, Ops> packages = mUidOps.valueAt(i);
                for (Map.Entry<String, Ops> ent : packages.entrySet()) {
                    String packageName = ent.getKey();
                    Ops pkgOps = ent.getValue();
                    for (int j=0; j<pkgOps.size(); j++) {
                        Op curOp = pkgOps.valueAt(j);
                        if (curOp.mode != AppOpsManager.MODE_ALLOWED) {
                            curOp.mode = AppOpsManager.MODE_ALLOWED;
                            changed = true;
                            callbacks = addCallbacks(callbacks, packageName, curOp.op,
                                    mOpModeWatchers.get(curOp.op));
                            callbacks = addCallbacks(callbacks, packageName, curOp.op,
                                    mPackageModeWatchers.get(packageName));
                            pruneOp(curOp, mUidOps.keyAt(i), packageName);
                        }
                    }
                }
            }
            if (changed) {
                scheduleWriteNowLocked();
            }
        }
        if (callbacks != null) {
            for (Map.Entry<Callback, ArrayList<Pair<String, Integer>>> ent : callbacks.entrySet()) {
                Callback cb = ent.getKey();
                ArrayList<Pair<String, Integer>> reports = ent.getValue();
                for (int i=0; i<reports.size(); i++) {
                    Pair<String, Integer> rep = reports.get(i);
                    try {
                    repCbs.get(i).mCallback.opChanged(code, packageName);
                        cb.mCallback.opChanged(rep.second, rep.first);
                    } catch (RemoteException e) {
                    }
                }
            }
        }
    }

    @Override
    public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) {