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

Commit 16548a3e authored by Chris Tate's avatar Chris Tate Committed by Android (Google) Code Review
Browse files

Merge "Don't full-data back up apps in foreground-equivalent state"

parents 09600102 63fec3ef
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -2842,6 +2842,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            reply.writeNoException();
            return true;
        }
        case IS_APP_FOREGROUND_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            final int userHandle = data.readInt();
            final boolean isForeground = isAppForeground(userHandle);
            reply.writeNoException();
            reply.writeInt(isForeground ? 1 : 0);
            return true;
        }
        }

        return super.onTransact(code, data, reply, flags);
@@ -6639,5 +6647,18 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
    }

    @Override
    public boolean isAppForeground(int uid) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(uid);
        mRemote.transact(IS_APP_FOREGROUND_TRANSACTION, data, reply, 0);
        final boolean isForeground = reply.readInt() == 1 ? true : false;
        data.recycle();
        reply.recycle();
        return isForeground;
    };

    private IBinder mRemote;
}
+3 −0
Original line number Diff line number Diff line
@@ -589,6 +589,8 @@ public interface IActivityManager extends IInterface {

    public void setVrMode(IBinder token, boolean enabled) throws RemoteException;

    public boolean isAppForeground(int uid) throws RemoteException;

    /*
     * Private non-Binder interfaces
     */
@@ -960,4 +962,5 @@ public interface IActivityManager extends IInterface {
    int SET_VR_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 359;
    int GET_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 360;
    int CLEAR_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 361;
    int IS_APP_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 362;
}
+65 −23
Original line number Diff line number Diff line
@@ -239,6 +239,11 @@ public class BackupManagerService {
    // How long between attempts to perform a full-data backup of any given app
    static final long MIN_FULL_BACKUP_INTERVAL = 1000 * 60 * 60 * 24; // one day

    // If an app is busy when we want to do a full-data backup, how long to defer the retry.
    // This is fuzzed, so there are two parameters; backoff_min + Rand[0, backoff_fuzz)
    static final long BUSY_BACKOFF_MIN_MILLIS = 1000 * 60 * 60;  // one hour
    static final int BUSY_BACKOFF_FUZZ = 1000 * 60 * 60 * 2;  // two hours

    Context mContext;
    private PackageManager mPackageManager;
    IPackageManager mPackageManagerBinder;
@@ -4496,10 +4501,14 @@ public class BackupManagerService {
                return false;
            }

            // At this point we know that we have work to do, just not right now.  Any
            // exit without actually running backups will also require that we
            // At this point we know that we have work to do, but possibly not right now.
            // Any exit without actually running backups will also require that we
            // reschedule the job.
            boolean runBackup = true;
            boolean headBusy;

            do {
                headBusy = false;

                if (!fullBackupAllowable(getTransport(mCurrentTransport))) {
                    if (MORE_DEBUG) {
@@ -4523,8 +4532,41 @@ public class BackupManagerService {
                        }
                        // Wait until the next app in the queue falls due for a full data backup
                        latency = MIN_FULL_BACKUP_INTERVAL - timeSinceRun;
                        break;  // we know we aren't doing work yet, so bail.
                    }

                    try {
                        PackageInfo appInfo = mPackageManager.getPackageInfo(entry.packageName, 0);
                        headBusy = mActivityManager.isAppForeground(appInfo.applicationInfo.uid);

                        if (headBusy) {
                            final long nextEligible = System.currentTimeMillis()
                                    + BUSY_BACKOFF_MIN_MILLIS
                                    + mTokenGenerator.nextInt(BUSY_BACKOFF_FUZZ);
                            if (DEBUG_SCHEDULING) {
                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                Slog.i(TAG, "Full backup time but " + entry.packageName
                                        + " is busy; deferring to "
                                        + sdf.format(new Date(nextEligible)));
                            }
                            // This relocates the app's entry from the head of the queue to
                            // its order-appropriate position further down, so upon looping
                            // a new candidate will be considered at the head.
                            enqueueFullBackup(entry.packageName,
                                    nextEligible - MIN_FULL_BACKUP_INTERVAL);
                        }

                    } catch (NameNotFoundException nnf) {
                        // So, we think we want to back this up, but it turns out the package
                        // in question is no longer installed.  We want to drop it from the
                        // queue entirely and move on, but if there's nothing else in the queue
                        // we should bail entirely.  headBusy cannot have been set to true yet.
                        runBackup = (mFullBackupQueue.size() > 1);
                    } catch (RemoteException e) {
                        // Cannot happen; the Activity Manager is in the same process
                    }
                }
            } while (headBusy);

            if (!runBackup) {
                if (DEBUG_SCHEDULING) {
@@ -4539,7 +4581,7 @@ public class BackupManagerService {
                return false;
            }

            // Okay, the top thing is runnable now.  Pop it off and get going.
            // Okay, the top thing is ready for backup now.  Do it.
            mFullBackupQueue.remove(0);
            CountDownLatch latch = new CountDownLatch(1);
            String[] pkg = new String[] {entry.packageName};
+12 −1
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.server.am;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.AssistUtils;
@@ -240,6 +239,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import dalvik.system.VMRuntime;
import libcore.io.IoUtils;
import libcore.util.EmptyArray;
@@ -7255,6 +7255,17 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
    }
    @Override
    public boolean isAppForeground(int uid) throws RemoteException {
        synchronized (this) {
            UidRecord uidRec = mActiveUids.get(uid);
            if (uidRec == null || uidRec.idle) {
                return false;
            }
            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
        }
    }
    @Override
    public boolean inMultiWindowMode(IBinder token) {
        final long origId = Binder.clearCallingIdentity();