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

Commit e9a4b16e authored by Kenny Guy's avatar Kenny Guy Committed by Android (Google) Code Review
Browse files

Merge "Daily idle job for writing out brightness events."

parents 86b92f3e cfe7b70e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -173,6 +173,11 @@ public abstract class DisplayManagerInternal {
     * */
    public abstract boolean isUidPresentOnDisplay(int uid, int displayId);

    /**
     * Persist brightness slider events.
     */
    public abstract void persistBrightnessSliderEvents();

    /**
     * Describes the requested power state of the display.
     *
+5 −1
Original line number Diff line number Diff line
@@ -3958,6 +3958,10 @@
        <service android:name="com.android.server.net.watchlist.ReportWatchlistJobService"
                 android:permission="android.permission.BIND_JOB_SERVICE" >
        </service>

        <service android:name="com.android.server.display.BrightnessIdleJob"
                 android:permission="android.permission.BIND_JOB_SERVICE" >
        </service>
</application>

</manifest>
+81 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.display;


import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
import android.hardware.display.DisplayManagerInternal;
import android.util.Slog;

import com.android.server.LocalServices;

import java.util.concurrent.TimeUnit;

/**
 * JobService used to persists brightness slider events when the device
 * is idle and charging.
 */
public class BrightnessIdleJob extends JobService {

    // Must be unique within the system server uid.
    private static final int JOB_ID = 3923512;

    public static void scheduleJob(Context context) {
        JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);

        JobInfo pending = jobScheduler.getPendingJob(JOB_ID);
        JobInfo jobInfo =
                new JobInfo.Builder(JOB_ID, new ComponentName(context, BrightnessIdleJob.class))
                        .setRequiresDeviceIdle(true)
                        .setRequiresCharging(true)
                        .setPeriodic(TimeUnit.HOURS.toMillis(24)).build();

        if (pending != null && !pending.equals(jobInfo)) {
            jobScheduler.cancel(JOB_ID);
            pending = null;
        }

        if (pending == null) {
            jobScheduler.schedule(jobInfo);
        }
    }

    public static void cancelJob(Context context) {
        JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
        jobScheduler.cancel(JOB_ID);
    }

    @Override
    public boolean onStartJob(JobParameters params) {
        if (BrightnessTracker.DEBUG) {
            Slog.d(BrightnessTracker.TAG, "Scheduled write of brightness events");
        }
        DisplayManagerInternal dmi = LocalServices.getService(DisplayManagerInternal.class);
        dmi.persistBrightnessSliderEvents();
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return false;
    }
}
 No newline at end of file
+45 −5
Original line number Diff line number Diff line
@@ -61,12 +61,12 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
import java.util.ArrayList;

import java.util.Deque;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
@@ -75,8 +75,8 @@ import java.util.concurrent.TimeUnit;
 */
public class BrightnessTracker {

    private static final String TAG = "BrightnessTracker";
    private static final boolean DEBUG = false;
    static final String TAG = "BrightnessTracker";
    static final boolean DEBUG = false;

    private static final String EVENTS_FILE = "brightness_events.xml";
    private static final int MAX_EVENTS = 100;
@@ -103,6 +103,8 @@ public class BrightnessTracker {
    @GuardedBy("mEventsLock")
    private RingBuffer<BrightnessChangeEvent> mEvents
            = new RingBuffer<>(BrightnessChangeEvent.class, MAX_EVENTS);
    @GuardedBy("mEventsLock")
    private boolean mEventsDirty;
    private final Runnable mEventsWriter = () -> writeEvents();
    private volatile boolean mWriteEventsScheduled;

@@ -170,6 +172,8 @@ public class BrightnessTracker {
        intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
        mBroadcastReceiver = new Receiver();
        mInjector.registerReceiver(mContext, mBroadcastReceiver, intentFilter);

        mInjector.scheduleIdleJob(mContext);
    }

    /** Stop listening for events */
@@ -181,6 +185,7 @@ public class BrightnessTracker {
        mInjector.unregisterSensorListener(mContext, mSensorListener);
        mInjector.unregisterReceiver(mContext, mBroadcastReceiver);
        mInjector.unregisterBrightnessObserver(mContext, mSettingsObserver);
        mInjector.cancelIdleJob(mContext);
    }

    /**
@@ -211,6 +216,10 @@ public class BrightnessTracker {
                brightness, userId);
    }

    public void persistEvents() {
        scheduleWriteEvents();
    }

    private void handleBrightnessChanged() {
        if (DEBUG) {
            Slog.d(TAG, "Brightness change");
@@ -278,6 +287,7 @@ public class BrightnessTracker {
            Slog.d(TAG, "Event " + event.brightness + " " + event.packageName);
        }
        synchronized (mEventsLock) {
            mEventsDirty = true;
            mEvents.append(event);
        }
    }
@@ -291,8 +301,12 @@ public class BrightnessTracker {

    private void writeEvents() {
        mWriteEventsScheduled = false;
        // TODO kick off write on handler thread e.g. every 24 hours.
        synchronized (mEventsLock) {
            if (!mEventsDirty) {
                // Nothing to write
                return;
            }

            final AtomicFile writeTo = mInjector.getFile();
            if (writeTo == null) {
                return;
@@ -301,12 +315,14 @@ public class BrightnessTracker {
                if (writeTo.exists()) {
                    writeTo.delete();
                }
                mEventsDirty = false;
            } else {
                FileOutputStream output = null;
                try {
                    output = writeTo.startWrite();
                    writeEventsLocked(output);
                    writeTo.finishWrite(output);
                    mEventsDirty = false;
                } catch (IOException e) {
                    writeTo.failWrite(output);
                    Slog.e(TAG, "Failed to write change mEvents.", e);
@@ -317,6 +333,8 @@ public class BrightnessTracker {

    private void readEvents() {
        synchronized (mEventsLock) {
            // Read might prune events so mark as dirty.
            mEventsDirty = true;
            mEvents.clear();
            final AtomicFile readFrom = mInjector.getFile();
            if (readFrom != null && readFrom.exists()) {
@@ -344,13 +362,16 @@ public class BrightnessTracker {

        out.startTag(null, TAG_EVENTS);
        BrightnessChangeEvent[] toWrite = mEvents.toArray();
        // Clear events, code below will add back the ones that are still within the time window.
        mEvents.clear();
        if (DEBUG) {
            Slog.d(TAG, "Writing events " + toWrite.length);
        }
        final long timeCutOff = System.currentTimeMillis() - MAX_EVENT_AGE;
        final long timeCutOff = mInjector.currentTimeMillis() - MAX_EVENT_AGE;
        for (int i = 0; i < toWrite.length; ++i) {
            int userSerialNo = mInjector.getUserSerialNumber(mUserManager, toWrite[i].userId);
            if (userSerialNo != -1 && toWrite[i].timeStamp > timeCutOff) {
                mEvents.append(toWrite[i]);
                out.startTag(null, TAG_EVENT);
                out.attribute(null, ATTR_BRIGHTNESS, Integer.toString(toWrite[i].brightness));
                out.attribute(null, ATTR_TIMESTAMP, Long.toString(toWrite[i].timeStamp));
@@ -465,6 +486,17 @@ public class BrightnessTracker {
        }
    }

    public void dump(PrintWriter pw) {
        synchronized (mEventsLock) {
            pw.println("BrightnessTracker state:");
            pw.println("  mEvents.size=" + mEvents.size());
            pw.println("  mEventsDirty=" + mEventsDirty);
        }
        synchronized (mDataCollectionLock) {
            pw.println("  mLastSensorReadings.size=" + mLastSensorReadings.size());
        }
    }

    // Not allowed to keep the SensorEvent so used to copy the data we care about.
    private static class LightData {
        public float lux;
@@ -635,5 +667,13 @@ public class BrightnessTracker {
        public ActivityManager.StackInfo getFocusedStack() throws RemoteException {
            return ActivityManager.getService().getFocusedStackInfo();
        }

        public void scheduleIdleJob(Context context) {
            BrightnessIdleJob.scheduleJob(context);
        }

        public void cancelIdleJob(Context context) {
            BrightnessIdleJob.cancelJob(context);
        }
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -1285,6 +1285,9 @@ public final class DisplayManagerService extends SystemService {

            pw.println();
            mPersistentDataStore.dump(pw);

            pw.println();
            mBrightnessTracker.dump(pw);
        }
    }

@@ -1921,5 +1924,10 @@ public final class DisplayManagerService extends SystemService {
        public boolean isUidPresentOnDisplay(int uid, int displayId) {
            return isUidPresentOnDisplayInternal(uid, displayId);
        }

        @Override
        public void persistBrightnessSliderEvents() {
            mBrightnessTracker.persistEvents();
        }
    }
}
Loading