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

Commit e26c97b5 authored by yro's avatar yro
Browse files

Remove bad configs by counting the number of statsd deaths

Bug: 75968642
Test: manual testing, statsd_test, cts test
Change-Id: Ie23e9003163b8dc554bcdc9811850091cd894000
parent 68256e09
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -20,5 +20,5 @@ service statsd /system/bin/statsd

on post-fs-data
    # Create directory for statsd
    mkdir /data/misc/stats-data/ 0770 statsd statsd
    mkdir /data/misc/stats-service/ 0770 statsd statsd
    mkdir /data/misc/stats-data/ 0770 statsd system
    mkdir /data/misc/stats-service/ 0770 statsd system
+68 −11
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.os.BatteryStatsInternal;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.IStatsCompanionService;
import android.os.IStatsManager;
@@ -68,14 +69,21 @@ import com.android.internal.os.KernelUidCpuFreqTimeReader;
import com.android.internal.os.KernelWakelockReader;
import com.android.internal.os.KernelWakelockStats;
import com.android.internal.os.PowerProfile;
import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;

import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
@@ -89,14 +97,17 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
     * How long to wait on an individual subsystem to return its stats.
     */
    private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000;
    private static final long MILLIS_IN_A_DAY = TimeUnit.DAYS.toMillis(1);

    public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
    public static final String CONFIG_DIR = "/data/misc/stats-service";

    static final String TAG = "StatsCompanionService";
    static final boolean DEBUG = false;

    public static final int CODE_DATA_BROADCAST = 1;
    public static final int CODE_SUBSCRIBER_BROADCAST = 1;
    public static final int DEATH_THRESHOLD = 10;

    private final Context mContext;
    private final AlarmManager mAlarmManager;
@@ -119,6 +130,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
            new StatFs(Environment.getRootDirectory().getAbsolutePath());
    private final StatFs mStatFsTemp =
            new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
    @GuardedBy("sStatsdLock")
    private final HashSet<Long> mDeathTimeMillis = new HashSet<>();
    @GuardedBy("sStatsdLock")
    private final HashMap<Long, String> mDeletedFiles = new HashMap<>();

    private KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
    private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
@@ -156,7 +171,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
                        informAllUidsLocked(context);
                    } catch (RemoteException e) {
                        Slog.e(TAG, "Failed to inform statsd latest update of all apps", e);
                        forgetEverything();
                        forgetEverythingLocked();
                    }
                }
            }
@@ -1055,7 +1070,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
                    sStatsd.asBinder().linkToDeath(new StatsdDeathRecipient(), 0);
                } catch (RemoteException e) {
                    Slog.e(TAG, "linkToDeath(StatsdDeathRecipient) failed", e);
                    forgetEverything();
                    forgetEverythingLocked();
                }
                // Setup broadcast receiver for updates.
                IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REPLACED);
@@ -1087,7 +1102,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
                Slog.i(TAG, "Told statsd that StatsCompanionService is alive.");
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to inform statsd that statscompanion is ready", e);
                forgetEverything();
                forgetEverythingLocked();
            }
        }
    }
@@ -1096,12 +1111,37 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
        @Override
        public void binderDied() {
            Slog.i(TAG, "Statsd is dead - erase all my knowledge.");
            forgetEverything();
            synchronized (sStatsdLock) {
                long now = SystemClock.elapsedRealtime();
                for (Long timeMillis : mDeathTimeMillis) {
                    long ageMillis = now - timeMillis;
                    if (ageMillis > MILLIS_IN_A_DAY) {
                        mDeathTimeMillis.remove(timeMillis);
                    }
                }
                for (Long timeMillis : mDeletedFiles.keySet()) {
                    long ageMillis = now - timeMillis;
                    if (ageMillis > MILLIS_IN_A_DAY * 7) {
                        mDeletedFiles.remove(timeMillis);
                    }
                }
                mDeathTimeMillis.add(now);
                if (mDeathTimeMillis.size() >= DEATH_THRESHOLD) {
                    mDeathTimeMillis.clear();
                    File[] configs = FileUtils.listFilesOrEmpty(new File(CONFIG_DIR));
                    if (configs.length > 0) {
                        String fileName = configs[0].getName();
                        if (configs[0].delete()) {
                            mDeletedFiles.put(now, fileName);
                        }
                    }
                }
                forgetEverythingLocked();
            }
        }
    }

    private void forgetEverything() {
        synchronized (sStatsdLock) {
    private void forgetEverythingLocked() {
        sStatsd = null;
        mContext.unregisterReceiver(mAppUpdateReceiver);
        mContext.unregisterReceiver(mUserUpdateReceiver);
@@ -1109,6 +1149,23 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
        cancelAnomalyAlarm();
        cancelPullingAlarm();
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
        if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;

        synchronized (sStatsdLock) {
            writer.println("Number of configuration files deleted: " + mDeletedFiles.size());
            if (mDeletedFiles.size() > 0) {
                writer.println("  timestamp, deleted file name");
            }
            long lastBootMillis =
                    SystemClock.currentThreadTimeMillis() - SystemClock.elapsedRealtime();
            for (Long elapsedMillis : mDeletedFiles.keySet()) {
                long deletionMillis = lastBootMillis + elapsedMillis;
                writer.println("  " + deletionMillis + ", " + mDeletedFiles.get(elapsedMillis));
            }
        }
    }

}