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

Commit 26cac193 authored by Danesh M's avatar Danesh M Committed by Gerrit Code Review
Browse files

Merge "AppOps: Add support for whitelist of packages." into cm-10.2

parents 6328145d 6a12d12f
Loading
Loading
Loading
Loading
+83 −1
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ public class AppOpsService extends IAppOpsService.Stub {
    static final String TAG = "AppOps";
    static final boolean DEBUG = false;
    static final String STRICT_PERMISSION_PROPERTY = "persist.sys.strict_op_enable";
    static final String WHITELIST_FILE = "persist.sys.whitelist";

    // Write at most every 30 minutes.
    static final long WRITE_DELAY = DEBUG ? 1000 : 30*60*1000;
@@ -107,6 +108,8 @@ public class AppOpsService extends IAppOpsService.Stub {
        }
    };

    final ArrayList<String> mWhitelist = new ArrayList<String>();

    final SparseArray<HashMap<String, Ops>> mUidOps
            = new SparseArray<HashMap<String, Ops>>();

@@ -197,6 +200,7 @@ public class AppOpsService extends IAppOpsService.Stub {
                }
            }
        };
        readWhitelist();
        readState();
    }

@@ -534,7 +538,11 @@ public class AppOpsService extends IAppOpsService.Stub {
            return false;
        }
        return ((uid > Process.FIRST_APPLICATION_UID) &&
                (AppOpsManager.opStrict(code)));
                (AppOpsManager.opStrict(code)) && !isInWhitelist(packageName));
    }

    private boolean isInWhitelist(String packageName) {
        return mWhitelist.contains(packageName);
    }

    private void recordOperationLocked(int code, int uid, String packageName, int mode) {
@@ -868,6 +876,80 @@ public class AppOpsService extends IAppOpsService.Stub {
        return op;
    }

    void readWhitelist() {
        String whitelistFileName = SystemProperties.get(WHITELIST_FILE);
        // Read if whitelist file provided
        if (!mStrictEnable || "".equals(whitelistFileName)) {
            return;
        }
        final File whitelistFile = new File(whitelistFileName);
        final AtomicFile whitelistAtomicFile = new AtomicFile(whitelistFile);
        synchronized (mWhitelist) {
            synchronized (this) {
                FileInputStream stream;
                try {
                    stream = whitelistAtomicFile.openRead();
                } catch (FileNotFoundException e) {
                    Slog.i(TAG, "No existing app ops whitelist " + whitelistAtomicFile.getBaseFile());
                    return;
                }
                boolean success = false;
                try {
                    XmlPullParser parser = Xml.newPullParser();
                    parser.setInput(stream, null);
                    int type;
                    while ((type = parser.next()) != XmlPullParser.START_TAG
                            && type != XmlPullParser.END_DOCUMENT) {
                        ;
                    }

                    if (type != XmlPullParser.START_TAG) {
                        throw new IllegalStateException("no start tag found");
                    }

                    int outerDepth = parser.getDepth();
                    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                            && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
                        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                            continue;
                        }

                        String tagName = parser.getName();
                        if (tagName.equals("pkg")) {
                            String pkgName = parser.getAttributeValue(null, "name");
                            mWhitelist.add(pkgName);
                        } else {
                            Slog.w(TAG, "Unknown element under <whitelist-pkgs>: "
                                    + parser.getName());
                            XmlUtils.skipCurrentTag(parser);
                        }
                    }
                    success = true;
                } catch (IllegalStateException e) {
                    Slog.w(TAG, "Failed parsing " + e);
                } catch (NullPointerException e) {
                    Slog.w(TAG, "Failed parsing " + e);
                } catch (NumberFormatException e) {
                    Slog.w(TAG, "Failed parsing " + e);
                } catch (XmlPullParserException e) {
                    Slog.w(TAG, "Failed parsing " + e);
                } catch (IOException e) {
                    Slog.w(TAG, "Failed parsing " + e);
                } catch (IndexOutOfBoundsException e) {
                    Slog.w(TAG, "Failed parsing " + e);
                } finally {
                    if (!success) {
                        mWhitelist.clear();
                    }
                    try {
                        stream.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
    }

    void readState() {
        synchronized (mFile) {
            synchronized (this) {