Loading app/src/main/AndroidManifest.xml +4 −1 Original line number Diff line number Diff line Loading @@ -110,6 +110,9 @@ <intent-filter> <action android:name="android.accounts.action.ACCOUNT_REMOVED"/> </intent-filter> <intent-filter> <action android:name="foundation.e.drive.action.ACCOUNT_REMOVED"/> </intent-filter> </receiver> <receiver android:name=".account.receivers.AccountAddedReceiver" Loading app/src/main/java/foundation/e/drive/EdriveApplication.java +58 −5 Original line number Diff line number Diff line /* * Copyright © ECORP SAS 2022-2023. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * Copyright (C) 2025 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package foundation.e.drive; Loading @@ -13,11 +22,14 @@ import static timber.log.Timber.DebugTree; import android.accounts.Account; import android.accounts.AccountManager; import android.app.Application; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import androidx.annotation.NonNull; import foundation.e.drive.account.AccountUtils; import foundation.e.drive.database.FailedSyncPrefsManager; import foundation.e.drive.fileObservers.FileObserverManager; import foundation.e.drive.utils.AppConstants; Loading Loading @@ -59,6 +71,47 @@ public class EdriveApplication extends Application { } FailedSyncPrefsManager.getInstance(getApplicationContext()).clearPreferences(); setupEdriveRecovery(); } private void setupEdriveRecovery() { final SharedPreferences prefs = getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); boolean isDataAlreadyRecovered = prefs.getBoolean(AppConstants.IS_DATA_ALREADY_RECOVERED, false); if (!isDataAlreadyRecovered) { Timber.d("Data recovery is needed for eDrive to sync with cloud"); String accountName = AccountUtils.getAccount(getApplicationContext()).name; String accountType = getString(R.string.eelo_account_type); // Account removal Intent accountRemovedIntent = new Intent("foundation.e.drive.action.ACCOUNT_REMOVED"); accountRemovedIntent.setComponent(new ComponentName("foundation.e.drive", "foundation.e.drive.account.receivers.AccountRemoveCallbackReceiver")); accountRemovedIntent.putExtra(AccountManager.KEY_ACCOUNT_NAME, accountName); accountRemovedIntent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType); Timber.d("Sending foundation.e.drive.action.ACCOUNT_REMOVED for eDrive data recovery: " + "account name = %s, account type = %s", accountName, accountType); getApplicationContext().sendBroadcast(accountRemovedIntent); // Account addition Intent accountAddedIntent = new Intent("foundation.e.drive.action.ADD_ACCOUNT"); accountAddedIntent.setComponent(new ComponentName("foundation.e.drive", "foundation.e.drive.account.receivers.AccountAddedReceiver")); accountAddedIntent.putExtra(AccountManager.KEY_ACCOUNT_NAME, accountName); accountAddedIntent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType); Timber.d("Sending foundation.e.drive.action.ADD_ACCOUNT for eDrive data recovery: " + "account name = %s, account type = %s", accountName, accountType); getApplicationContext().sendBroadcast(accountAddedIntent); } else { Timber.d("Data recovery is not necessary for eDrive."); } } synchronized public void startRecursiveFileObserver() { Loading app/src/main/java/foundation/e/drive/account/receivers/AccountAddedReceiver.kt +20 −5 Original line number Diff line number Diff line /* * Copyright © MURENA SAS 2023-2024. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * Copyright (C) 2025 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package foundation.e.drive.account.receivers Loading Loading @@ -49,6 +58,12 @@ class AccountAddedReceiver() : BroadcastReceiver() { DavClientProvider.getInstance().cleanUp() workLauncher.enqueuePeriodicUserInfoFetching() } // Update SharedPref to not trigger future recovery Timber.d("Updating IS_DATA_ALREADY_RECOVERED = true in SharedPref to not trigger future recovery") prefs.edit() .putBoolean(AppConstants.IS_DATA_ALREADY_RECOVERED, true) .apply() } /** Loading app/src/main/java/foundation/e/drive/account/receivers/AccountRemoveCallbackReceiver.java +26 −6 Original line number Diff line number Diff line /* * Copyright © ECORP SAS 2023. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * Copyright (C) 2025 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package foundation.e.drive.account.receivers; Loading @@ -25,6 +34,8 @@ import androidx.annotation.Nullable; import androidx.work.WorkManager; import java.io.File; import java.util.ArrayList; import java.util.List; import foundation.e.drive.R; import foundation.e.drive.database.DbHelper; Loading Loading @@ -94,7 +105,15 @@ public class AccountRemoveCallbackReceiver extends BroadcastReceiver { } private boolean isInvalidAction(@NonNull Intent intent) { return !"android.accounts.action.ACCOUNT_REMOVED".equals(intent.getAction()); List<String> actions = new ArrayList<>(); actions.add("android.accounts.action.ACCOUNT_REMOVED"); actions.add("foundation.e.drive.action.ACCOUNT_REMOVED"); String intentAction = intent.getAction(); boolean hasNecessaryIntentAction = actions.contains(intentAction); return !hasNecessaryIntentAction; } private void cleanSharedPreferences(@NonNull Context applicationContext, @NonNull SharedPreferences prefs) { Loading @@ -105,6 +124,7 @@ public class AccountRemoveCallbackReceiver extends BroadcastReceiver { .remove(SETUP_COMPLETED) .remove(INITIAL_FOLDER_NUMBER) .remove(AppConstants.KEY_LAST_SCAN_TIME) .remove(AppConstants.IS_DATA_ALREADY_RECOVERED) .apply(); } Loading app/src/main/java/foundation/e/drive/utils/AppConstants.kt +15 −6 Original line number Diff line number Diff line /* * Copyright © CLEUS SAS 2018-2019. * Copyright © MURENA SAS 2022-2023. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * Copyright (C) 2025 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package foundation.e.drive.utils Loading Loading @@ -34,4 +42,5 @@ object AppConstants { const val WORK_GENERIC_TAG = "eDrive" const val WORK_SETUP_TAG = "eDrive-init" const val CORRUPTED_TIMESTAMP_IN_MILLISECOND = 4294967295000L const val IS_DATA_ALREADY_RECOVERED = "is_data_already_recovered" } Loading
app/src/main/AndroidManifest.xml +4 −1 Original line number Diff line number Diff line Loading @@ -110,6 +110,9 @@ <intent-filter> <action android:name="android.accounts.action.ACCOUNT_REMOVED"/> </intent-filter> <intent-filter> <action android:name="foundation.e.drive.action.ACCOUNT_REMOVED"/> </intent-filter> </receiver> <receiver android:name=".account.receivers.AccountAddedReceiver" Loading
app/src/main/java/foundation/e/drive/EdriveApplication.java +58 −5 Original line number Diff line number Diff line /* * Copyright © ECORP SAS 2022-2023. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * Copyright (C) 2025 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package foundation.e.drive; Loading @@ -13,11 +22,14 @@ import static timber.log.Timber.DebugTree; import android.accounts.Account; import android.accounts.AccountManager; import android.app.Application; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import androidx.annotation.NonNull; import foundation.e.drive.account.AccountUtils; import foundation.e.drive.database.FailedSyncPrefsManager; import foundation.e.drive.fileObservers.FileObserverManager; import foundation.e.drive.utils.AppConstants; Loading Loading @@ -59,6 +71,47 @@ public class EdriveApplication extends Application { } FailedSyncPrefsManager.getInstance(getApplicationContext()).clearPreferences(); setupEdriveRecovery(); } private void setupEdriveRecovery() { final SharedPreferences prefs = getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); boolean isDataAlreadyRecovered = prefs.getBoolean(AppConstants.IS_DATA_ALREADY_RECOVERED, false); if (!isDataAlreadyRecovered) { Timber.d("Data recovery is needed for eDrive to sync with cloud"); String accountName = AccountUtils.getAccount(getApplicationContext()).name; String accountType = getString(R.string.eelo_account_type); // Account removal Intent accountRemovedIntent = new Intent("foundation.e.drive.action.ACCOUNT_REMOVED"); accountRemovedIntent.setComponent(new ComponentName("foundation.e.drive", "foundation.e.drive.account.receivers.AccountRemoveCallbackReceiver")); accountRemovedIntent.putExtra(AccountManager.KEY_ACCOUNT_NAME, accountName); accountRemovedIntent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType); Timber.d("Sending foundation.e.drive.action.ACCOUNT_REMOVED for eDrive data recovery: " + "account name = %s, account type = %s", accountName, accountType); getApplicationContext().sendBroadcast(accountRemovedIntent); // Account addition Intent accountAddedIntent = new Intent("foundation.e.drive.action.ADD_ACCOUNT"); accountAddedIntent.setComponent(new ComponentName("foundation.e.drive", "foundation.e.drive.account.receivers.AccountAddedReceiver")); accountAddedIntent.putExtra(AccountManager.KEY_ACCOUNT_NAME, accountName); accountAddedIntent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType); Timber.d("Sending foundation.e.drive.action.ADD_ACCOUNT for eDrive data recovery: " + "account name = %s, account type = %s", accountName, accountType); getApplicationContext().sendBroadcast(accountAddedIntent); } else { Timber.d("Data recovery is not necessary for eDrive."); } } synchronized public void startRecursiveFileObserver() { Loading
app/src/main/java/foundation/e/drive/account/receivers/AccountAddedReceiver.kt +20 −5 Original line number Diff line number Diff line /* * Copyright © MURENA SAS 2023-2024. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * Copyright (C) 2025 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package foundation.e.drive.account.receivers Loading Loading @@ -49,6 +58,12 @@ class AccountAddedReceiver() : BroadcastReceiver() { DavClientProvider.getInstance().cleanUp() workLauncher.enqueuePeriodicUserInfoFetching() } // Update SharedPref to not trigger future recovery Timber.d("Updating IS_DATA_ALREADY_RECOVERED = true in SharedPref to not trigger future recovery") prefs.edit() .putBoolean(AppConstants.IS_DATA_ALREADY_RECOVERED, true) .apply() } /** Loading
app/src/main/java/foundation/e/drive/account/receivers/AccountRemoveCallbackReceiver.java +26 −6 Original line number Diff line number Diff line /* * Copyright © ECORP SAS 2023. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * Copyright (C) 2025 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package foundation.e.drive.account.receivers; Loading @@ -25,6 +34,8 @@ import androidx.annotation.Nullable; import androidx.work.WorkManager; import java.io.File; import java.util.ArrayList; import java.util.List; import foundation.e.drive.R; import foundation.e.drive.database.DbHelper; Loading Loading @@ -94,7 +105,15 @@ public class AccountRemoveCallbackReceiver extends BroadcastReceiver { } private boolean isInvalidAction(@NonNull Intent intent) { return !"android.accounts.action.ACCOUNT_REMOVED".equals(intent.getAction()); List<String> actions = new ArrayList<>(); actions.add("android.accounts.action.ACCOUNT_REMOVED"); actions.add("foundation.e.drive.action.ACCOUNT_REMOVED"); String intentAction = intent.getAction(); boolean hasNecessaryIntentAction = actions.contains(intentAction); return !hasNecessaryIntentAction; } private void cleanSharedPreferences(@NonNull Context applicationContext, @NonNull SharedPreferences prefs) { Loading @@ -105,6 +124,7 @@ public class AccountRemoveCallbackReceiver extends BroadcastReceiver { .remove(SETUP_COMPLETED) .remove(INITIAL_FOLDER_NUMBER) .remove(AppConstants.KEY_LAST_SCAN_TIME) .remove(AppConstants.IS_DATA_ALREADY_RECOVERED) .apply(); } Loading
app/src/main/java/foundation/e/drive/utils/AppConstants.kt +15 −6 Original line number Diff line number Diff line /* * Copyright © CLEUS SAS 2018-2019. * Copyright © MURENA SAS 2022-2023. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * Copyright (C) 2025 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package foundation.e.drive.utils Loading Loading @@ -34,4 +42,5 @@ object AppConstants { const val WORK_GENERIC_TAG = "eDrive" const val WORK_SETUP_TAG = "eDrive-init" const val CORRUPTED_TIMESTAMP_IN_MILLISECOND = 4294967295000L const val IS_DATA_ALREADY_RECOVERED = "is_data_already_recovered" }