SecurityLogMonitor.java revision a0ea967d111b9f8e01ebbb1ac8d393270e1788b6
1cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath/* 2cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Copyright (C) 2016 The Android Open Source Project 3cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * 4cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Licensed under the Apache License, Version 2.0 (the "License"); 5cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * you may not use this file except in compliance with the License. 6cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * You may obtain a copy of the License at 7cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * 8cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * http://www.apache.org/licenses/LICENSE-2.0 9cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * 10cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Unless required by applicable law or agreed to in writing, software 11cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * distributed under the License is distributed on an "AS IS" BASIS, 12cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * See the License for the specific language governing permissions and 14cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * limitations under the License. 15cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */ 16cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 17ab762bb740405d0fefcccf4a0899a234f995be13Narayan Kamathpackage com.android.server.devicepolicy; 18cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 19cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport android.app.admin.DeviceAdminReceiver; 20cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport android.auditing.SecurityLog; 21cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport android.auditing.SecurityLog.SecurityEvent; 22cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport android.util.Log; 23cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport android.util.Slog; 24cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 25cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport com.android.internal.annotations.GuardedBy; 26cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 27cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport java.io.IOException; 28cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport java.util.ArrayList; 29cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport java.util.List; 30cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport java.util.concurrent.TimeUnit; 31cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport java.util.concurrent.locks.Lock; 32cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport java.util.concurrent.locks.ReentrantLock; 33cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 34cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport android.os.Process; 35cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 36cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath/** 37cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * A class managing access to the security logs. It maintains an internal buffer of pending 38cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * logs to be retrieved by the device owner. The logs are retrieved from the logd daemon via 39cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * JNI binding, and kept until device owner has retrieved to prevent loss of logs. Access to 40cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * the logs from the device owner is rate-limited, and device owner is notified when the logs 41cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * are ready to be retrieved. This happens every two hours, or when our internal buffer is 42cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * larger than a certain threshold. 43cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */ 44cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathclass SecurityLogMonitor implements Runnable { 45cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private final DevicePolicyManagerService mService; 46cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 47cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private final Lock mLock = new ReentrantLock(); 48cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 49cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath SecurityLogMonitor(DevicePolicyManagerService service) { 50cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mService = service; 51cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 52cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 53cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private static final boolean DEBUG = false; 54cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private static final String TAG = "SecurityLogMonitor"; 55cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath /** 56cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Each log entry can hold up to 4K bytes (but as of {@link android.os.Build.VERSION_CODES#N} 57cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * it should be less than 100 bytes), setting 1024 entries as the threshold to notify Device 58cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Owner. 59cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */ 60cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private static final int BUFFER_ENTRIES_NOTIFICATION_LEVEL = 1024; 61cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath /** 62cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * The maximum number of entries we should store before dropping earlier logs, to limit the 63cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * memory usage. 64cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */ 65cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private static final int BUFFER_ENTRIES_MAXIMUM_LEVEL = BUFFER_ENTRIES_NOTIFICATION_LEVEL * 10; 66cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath /** 67cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * How often should Device Owner be notified under normal circumstances. 68cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */ 69cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private static final long RATE_LIMIT_INTERVAL_MILLISECONDS = TimeUnit.HOURS.toMillis(2); 70cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath /** 71cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Internally how often should the monitor poll the security logs from logd. 72cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */ 73cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private static final long POLLING_INTERVAL_MILLISECONDS = TimeUnit.MINUTES.toMillis(1); 74cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 75cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @GuardedBy("mLock") 76cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private Thread mMonitorThread = null; 77cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @GuardedBy("mLock") 78cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private ArrayList<SecurityEvent> mPendingLogs = new ArrayList<SecurityEvent>(); 79cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @GuardedBy("mLock") 80cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private boolean mAllowedToRetrieve = false; 81cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // When DO will be allowed to retrieves the log, in milliseconds. 82cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @GuardedBy("mLock") 83cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private long mNextAllowedRetrivalTimeMillis = -1; 84cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 85cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath void start() { 86cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mLock.lock(); 87cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 88cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (mMonitorThread == null) { 89cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mPendingLogs = new ArrayList<SecurityEvent>(); 90cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mAllowedToRetrieve = false; 91cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mNextAllowedRetrivalTimeMillis = -1; 92cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 93cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mMonitorThread = new Thread(this); 94cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mMonitorThread.start(); 95cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 96cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } finally { 97cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mLock.unlock(); 98cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 99cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 100cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 101cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath void stop() { 102cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mLock.lock(); 103cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 104cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (mMonitorThread != null) { 105cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mMonitorThread.interrupt(); 106cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 107cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mMonitorThread.join(TimeUnit.SECONDS.toMillis(5)); 108cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (InterruptedException e) { 109cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Log.e(TAG, "Interrupted while waiting for thread to stop", e); 110cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 111cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Reset state and clear buffer 112cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mPendingLogs = new ArrayList<SecurityEvent>(); 113cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mAllowedToRetrieve = false; 114cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mNextAllowedRetrivalTimeMillis = -1; 115cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mMonitorThread = null; 116cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 117cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } finally { 118cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mLock.unlock(); 119cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 120cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 121cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 122cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath /** 123cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Returns the new batch of logs since the last call to this method. Returns null if 124cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * rate limit is exceeded. 125cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */ 126cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath List<SecurityEvent> retrieveLogs() { 127cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mLock.lock(); 128cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 129cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (mAllowedToRetrieve) { 130cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mAllowedToRetrieve = false; 131cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mNextAllowedRetrivalTimeMillis = System.currentTimeMillis() 132cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath + RATE_LIMIT_INTERVAL_MILLISECONDS; 133cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath List<SecurityEvent> result = mPendingLogs; 134cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mPendingLogs = new ArrayList<SecurityEvent>(); 135cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath return result; 136cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } else { 137cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath return null; 138cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 139cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } finally { 140cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mLock.unlock(); 141cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 142cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 143cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 144cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 145cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void run() { 146cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 147cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 148cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ArrayList<SecurityEvent> logs = new ArrayList<SecurityEvent>(); 149cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // The timestamp of the latest log entry that has been read, in nanoseconds 150cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath long lastLogTimestampNanos = -1; 151cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath while (!Thread.currentThread().isInterrupted()) { 152cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 153cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Thread.sleep(POLLING_INTERVAL_MILLISECONDS); 154cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 155cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (lastLogTimestampNanos < 0) { 156cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Non-blocking read that returns all logs immediately. 157cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (DEBUG) Slog.d(TAG, "SecurityLog.readEvents"); 158cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath SecurityLog.readEvents(logs); 159cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } else { 160cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (DEBUG) Slog.d(TAG, 161cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "SecurityLog.readEventsSince: " + lastLogTimestampNanos); 162cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Non-blocking read that returns all logs >= the timestamp immediately. 163cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath SecurityLog.readEventsSince(lastLogTimestampNanos + 1, logs); 164cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 165cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (!logs.isEmpty()) { 166cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (DEBUG) Slog.d(TAG, "processing new logs"); 167cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mLock.lockInterruptibly(); 168cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 169cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mPendingLogs.addAll(logs); 170cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (mPendingLogs.size() > BUFFER_ENTRIES_MAXIMUM_LEVEL) { 171cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Truncate buffer down to half of BUFFER_ENTRIES_MAXIMUM_LEVEL 172cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mPendingLogs = new ArrayList<SecurityEvent>(mPendingLogs.subList( 173cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mPendingLogs.size() - (BUFFER_ENTRIES_MAXIMUM_LEVEL / 2), 174cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mPendingLogs.size())); 175cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 176cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } finally { 177cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mLock.unlock(); 178cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 179cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath lastLogTimestampNanos = logs.get(logs.size() - 1).getTimeNanos(); 180cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath logs.clear(); 181cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 182cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath notifyDeviceOwnerIfNeeded(); 183cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (IOException e) { 184cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Log.e(TAG, "Failed to read security log", e); 185cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (InterruptedException e) { 186cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Log.i(TAG, "Thread interrupted, exiting.", e); 187cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // We are asked to stop. 188cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath break; 189cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 190cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 191cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (DEBUG) Slog.d(TAG, "MonitorThread exit."); 192cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 193cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 194cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private void notifyDeviceOwnerIfNeeded() throws InterruptedException { 195cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath boolean shouldNotifyDO = false; 196cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath boolean allowToRetrieveNow = false; 197cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mLock.lockInterruptibly(); 198cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 199cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath int logSize = mPendingLogs.size(); 200cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (logSize >= BUFFER_ENTRIES_NOTIFICATION_LEVEL) { 201cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Allow DO to retrieve logs if too many pending logs 202cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath allowToRetrieveNow = true; 203cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } else if (logSize > 0) { 204cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (mNextAllowedRetrivalTimeMillis == -1 || 205cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath System.currentTimeMillis() >= mNextAllowedRetrivalTimeMillis) { 206cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Rate limit reset 207cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath allowToRetrieveNow = true; 208cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 209cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 210cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath shouldNotifyDO = (!mAllowedToRetrieve) && allowToRetrieveNow; 211cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mAllowedToRetrieve = allowToRetrieveNow; 212cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } finally { 213cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mLock.unlock(); 214cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 215cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (shouldNotifyDO) { 216cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (DEBUG) Slog.d(TAG, "notify DO"); 217cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath mService.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_SECURITY_LOGS_AVAILABLE, 218cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath null); 219cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 220cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 221cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath} 222cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath