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

Verified Commit 0352d108 authored by Fahim M. Choudhury's avatar Fahim M. Choudhury
Browse files

feat: relogin users to murena.io for recovery

parent 9a290f19
Loading
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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"
+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;
@@ -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;
@@ -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() {
+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

@@ -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()
}

    /**
+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;
@@ -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;
@@ -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) {
@@ -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();
        }

+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

@@ -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"
}