1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-29 08:20:16 +02:00
Gadgetbridge/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/PeriodicExporter.java

148 lines
6.0 KiB
Java
Raw Normal View History

/* Copyright (C) 2018-2024 Carsten Pfeiffer, Felix Konstantin Maurer,
Ganblejs, José Rebelo, Petr Vaněk
2018-02-26 14:27:32 +01:00
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
2018-01-04 15:13:06 +01:00
package nodomain.freeyourgadget.gadgetbridge.database;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
import android.os.Build;
2018-01-04 15:13:06 +01:00
import android.os.SystemClock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.OutputStream;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
2018-01-07 12:50:59 +01:00
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
2018-01-08 11:27:28 +01:00
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
import nodomain.freeyourgadget.gadgetbridge.util.PendingIntentUtils;
2018-01-08 12:07:39 +01:00
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
2018-01-04 15:13:06 +01:00
/**
* Created by maufl on 1/4/18.
*/
public class PeriodicExporter extends BroadcastReceiver {
private static final Logger LOG = LoggerFactory.getLogger(PeriodicExporter.class);
public static final String ACTION_DATABASE_EXPORT_SUCCESS = "nodomain.freeyourgadget.gadgetbridge.action.DATABASE_EXPORT_SUCCESS";
public static final String ACTION_DATABASE_EXPORT_FAIL = "nodomain.freeyourgadget.gadgetbridge.action.DATABASE_EXPORT_FAIL";
2018-01-08 12:07:39 +01:00
public static void enablePeriodicExport(Context context) {
Prefs prefs = GBApplication.getPrefs();
GBApplication gbApp = GBApplication.app();
long autoExportScheduled = gbApp.getAutoExportScheduledTimestamp();
2018-01-08 12:07:39 +01:00
boolean autoExportEnabled = prefs.getBoolean(GBPrefs.AUTO_EXPORT_ENABLED, false);
Integer autoExportInterval = prefs.getInt(GBPrefs.AUTO_EXPORT_INTERVAL, 0);
scheduleAlarm(context, autoExportInterval, autoExportEnabled && autoExportScheduled == 0);
2018-01-08 12:07:39 +01:00
}
2018-01-04 15:13:06 +01:00
public static void scheduleAlarm(Context context, Integer autoExportInterval, boolean autoExportEnabled) {
2018-01-04 15:13:06 +01:00
Intent i = new Intent(context, PeriodicExporter.class);
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
PendingIntent pi = PendingIntentUtils.getBroadcast(context, 0, i, 0, false);
2018-01-04 15:13:06 +01:00
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(pi);
if (!autoExportEnabled) {
LOG.info("Not scheduling periodic export, either already scheduled or not enabled");
2018-01-04 15:13:06 +01:00
return;
}
2018-01-08 12:07:39 +01:00
int exportPeriod = autoExportInterval * 60 * 60 * 1000;
2018-01-04 15:13:06 +01:00
if (exportPeriod == 0) {
LOG.info("Not scheduling periodic export, interval set to 0");
2018-01-04 15:13:06 +01:00
return;
}
LOG.info("Scheduling periodic export");
GBApplication gbApp = GBApplication.app();
gbApp.setAutoExportScheduledTimestamp(System.currentTimeMillis() + exportPeriod);
2018-01-04 15:13:06 +01:00
am.setInexactRepeating(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + exportPeriod,
exportPeriod,
pi
);
}
@Override
public void onReceive(Context context, Intent intent) {
LOG.info("Received command to export DB");
createRefreshTask("Export database", context).execute();
}
protected RefreshTask createRefreshTask(String task, Context context) {
return new RefreshTask(task, context);
}
public class RefreshTask extends DBAccess {
Context localContext;
public RefreshTask(String task, Context context) {
super(task, context);
localContext = context;
}
@Override
protected void doInBackground(DBHandler handler) {
LOG.info("Exporting DB in a background thread");
try (DBHandler dbHandler = GBApplication.acquireDB()) {
DBHelper helper = new DBHelper(localContext);
String dst = GBApplication.getPrefs().getString(GBPrefs.AUTO_EXPORT_LOCATION, null);
if (dst == null) {
LOG.warn("Unable to export DB, export location not set");
broadcastSuccess(false);
return;
}
Uri dstUri = Uri.parse(dst);
try (OutputStream out = localContext.getContentResolver().openOutputStream(dstUri)) {
helper.exportDB(dbHandler, out);
GBApplication gbApp = GBApplication.app();
gbApp.setLastAutoExportTimestamp(System.currentTimeMillis());
}
broadcastSuccess(true);
LOG.info("DB export completed");
} catch (Exception ex) {
GB.updateExportFailedNotification(localContext.getString(R.string.notif_export_failed_title), localContext);
LOG.info("Exception while exporting DB: ", ex);
broadcastSuccess(false);
}
}
private void broadcastSuccess(final boolean success) {
if (!GBApplication.getPrefs().getBoolean("intent_api_broadcast_export", false)) {
return;
}
LOG.info("Broadcasting database export success={}", success);
final String action = success ? ACTION_DATABASE_EXPORT_SUCCESS : ACTION_DATABASE_EXPORT_FAIL;
final Intent exportedNotifyIntent = new Intent(action);
localContext.sendBroadcast(exportedNotifyIntent);
}
@Override
protected void onPostExecute(Object o) {
2018-01-04 15:13:06 +01:00
}
}
}