File indexing completed on 2024-12-22 04:41:40

0001 /*
0002  * SPDX-FileCopyrightText: 2015 Vineet Garg <grg.vineet@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 package org.kde.kdeconnect.Plugins.NotificationsPlugin;
0008 
0009 import android.content.ContentValues;
0010 import android.content.Context;
0011 import android.content.SharedPreferences;
0012 import android.database.Cursor;
0013 import android.database.sqlite.SQLiteDatabase;
0014 import android.database.sqlite.SQLiteOpenHelper;
0015 import android.util.Log;
0016 
0017 import java.util.HashSet;
0018 
0019 class AppDatabase {
0020 
0021     static final private HashSet<String> disabledByDefault = new HashSet<>();
0022     static {
0023         disabledByDefault.add("com.google.android.googlequicksearchbox"); //Google Now notifications re-spawn every few minutes
0024     }
0025 
0026     private static final String SETTINGS_NAME = "app_database";
0027     private static final String SETTINGS_KEY_ALL_ENABLED = "all_enabled";
0028 
0029     private static final int DATABASE_VERSION = 5;
0030     private static final String DATABASE_NAME = "Applications";
0031     private static final String TABLE_ENABLED = "Applications";
0032     private static final String TABLE_PRIVACY = "PrivacyOpts";
0033     private static final String KEY_PACKAGE_NAME = "packageName";
0034     private static final String KEY_IS_ENABLED = "isEnabled";
0035     private static final String KEY_PRIVACY_OPTIONS = "privacyOptions";
0036 
0037 
0038     private static final String DATABASE_CREATE_ENABLED = "CREATE TABLE "
0039             + TABLE_ENABLED + "(" + KEY_PACKAGE_NAME + " TEXT PRIMARY KEY NOT NULL, "
0040             + KEY_IS_ENABLED + " INTEGER NOT NULL ); ";
0041     private static final String DATABASE_CREATE_PRIVACY_OPTS = "CREATE TABLE "
0042             + TABLE_PRIVACY + "(" + KEY_PACKAGE_NAME + " TEXT PRIMARY KEY NOT NULL, "
0043             + KEY_PRIVACY_OPTIONS + " INTEGER NOT NULL); ";
0044 
0045 
0046     private final SQLiteDatabase ourDatabase;
0047     private final DbHelper ourHelper;
0048     private final SharedPreferences prefs;
0049 
0050     AppDatabase(Context context, boolean readonly) {
0051         ourHelper = new DbHelper(context);
0052         prefs = context.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE);
0053         if (readonly) {
0054             ourDatabase = ourHelper.getReadableDatabase();
0055         } else {
0056             ourDatabase = ourHelper.getWritableDatabase();
0057         }
0058     }
0059 
0060     @Override
0061     protected void finalize() throws Throwable {
0062         ourHelper.close();
0063         super.finalize();
0064     }
0065 
0066     private static class DbHelper extends SQLiteOpenHelper {
0067 
0068         DbHelper(Context context) {
0069             super(context, DATABASE_NAME, null, DATABASE_VERSION);
0070         }
0071 
0072         @Override
0073         public void onCreate(SQLiteDatabase db) {
0074             db.execSQL(DATABASE_CREATE_ENABLED);
0075             db.execSQL(DATABASE_CREATE_PRIVACY_OPTS);
0076         }
0077 
0078         @Override
0079         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
0080             if (oldVersion < 5) {
0081                 db.execSQL(DATABASE_CREATE_PRIVACY_OPTS);
0082             }
0083         }
0084 
0085     }
0086 
0087     void setEnabled(String packageName, boolean isEnabled) {
0088         String[] columns = new String[]{KEY_IS_ENABLED};
0089         try (Cursor res = ourDatabase.query(TABLE_ENABLED, columns, KEY_PACKAGE_NAME + " =? ", new String[]{packageName}, null, null, null)) {
0090             ContentValues cv = new ContentValues();
0091             cv.put(KEY_IS_ENABLED, isEnabled ? 1 : 0);
0092             if (res.getCount() > 0) {
0093                 ourDatabase.update(TABLE_ENABLED, cv, KEY_PACKAGE_NAME + "=?", new String[]{packageName});
0094             } else {
0095                 cv.put(KEY_PACKAGE_NAME, packageName);
0096                 long retVal = ourDatabase.insert(TABLE_ENABLED, null, cv);
0097                 Log.i("AppDatabase", "SetEnabled retval = " + retVal);
0098             }
0099         }
0100     }
0101 
0102     boolean getAllEnabled() {
0103         return prefs.getBoolean(SETTINGS_KEY_ALL_ENABLED, true);
0104     }
0105 
0106     void setAllEnabled(boolean enabled) {
0107         prefs.edit().putBoolean(SETTINGS_KEY_ALL_ENABLED, enabled).apply();
0108         ourDatabase.execSQL("UPDATE " + TABLE_ENABLED + " SET " + KEY_IS_ENABLED + "=" + (enabled? "1" : "0"));
0109     }
0110 
0111     boolean isEnabled(String packageName) {
0112         String[] columns = new String[]{KEY_IS_ENABLED};
0113         try (Cursor res = ourDatabase.query(TABLE_ENABLED, columns, KEY_PACKAGE_NAME + " =? ", new String[]{packageName}, null, null, null)) {
0114             boolean result;
0115             if (res.getCount() > 0) {
0116                 res.moveToFirst();
0117                 result = (res.getInt(res.getColumnIndex(KEY_IS_ENABLED)) != 0);
0118             } else {
0119                 result = getDefaultStatus(packageName);
0120             }
0121             return result;
0122         }
0123     }
0124 
0125     private boolean getDefaultStatus(String packageName) {
0126         if (disabledByDefault.contains(packageName)) {
0127             return false;
0128         }
0129         return getAllEnabled();
0130     }
0131 
0132     public enum PrivacyOptions {
0133         BLOCK_CONTENTS,
0134         BLOCK_IMAGES
0135         // Just add new enum to add a new privacy option.
0136     }
0137 
0138     private int getPrivacyOptionsValue(String packageName)
0139     {
0140         String[] columns = new String[]{KEY_PRIVACY_OPTIONS};
0141         try (Cursor res = ourDatabase.query(TABLE_PRIVACY, columns, KEY_PACKAGE_NAME + " =? ", new String[]{packageName}, null, null, null)) {
0142             int result;
0143             if (res.getCount() > 0) {
0144                 res.moveToFirst();
0145                 result = res.getInt(res.getColumnIndex(KEY_PRIVACY_OPTIONS));
0146             } else {
0147                 result = 0;
0148             }
0149             return result;
0150         }
0151     }
0152 
0153     private void setPrivacyOptionsValue(String packageName, int value) {
0154         String[] columns = new String[]{KEY_PRIVACY_OPTIONS};
0155         try (Cursor res = ourDatabase.query(TABLE_PRIVACY, columns, KEY_PACKAGE_NAME + " =? ", new String[]{packageName}, null, null, null)) {
0156             ContentValues cv = new ContentValues();
0157             cv.put(KEY_PRIVACY_OPTIONS, value);
0158             if (res.getCount() > 0) {
0159                 ourDatabase.update(TABLE_PRIVACY, cv, KEY_PACKAGE_NAME + "=?", new String[]{packageName});
0160             } else {
0161                 cv.put(KEY_PACKAGE_NAME, packageName);
0162                 long retVal = ourDatabase.insert(TABLE_PRIVACY, null, cv);
0163                 Log.i("AppDatabase", "SetPrivacyOptions retval = " + retVal);
0164             }
0165         }
0166     }
0167 
0168     /**
0169      * Set privacy option of an app.
0170      * @param packageName name of the app
0171      * @param option option of PrivacyOptions enum, that we set the value of.
0172      * @param isBlocked boolean, if user wants to block an option.
0173      */
0174     public void setPrivacy(String packageName, PrivacyOptions option, boolean isBlocked) {
0175         // Bit, that we want to change
0176         int curBit = option.ordinal();
0177         // Current value of privacy options
0178         int value = getPrivacyOptionsValue(packageName);
0179         // Make the selected bit '1'
0180         value |= (1 << curBit);
0181         // If we want to block an option, we set the selected bit to '0'.
0182         value ^= isBlocked ? 0 : (1 << curBit);
0183         // Update the value
0184         setPrivacyOptionsValue(packageName, value);
0185     }
0186 
0187     /**
0188      * Get privacy option of an app.
0189      * @param packageName name of the app
0190      * @param option option of PrivacyOptions enum, that we set the value of.
0191      * @return returns true if the option is blocking.
0192      */
0193     public boolean getPrivacy(String packageName, PrivacyOptions option) {
0194         // Bit, that we want to change
0195         int curBit = option.ordinal();
0196         // Current value of privacy options
0197         int value = getPrivacyOptionsValue(packageName);
0198         // Read the bit
0199         int bit = value & (1 << curBit);
0200         // If that bit was 0, the bit variable is 0. If not, it's some power of 2.
0201         return bit != 0;
0202     }
0203 }