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

Commit 9a2e4207 authored by Michal Karpinski's avatar Michal Karpinski
Browse files

Change batch finalization timeout mechanism from

Handler#sendMessageDelayed() to a wakeful alarm

Messages sent with Handler#sendMessageDelayed() didn't get delivered
until the device woke up after being idle, which resulted in
potentially very long windows of logs accumulation and highly possible
network log loss from before the device becaming idle.

Bug: 34157435
Test: manual with decreased timeout over a few timeout iterations
Change-Id: I50b29b9f132856a629e28f46c022f21976bd92fb
parent 1a292884
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -1510,6 +1510,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            return (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
        }

        AlarmManager getAlarmManager() {
            return (AlarmManager) mContext.getSystemService(AlarmManager.class);
        }

        IWindowManager getIWindowManager() {
            return IWindowManager.Stub
                    .asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
@@ -2065,7 +2069,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        long token = mInjector.binderClearCallingIdentity();
        try {
            int affectedUserHandle = parent ? getProfileParentId(userHandle) : userHandle;
            AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            AlarmManager am = mInjector.getAlarmManager();
            PendingIntent pi = PendingIntent.getBroadcastAsUser(context, REQUEST_EXPIRE_PASSWORD,
                    new Intent(ACTION_EXPIRED_PASSWORD_NOTIFICATION),
                    PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT,
+28 −9
Original line number Diff line number Diff line
@@ -16,12 +16,15 @@

package com.android.server.devicepolicy;

import android.app.AlarmManager;
import android.app.AlarmManager.OnAlarmListener;
import android.app.admin.DeviceAdminReceiver;
import android.app.admin.NetworkEvent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;
@@ -42,11 +45,26 @@ final class NetworkLoggingHandler extends Handler {
    // If this value changes, update DevicePolicyManager#retrieveNetworkLogs() javadoc
    private static final int MAX_EVENTS_PER_BATCH = 1200;
    private static final long BATCH_FINALIZATION_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(90);
    private static final long BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS =
            TimeUnit.MINUTES.toMillis(30);

    static final int LOG_NETWORK_EVENT_MSG = 1;
    static final int FINALIZE_BATCH_MSG = 2;
    private static final String NETWORK_LOGGING_TIMEOUT_ALARM_TAG = "NetworkLogging.batchTimeout";

    private final DevicePolicyManagerService mDpm;
    private final AlarmManager mAlarmManager;

    private final OnAlarmListener mBatchTimeoutAlarmListener = new OnAlarmListener() {
        @Override
        public void onAlarm() {
            Log.d(TAG, "Received a batch finalization timeout alarm, finalizing "
                    + mNetworkEvents.size() + " pending events.");
            synchronized (NetworkLoggingHandler.this) {
                finalizeBatchAndNotifyDeviceOwnerLocked();
            }
        }
    };

    static final int LOG_NETWORK_EVENT_MSG = 1;

    // threadsafe as it's Handler's thread confined
    @GuardedBy("this")
@@ -68,6 +86,7 @@ final class NetworkLoggingHandler extends Handler {
    NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm) {
        super(looper);
        mDpm = dpm;
        mAlarmManager = mDpm.mInjector.getAlarmManager();
    }

    @Override
@@ -85,19 +104,19 @@ final class NetworkLoggingHandler extends Handler {
                }
                break;
            }
            case FINALIZE_BATCH_MSG: {
                synchronized (NetworkLoggingHandler.this) {
                    finalizeBatchAndNotifyDeviceOwnerLocked();
                }
            default: {
                Log.d(TAG, "NetworkLoggingHandler received an unknown of message.");
                break;
            }
        }
    }

    void scheduleBatchFinalization() {
        removeMessages(FINALIZE_BATCH_MSG);
        sendMessageDelayed(obtainMessage(FINALIZE_BATCH_MSG), BATCH_FINALIZATION_TIMEOUT_MS);
        Log.d(TAG, "Scheduled new batch finalization " + BATCH_FINALIZATION_TIMEOUT_MS
        final long when = SystemClock.elapsedRealtime() + BATCH_FINALIZATION_TIMEOUT_MS;
        mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
                BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS, NETWORK_LOGGING_TIMEOUT_ALARM_TAG,
                mBatchTimeoutAlarmListener, this);
        Log.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
                + "ms from now.");
    }