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

Commit 034d07e3 authored by Alexander Hofbauer's avatar Alexander Hofbauer Committed by Aaron Echols
Browse files

Cleanup dock battery support

Send an intent as soon as the device is undocked to get a timely update
of the SystemUI.

Adds a proper implementation of dock detection in BatteryService via
"dock_battery/device/ec_dock". This will probably have to be rewritten
in a more generic way to support other manufacturers as well (once we
support other docks at all).

Change-Id: Ib1088c118c8695fd93ba085d976ca1eb374ae71e

Conflicts:
	packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java
parent 899f5c24
Loading
Loading
Loading
Loading
+10 −18
Original line number Diff line number Diff line
@@ -45,6 +45,12 @@ public class BatteryManager {
     */
    public static final String EXTRA_PRESENT = "present";

    /**
     * Integer containing the current status constant for the dock battery.
     * @hide
     */
    public static final String EXTRA_DOCK_PRESENT = "dock_present";

    /**
     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
     * integer field containing the current battery level, from 0 to
@@ -58,12 +64,6 @@ public class BatteryManager {
     */
    public static final String EXTRA_DOCK_LEVEL = "dock_level";

    /**
     * Boolean field containing the current dock battery AC status.
     * @hide
     */
    public static final String EXTRA_DOCK_AC_ONLINE = "dock_ac_online";
    
    /**
     * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
     * integer containing the maximum battery level.
@@ -128,19 +128,11 @@ public class BatteryManager {
    public static final int BATTERY_HEALTH_COLD = 7;

    /** @hide */
    public static final int DOCK_STATE_UNKNOWN = 0;

    /** @hide */
    public static final int DOCK_STATE_UNDOCKED = 1;

    public static final int DOCK_BATTERY_STATUS_UNKNOWN = 1;
    /** @hide */
    public static final int DOCK_STATE_CHARGING = 2;

    /** @hide */
    public static final int DOCK_STATE_DOCKED = 3;

    public static final int DOCK_BATTERY_STATUS_CHARGING = 2;
    /** @hide */
    public static final int DOCK_STATE_DISCHARGING = 4;
    public static final int DOCK_BATTERY_STATUS_NOT_CHARGING = 4;

    // values of the "plugged" field in the ACTION_BATTERY_CHANGED intent.
    // These must be powers of 2.
+46 −37
Original line number Diff line number Diff line
@@ -42,20 +42,20 @@ public class DockBatteryController extends BroadcastReceiver {

    private static final int BATTERY_STYLE_NORMAL = 0;
    private static final int BATTERY_STYLE_TEXT = 1;
    private static final int BATTERY_STYLE_GONE    = 2;
    private static final int BATTERY_STYLE_HIDE = 2;

    private static final int BATTERY_ICON_STYLE_UNKNOWN = R.drawable.stat_sys_kb_battery_unknown;
    private static final int BATTERY_ICON_STYLE_NORMAL = R.drawable.stat_sys_kb_battery;
    private static final int BATTERY_ICON_STYLE_CHARGE = R.drawable.stat_sys_kb_battery_charge;

    private boolean mDockStatus = false;
    private boolean mDockCharging = false;
    private int mDockStatus = BatteryManager.DOCK_BATTERY_STATUS_UNKNOWN;
    private boolean mDockPresent = false;
    private int mBatteryStyle;
    private int mBatteryIcon = BATTERY_ICON_STYLE_NORMAL;

    private static final int BATTERY_TEXT_STYLE_NORMAL  = R.string.status_bar_settings_battery_meter_format;
    private static final int BATTERY_TEXT_STYLE_MIN     = R.string.status_bar_settings_battery_meter_min_format;
    private static final int BATTERY_TEXT_STYLE_MIN =
            R.string.status_bar_settings_battery_meter_min_format;

    Handler mHandler;
    private Handler mHandler;

    class SettingsObserver extends ContentObserver {
        SettingsObserver(Handler handler) {
@@ -68,7 +68,8 @@ public class DockBatteryController extends BroadcastReceiver {
                    Settings.System.STATUS_BAR_BATTERY), false, this);
        }

        @Override public void onChange(boolean selfChange) {
        @Override
        public void onChange(boolean selfChange) {
            updateSettings();
        }
    }
@@ -98,8 +99,10 @@ public class DockBatteryController extends BroadcastReceiver {
        final String action = intent.getAction();
        if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
            final int level = intent.getIntExtra(BatteryManager.EXTRA_DOCK_LEVEL, 0);
            mDockCharging = intent.getIntExtra(BatteryManager.EXTRA_DOCK_STATUS, 0) == BatteryManager.DOCK_STATE_CHARGING;
            mDockStatus = intent.getIntExtra(BatteryManager.EXTRA_DOCK_STATUS, 0) != BatteryManager.DOCK_STATE_UNDOCKED;
            mDockStatus = intent.getIntExtra(BatteryManager.EXTRA_DOCK_STATUS,
                    BatteryManager.DOCK_BATTERY_STATUS_UNKNOWN);
            mDockPresent = intent.getBooleanExtra(BatteryManager.EXTRA_DOCK_PRESENT,
                    false);

            int N = mIconViews.size();
            for (int i = 0; i < N; i++) {
@@ -108,42 +111,47 @@ public class DockBatteryController extends BroadcastReceiver {
                v.setContentDescription(mContext.getString(R.string.accessibility_battery_level,
                        level));
            }

            N = mLabelViews.size();
            for (int i = 0; i < N; i++) {
                TextView v = mLabelViews.get(i);
                v.setText(mContext.getString(BATTERY_TEXT_STYLE_MIN,
                        level));
                v.setText(mContext.getString(BATTERY_TEXT_STYLE_MIN, level));
            }

            updateBattery();
        }
    }

    private void updateBattery() {
        int mIcon = View.GONE;
        int mText = View.GONE;
        int mIconStyle = BATTERY_ICON_STYLE_NORMAL;
        int icon = View.GONE;
        int text = View.GONE;
        int iconStyle = BATTERY_ICON_STYLE_UNKNOWN;

        if (mBatteryStyle == 0) {
            mIcon = mDockStatus ? (View.VISIBLE) : (View.GONE);
            mIconStyle = mDockCharging ? BATTERY_ICON_STYLE_CHARGE
                    : BATTERY_ICON_STYLE_NORMAL;
        } else if(mBatteryStyle == 1){
            mIcon = mDockStatus ? (View.VISIBLE) : (View.GONE);
            mText = mDockStatus ? (View.VISIBLE) : (View.GONE);
            mIconStyle = mDockCharging ? BATTERY_ICON_STYLE_CHARGE
                    : BATTERY_ICON_STYLE_NORMAL;
        if (mDockPresent && mBatteryStyle != BATTERY_STYLE_HIDE) {
            icon = View.VISIBLE;

            if (mBatteryStyle == BATTERY_STYLE_TEXT) {
                text = View.VISIBLE;
            }

            if (mDockStatus == BatteryManager.DOCK_BATTERY_STATUS_NOT_CHARGING) {
                iconStyle = BATTERY_ICON_STYLE_NORMAL;
            } else if (mDockStatus == BatteryManager.DOCK_BATTERY_STATUS_CHARGING) {
                iconStyle = BATTERY_ICON_STYLE_CHARGE;
            }
        }

        int N = mIconViews.size();
        for (int i = 0; i < N; i++) {
            ImageView v = mIconViews.get(i);
            v.setVisibility(mIcon);
            v.setImageResource(mIconStyle);
            v.setVisibility(icon);
            v.setImageResource(iconStyle);
        }

        N = mLabelViews.size();
        for (int i = 0; i < N; i++) {
            TextView v = mLabelViews.get(i);
            v.setVisibility(mText);
            v.setVisibility(text);
        }
    }

@@ -151,7 +159,8 @@ public class DockBatteryController extends BroadcastReceiver {
        ContentResolver resolver = mContext.getContentResolver();

        mBatteryStyle = (Settings.System.getInt(resolver,
                Settings.System.STATUS_BAR_BATTERY, 0));
                Settings.System.STATUS_BAR_BATTERY, BATTERY_STYLE_NORMAL));

        updateBattery();
    }
}
+28 −10
Original line number Diff line number Diff line
@@ -117,12 +117,9 @@ public final class BatteryService extends Binder {
    private int mBatteryTemperature;
    private String mBatteryTechnology;
    private boolean mBatteryLevelCritical;
    private int mInvalidCharger;
    /* End native fields. */

    private int mDockBatteryStatus;
    private int mDockBatteryLevel;
    private String mDockBatteryPresent;

    private int mLastBatteryStatus;
    private int mLastBatteryHealth;
    private boolean mLastBatteryPresent;
@@ -130,16 +127,22 @@ public final class BatteryService extends Binder {
    private int mLastBatteryVoltage;
    private int mLastBatteryTemperature;
    private boolean mLastBatteryLevelCritical;

    private int mInvalidCharger;
    private int mLastInvalidCharger;

    private boolean mHasDockBattery;

    private int mDockBatteryStatus;
    private int mDockBatteryLevel;
    private boolean mDockBatteryPresent;

    private int mLastDockBatteryStatus;
    private int mLastDockBatteryLevel;
    private boolean mLastDockBatteryPresent;

    private int mLowBatteryWarningLevel;
    private int mLowBatteryCloseWarningLevel;
    private int mShutdownBatteryTemperature;

    private boolean mHasDockBattery;

    private int mPlugType;
    private int mLastPlugType = -1; // Extra state so we can detect first run

@@ -352,6 +355,14 @@ public final class BatteryService extends Binder {
        shutdownIfNoPowerLocked();
        shutdownIfOverTempLocked();

        boolean dockBatteryChanged = false;
        if (mHasDockBattery &&
                (mDockBatteryLevel != mLastDockBatteryLevel ||
                mDockBatteryStatus != mLastDockBatteryStatus ||
                mDockBatteryPresent != mLastDockBatteryPresent)) {
            dockBatteryChanged = true;
        }

        if (mBatteryStatus != mLastBatteryStatus ||
                mBatteryHealth != mLastBatteryHealth ||
                mBatteryPresent != mLastBatteryPresent ||
@@ -359,7 +370,8 @@ public final class BatteryService extends Binder {
                mPlugType != mLastPlugType ||
                mBatteryVoltage != mLastBatteryVoltage ||
                mBatteryTemperature != mLastBatteryTemperature ||
                mInvalidCharger != mLastInvalidCharger) {
                mInvalidCharger != mLastInvalidCharger ||
                dockBatteryChanged) {

            if (mPlugType != mLastPlugType) {
                if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -482,6 +494,12 @@ public final class BatteryService extends Binder {
            mLastBatteryTemperature = mBatteryTemperature;
            mLastBatteryLevelCritical = mBatteryLevelCritical;
            mLastInvalidCharger = mInvalidCharger;

            if (mHasDockBattery) {
                mLastDockBatteryLevel = mDockBatteryLevel;
                mLastDockBatteryStatus = mDockBatteryStatus;
                mLastDockBatteryPresent = mDockBatteryPresent;
            }
        }
    }

@@ -518,9 +536,9 @@ public final class BatteryService extends Binder {
        }

        if (mHasDockBattery){
            intent.putExtra(BatteryManager.EXTRA_DOCK_PRESENT, mDockBatteryPresent);
            intent.putExtra(BatteryManager.EXTRA_DOCK_STATUS, mDockBatteryStatus);
            intent.putExtra(BatteryManager.EXTRA_DOCK_LEVEL, mDockBatteryLevel);
            intent.putExtra(BatteryManager.EXTRA_DOCK_AC_ONLINE, false);
        }

        if (false) {
+41 −33
Original line number Diff line number Diff line
@@ -72,9 +72,9 @@ struct BatteryManagerConstants {
    jint healthUnspecifiedFailure;
    jint healthCold;
#ifdef HAS_DOCK_BATTERY
    jint dockstatusCharging;
    jint dockstatusNotCharging;
    jint dockstatusUndocked;
    jint dockStatusUnknown;
    jint dockStatusCharging;
    jint dockStatusNotCharging;
#endif
};
static BatteryManagerConstants gConstants;
@@ -91,9 +91,9 @@ struct PowerSupplyPaths {
    char* batteryTemperaturePath;
    char* batteryTechnologyPath;
#ifdef HAS_DOCK_BATTERY
    char* dockbatteryStatusPath;
    char* dockbatteryCapacityPath;
    char* dockbatteryPresentPath;
    char* dockBatteryStatusPath;
    char* dockBatteryCapacityPath;
    char* dockBatteryPresentPath;
#endif
};
static PowerSupplyPaths gPaths;
@@ -120,12 +120,12 @@ static jint getBatteryStatus(const char* status)
static jint getDockBatteryStatus(const char* status)
{
    switch (status[0]) {
        case 'C': return gConstants.dockstatusCharging;         // Charging
        case 'N': return gConstants.dockstatusNotCharging;      // Not charging
        case 'C': return gConstants.dockStatusCharging;         // Charging
        case 'N': return gConstants.dockStatusNotCharging;      // Not charging

        default: {
            ALOGW("Unknown dock battery status '%s'", status);
            return gConstants.dockstatusUndocked;
            return gConstants.dockStatusUnknown;
        }
    }
}
@@ -233,10 +233,6 @@ static void android_server_BatteryService_update(JNIEnv* env, jobject obj)
    setBooleanField(env, obj, gPaths.wirelessOnlinePath, gFieldIds.mWirelessOnline);
    setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent);

#ifdef HAS_DOCK_BATTERY
    setIntField(env, obj, gPaths.dockbatteryCapacityPath, gFieldIds.mDockBatteryLevel);
#endif
    
    setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);
    setVoltageField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage);
    setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature);
@@ -250,19 +246,31 @@ static void android_server_BatteryService_update(JNIEnv* env, jobject obj)
        env->SetIntField(obj, gFieldIds.mBatteryStatus,
                         gConstants.statusUnknown);

#ifdef HAS_DOCK_BATTERY
    if (readFromFile(gPaths.dockbatteryStatusPath, buf, SIZE) > 0)
        env->SetIntField(obj, gFieldIds.mDockBatteryStatus, getDockBatteryStatus(buf));
    else
        env->SetIntField(obj, gFieldIds.mDockBatteryStatus,
                         gConstants.dockstatusUndocked);
#endif
    
    if (readFromFile(gPaths.batteryHealthPath, buf, SIZE) > 0)
        env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf));

    if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0)
        env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf));

#ifdef HAS_DOCK_BATTERY
    jboolean present = false;
    if (readFromFile(gPaths.dockBatteryPresentPath, buf, SIZE) >= 15) {
        // should return "dock detect = 1"
        if (buf[14] == '1') {
            present = true;
        }
    }
    env->SetBooleanField(obj, gFieldIds.mDockBatteryPresent, present);

    setIntField(env, obj, gPaths.dockBatteryCapacityPath, gFieldIds.mDockBatteryLevel);

    if (readFromFile(gPaths.dockBatteryStatusPath, buf, SIZE) > 0)
        env->SetIntField(obj, gFieldIds.mDockBatteryStatus,
                         getDockBatteryStatus(buf));
    else
        env->SetIntField(obj, gFieldIds.mDockBatteryStatus,
                         gConstants.dockStatusUnknown);
#endif
}

static JNINativeMethod sMethods[] = {
@@ -352,13 +360,13 @@ int register_android_server_BatteryService(JNIEnv* env)
                else if(strcmp(buf, "DockBattery") == 0) {
                    snprintf(path, sizeof(path), "%s/%s/status", POWER_SUPPLY_PATH, name);
                    if (access(path, R_OK) == 0)
                        gPaths.dockbatteryStatusPath = strdup(path);
                        gPaths.dockBatteryStatusPath = strdup(path);
                    snprintf(path, sizeof(path), "%s/%s/capacity", POWER_SUPPLY_PATH, name);
                    if (access(path, R_OK) == 0)
                        gPaths.dockbatteryCapacityPath = strdup(path);
                        gPaths.dockBatteryCapacityPath = strdup(path);
                    snprintf(path, sizeof(path), "%s/%s/device/ec_dock", POWER_SUPPLY_PATH, name);
                    if (access(path, R_OK) == 0)
                        gPaths.dockbatteryPresentPath = strdup(path);
                        gPaths.dockBatteryPresentPath = strdup(path);
                }
#endif
            }
@@ -408,7 +416,7 @@ int register_android_server_BatteryService(JNIEnv* env)
#ifdef HAS_DOCK_BATTERY
    gFieldIds.mDockBatteryStatus = env->GetFieldID(clazz, "mDockBatteryStatus", "I");
    gFieldIds.mDockBatteryLevel = env->GetFieldID(clazz, "mDockBatteryLevel", "I");
    gFieldIds.mDockBatteryPresent = env->GetFieldID(clazz, "mDockBatteryPresent", "Ljava/lang/String;");
    gFieldIds.mDockBatteryPresent = env->GetFieldID(clazz, "mDockBatteryPresent", "Z");
#endif

    LOG_FATAL_IF(gFieldIds.mAcOnline == NULL, "Unable to find BatteryService.AC_ONLINE_PATH");
@@ -466,14 +474,14 @@ int register_android_server_BatteryService(JNIEnv* env)
            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_COLD", "I"));

#ifdef HAS_DOCK_BATTERY
    gConstants.dockstatusCharging = env->GetStaticIntField(clazz,
            env->GetStaticFieldID(clazz, "DOCK_STATE_CHARGING", "I"));
    gConstants.dockStatusUnknown = env->GetStaticIntField(clazz,
            env->GetStaticFieldID(clazz, "DOCK_BATTERY_STATUS_UNKNOWN", "I"));

    gConstants.dockstatusNotCharging = env->GetStaticIntField(clazz,
            env->GetStaticFieldID(clazz, "DOCK_STATE_DISCHARGING", "I"));
    gConstants.dockStatusCharging = env->GetStaticIntField(clazz,
            env->GetStaticFieldID(clazz, "DOCK_BATTERY_STATUS_CHARGING", "I"));

    gConstants.dockstatusUndocked = env->GetStaticIntField(clazz,
            env->GetStaticFieldID(clazz, "DOCK_STATE_UNDOCKED", "I"));
    gConstants.dockStatusNotCharging = env->GetStaticIntField(clazz,
            env->GetStaticFieldID(clazz, "DOCK_BATTERY_STATUS_NOT_CHARGING", "I"));
#endif

    return jniRegisterNativeMethods(env, "com/android/server/BatteryService", sMethods, NELEM(sMethods));