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

Commit da3addda authored by Justin Klaassen's avatar Justin Klaassen Committed by android-build-merger
Browse files

TwilightService v2.0 am: 908b86c7 am: f7aa8bcb

am: 2f6aac33

Change-Id: I3f982ae736f33f6da20d7d197d551c1408ab2d5f
parents 16c01b04 2f6aac33
Loading
Loading
Loading
Loading
+0 −122
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 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;

import android.text.format.DateUtils;

/** @hide */
public class TwilightCalculator {

    /** Value of {@link #mState} if it is currently day */
    public static final int DAY = 0;

    /** Value of {@link #mState} if it is currently night */
    public static final int NIGHT = 1;

    private static final float DEGREES_TO_RADIANS = (float) (Math.PI / 180.0f);

    // element for calculating solar transit.
    private static final float J0 = 0.0009f;

    // correction for civil twilight
    private static final float ALTIDUTE_CORRECTION_CIVIL_TWILIGHT = -0.104719755f;

    // coefficients for calculating Equation of Center.
    private static final float C1 = 0.0334196f;
    private static final float C2 = 0.000349066f;
    private static final float C3 = 0.000005236f;

    private static final float OBLIQUITY = 0.40927971f;

    // Java time on Jan 1, 2000 12:00 UTC.
    private static final long UTC_2000 = 946728000000L;

    /**
     * Time of sunset (civil twilight) in milliseconds or -1 in the case the day
     * or night never ends.
     */
    public long mSunset;

    /**
     * Time of sunrise (civil twilight) in milliseconds or -1 in the case the
     * day or night never ends.
     */
    public long mSunrise;

    /** Current state */
    public int mState;

    /**
     * calculates the civil twilight bases on time and geo-coordinates.
     *
     * @param time time in milliseconds.
     * @param latiude latitude in degrees.
     * @param longitude latitude in degrees.
     */
    public void calculateTwilight(long time, double latiude, double longitude) {
        final float daysSince2000 = (float) (time - UTC_2000) / DateUtils.DAY_IN_MILLIS;

        // mean anomaly
        final float meanAnomaly = 6.240059968f + daysSince2000 * 0.01720197f;

        // true anomaly
        final double trueAnomaly = meanAnomaly + C1 * Math.sin(meanAnomaly) + C2
                * Math.sin(2 * meanAnomaly) + C3 * Math.sin(3 * meanAnomaly);

        // ecliptic longitude
        final double solarLng = trueAnomaly + 1.796593063d + Math.PI;

        // solar transit in days since 2000
        final double arcLongitude = -longitude / 360;
        float n = Math.round(daysSince2000 - J0 - arcLongitude);
        double solarTransitJ2000 = n + J0 + arcLongitude + 0.0053d * Math.sin(meanAnomaly)
                + -0.0069d * Math.sin(2 * solarLng);

        // declination of sun
        double solarDec = Math.asin(Math.sin(solarLng) * Math.sin(OBLIQUITY));

        final double latRad = latiude * DEGREES_TO_RADIANS;

        double cosHourAngle = (Math.sin(ALTIDUTE_CORRECTION_CIVIL_TWILIGHT) - Math.sin(latRad)
                * Math.sin(solarDec)) / (Math.cos(latRad) * Math.cos(solarDec));
        // The day or night never ends for the given date and location, if this value is out of
        // range.
        if (cosHourAngle >= 1) {
            mState = NIGHT;
            mSunset = -1;
            mSunrise = -1;
            return;
        } else if (cosHourAngle <= -1) {
            mState = DAY;
            mSunset = -1;
            mSunrise = -1;
            return;
        }

        float hourAngle = (float) (Math.acos(cosHourAngle) / (2 * Math.PI));

        mSunset = Math.round((solarTransitJ2000 + hourAngle) * DateUtils.DAY_IN_MILLIS) + UTC_2000;
        mSunrise = Math.round((solarTransitJ2000 - hourAngle) * DateUtils.DAY_IN_MILLIS) + UTC_2000;

        if (mSunrise < time && mSunset > time) {
            mState = DAY;
        } else {
            mState = NIGHT;
        }
    }

}
+17 −17
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server;

import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
@@ -155,8 +156,13 @@ final class UiModeManagerService extends SystemService {

    private final TwilightListener mTwilightListener = new TwilightListener() {
        @Override
        public void onTwilightStateChanged() {
            updateTwilight();
        public void onTwilightStateChanged(@Nullable TwilightState state) {
            synchronized (mLock) {
                if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
                    updateComputedNightModeLocked();
                    updateLocked(0, 0);
                }
            }
        }
    };

@@ -344,8 +350,8 @@ final class UiModeManagerService extends SystemService {
                    pw.print(" mSystemReady="); pw.println(mSystemReady);
            if (mTwilightManager != null) {
                // We may not have a TwilightManager.
                pw.print("  mTwilightService.getCurrentState()=");
                pw.println(mTwilightManager.getCurrentState());
                pw.print("  mTwilightService.getLastTwilightState()=");
                pw.println(mTwilightManager.getLastTwilightState());
            }
        }
    }
@@ -355,9 +361,6 @@ final class UiModeManagerService extends SystemService {
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            synchronized (mLock) {
                mTwilightManager = getLocalService(TwilightManager.class);
                if (mTwilightManager != null) {
                    mTwilightManager.registerListener(mTwilightListener, mHandler);
                }
                mSystemReady = true;
                mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
                updateComputedNightModeLocked();
@@ -411,10 +414,16 @@ final class UiModeManagerService extends SystemService {
        }

        if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
            if (mTwilightManager != null) {
                mTwilightManager.registerListener(mTwilightListener, mHandler);
            }
            updateComputedNightModeLocked();
            uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES
                    : Configuration.UI_MODE_NIGHT_NO;
        } else {
            if (mTwilightManager != null) {
                mTwilightManager.unregisterListener(mTwilightListener);
            }
            uiMode |= mNightMode << 4;
        }

@@ -668,18 +677,9 @@ final class UiModeManagerService extends SystemService {
        }
    }

    void updateTwilight() {
        synchronized (mLock) {
            if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
                updateComputedNightModeLocked();
                updateLocked(0, 0);
            }
        }
    }

    private void updateComputedNightModeLocked() {
        if (mTwilightManager != null) {
            TwilightState state = mTwilightManager.getCurrentState();
            TwilightState state = mTwilightManager.getLastTwilightState();
            if (state != null) {
                mComputedNightMode = state.isNight();
            }
+9 −6
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;

import android.annotation.Nullable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
@@ -268,7 +269,7 @@ class AutomaticBrightnessController {
        pw.println();
        pw.println("Automatic Brightness Controller State:");
        pw.println("  mLightSensor=" + mLightSensor);
        pw.println("  mTwilight.getCurrentState()=" + mTwilight.getCurrentState());
        pw.println("  mTwilight.getLastTwilightState()=" + mTwilight.getLastTwilightState());
        pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
        pw.println("  mLightSensorEnableTime=" + TimeUtils.formatUptime(mLightSensorEnableTime));
        pw.println("  mAmbientLux=" + mAmbientLux);
@@ -495,12 +496,14 @@ class AutomaticBrightnessController {
        }

        if (mUseTwilight) {
            TwilightState state = mTwilight.getCurrentState();
            TwilightState state = mTwilight.getLastTwilightState();
            if (state != null && state.isNight()) {
                final long now = System.currentTimeMillis();
                gamma *= 1 + state.getAmount() * TWILIGHT_ADJUSTMENT_MAX_GAMMA;
                final long duration = state.sunriseTimeMillis() - state.sunsetTimeMillis();
                final long progress = System.currentTimeMillis() - state.sunsetTimeMillis();
                final float amount = (float) Math.pow(2.0 * progress / duration - 1.0, 2.0);
                gamma *= 1 + amount * TWILIGHT_ADJUSTMENT_MAX_GAMMA;
                if (DEBUG) {
                    Slog.d(TAG, "updateAutoBrightness: twilight amount=" + state.getAmount());
                    Slog.d(TAG, "updateAutoBrightness: twilight amount=" + amount);
                }
            }
        }
@@ -621,7 +624,7 @@ class AutomaticBrightnessController {

    private final TwilightListener mTwilightListener = new TwilightListener() {
        @Override
        public void onTwilightStateChanged() {
        public void onTwilightStateChanged(@Nullable TwilightState state) {
            updateAutoBrightness(true /*sendUpdate*/);
        }
    };
+33 −14
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -217,12 +218,12 @@ public final class NightDisplayService extends SystemService
        if (mIsActivated == null || mIsActivated != activated) {
            Slog.i(TAG, activated ? "Turning on night display" : "Turning off night display");

            mIsActivated = activated;

            if (mAutoMode != null) {
                mAutoMode.onActivated(activated);
            }

            mIsActivated = activated;

            // Cancel the old animator if still running.
            if (mColorMatrixAnimator != null) {
                mColorMatrixAnimator.cancel();
@@ -395,7 +396,9 @@ public final class NightDisplayService extends SystemService

        @Override
        public void onActivated(boolean activated) {
            if (mIsActivated != null) {
                mLastActivatedTime = Calendar.getInstance();
            }
            updateNextAlarm();
        }

@@ -424,41 +427,57 @@ public final class NightDisplayService extends SystemService

        private final TwilightManager mTwilightManager;

        private boolean mIsNight;
        private Calendar mLastActivatedTime;

        public TwilightAutoMode() {
            mTwilightManager = getLocalService(TwilightManager.class);
        }

        private void updateActivated() {
            final TwilightState state = mTwilightManager.getCurrentState();
        private void updateActivated(TwilightState state) {
            final boolean isNight = state != null && state.isNight();
            if (mIsNight != isNight) {
                mIsNight = isNight;
            boolean setActivated = mIsActivated == null || mIsActivated != isNight;
            if (setActivated && state != null && mLastActivatedTime != null) {
                final Calendar sunrise = state.sunrise();
                final Calendar sunset = state.sunset();
                if (sunrise.before(sunset)) {
                    setActivated = mLastActivatedTime.before(sunrise)
                            || mLastActivatedTime.after(sunset);
                } else {
                    setActivated = mLastActivatedTime.before(sunset)
                            || mLastActivatedTime.after(sunrise);
                }
            }

                if (mIsActivated == null || mIsActivated != isNight) {
            if (setActivated) {
                mController.setActivated(isNight);
            }
        }
        }

        @Override
        public void onStart() {
            mTwilightManager.registerListener(this, mHandler);

            // Force an update to initialize state.
            updateActivated();
            updateActivated(mTwilightManager.getLastTwilightState());
        }

        @Override
        public void onStop() {
            mTwilightManager.unregisterListener(this);
            mLastActivatedTime = null;
        }

        @Override
        public void onTwilightStateChanged() {
        public void onActivated(boolean activated) {
            if (mIsActivated != null) {
                mLastActivatedTime = Calendar.getInstance();
            }
        }

        @Override
        public void onTwilightStateChanged(@Nullable TwilightState state) {
            if (DEBUG) Slog.d(TAG, "onTwilightStateChanged");
            updateActivated();
            updateActivated(state);
        }
    }

+9 −1
Original line number Diff line number Diff line
@@ -16,6 +16,14 @@

package com.android.server.twilight;

import android.annotation.Nullable;

/**
 * Callback for when the twilight state has changed.
 */
public interface TwilightListener {
    void onTwilightStateChanged();
    /**
     * Called when the twilight state has changed.
     */
    void onTwilightStateChanged(@Nullable TwilightState state);
}
 No newline at end of file
Loading