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

Commit 77b987f1 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Hold a wake lock while dispatching network activity events.

Also add new API for determining whether the current data network
is active, and thus better scheduling network operations.  This
API is designed to not be tied to a mobile network -- regardless
of the network, apps can use it to determine whether they should
initiate activity or wait.  On non-mobile networks, it simply always
reports as the network being active.

This changed involved reworking how the idle timers are done so
that we only register an idle timer with the current default
network.  This way, we can know whether we currently expect to
get callbacks about the network being active, or should just always
report that it is active.  (Ultimately we need to be getting this
radio active data from the radio itself.)

Change-Id: Iaf6cc91a960d7542a70b72f87a7db26d12c4ea8e
parent 454a0384
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ LOCAL_SRC_FILES += \
	core/java/android/os/ICancellationSignal.aidl \
	core/java/android/os/IHardwareService.aidl \
	core/java/android/os/IMessenger.aidl \
	core/java/android/os/INetworkActivityListener.aidl \
	core/java/android/os/INetworkManagementService.aidl \
	core/java/android/os/IPermissionController.aidl \
	core/java/android/os/IPowerManager.aidl \
+7 −0
Original line number Diff line number Diff line
@@ -14614,11 +14614,14 @@ package android.net {
    method public android.net.NetworkInfo getNetworkInfo(int);
    method public int getNetworkPreference();
    method public boolean isActiveNetworkMetered();
    method public boolean isNetworkActive();
    method public static boolean isNetworkTypeValid(int);
    method public void registerNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
    method public boolean requestRouteToHost(int, int);
    method public void setNetworkPreference(int);
    method public int startUsingNetworkFeature(int, java.lang.String);
    method public int stopUsingNetworkFeature(int, java.lang.String);
    method public void unregisterNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
    field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
    field public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
    field public static final deprecated int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
@@ -14641,6 +14644,10 @@ package android.net {
    field public static final int TYPE_WIMAX = 6; // 0x6
  }
  public static abstract interface ConnectivityManager.OnNetworkActiveListener {
    method public abstract void onNetworkActive();
  }
  public class Credentials {
    ctor public Credentials(int, int, int);
    method public int getGid();
+97 −4
Original line number Diff line number Diff line
@@ -23,9 +23,14 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.os.Binder;
import android.os.Build.VERSION_CODES;
import android.os.IBinder;
import android.os.INetworkActivityListener;
import android.os.INetworkManagementService;
import android.os.Messenger;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
import android.util.ArrayMap;

import java.net.InetAddress;

@@ -76,7 +81,7 @@ public class ConnectivityManager {

    /**
     * Identical to {@link #CONNECTIVITY_ACTION} broadcast, but sent without any
     * applicable {@link Settings.Secure#CONNECTIVITY_CHANGE_DELAY}.
     * applicable {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY}.
     *
     * @hide
     */
@@ -402,6 +407,8 @@ public class ConnectivityManager {

    private final String mPackageName;

    private INetworkManagementService mNMService;

    /**
     * Tests if a given integer represents a valid network type.
     * @param networkType the type to be tested
@@ -906,6 +913,92 @@ public class ConnectivityManager {
        }
    }

    /**
     * Callback for use with {@link ConnectivityManager#registerNetworkActiveListener} to
     * find out when the current network has gone in to a high power state.
     */
    public interface OnNetworkActiveListener {
        /**
         * Called on the main thread of the process to report that the current data network
         * has become active, and it is now a good time to perform any pending network
         * operations.  Note that this listener only tells you when the network becomes
         * active; if at any other time you want to know whether it is active (and thus okay
         * to initiate network traffic), you can retrieve its instantaneous state with
         * {@link ConnectivityManager#isNetworkActive}.
         */
        public void onNetworkActive();
    }

    private INetworkManagementService getNetworkManagementService() {
        synchronized (this) {
            if (mNMService != null) {
                return mNMService;
            }
            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
            mNMService = INetworkManagementService.Stub.asInterface(b);
            return mNMService;
        }
    }

    private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
            mNetworkActivityListeners
                    = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>();

    /**
     * Start listening to reports when the data network is active, meaning it is
     * a good time to perform network traffic.  Use {@link #isNetworkActive()}
     * to determine the current state of the network after registering the listener.
     *
     * @param l The listener to be told when the network is active.
     */
    public void registerNetworkActiveListener(final OnNetworkActiveListener l) {
        INetworkActivityListener rl = new INetworkActivityListener.Stub() {
            @Override
            public void onNetworkActive() throws RemoteException {
                l.onNetworkActive();
            }
        };

        try {
            getNetworkManagementService().registerNetworkActivityListener(rl);
            mNetworkActivityListeners.put(l, rl);
        } catch (RemoteException e) {
        }
    }

    /**
     * Remove network active listener previously registered with
     * {@link #registerNetworkActiveListener}.
     *
     * @param l Previously registered listener.
     */
    public void unregisterNetworkActiveListener(OnNetworkActiveListener l) {
        INetworkActivityListener rl = mNetworkActivityListeners.get(l);
        if (rl == null) {
            throw new IllegalArgumentException("Listener not registered: " + l);
        }
        try {
            getNetworkManagementService().unregisterNetworkActivityListener(rl);
        } catch (RemoteException e) {
        }
    }

    /**
     * Return whether the data network is currently active.  An active network means that
     * it is currently in a high power state for performing data transmission.  On some
     * types of networks, it may be expensive to move and stay in such a state, so it is
     * more power efficient to batch network traffic together when the radio is already in
     * this state.  This method tells you whether right now is currently a good time to
     * initiate network traffic, as the network is already active.
     */
    public boolean isNetworkActive() {
        try {
            return getNetworkManagementService().isNetworkActive();
        } catch (RemoteException e) {
        }
        return false;
    }

    /**
     * {@hide}
     */
@@ -1021,7 +1114,7 @@ public class ConnectivityManager {

    /**
     * Check if the device allows for tethering.  It may be disabled via
     * {@code ro.tether.denied} system property, {@link Settings#TETHER_SUPPORTED} or
     * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
     * due to device configuration.
     *
     * @return a boolean - {@code true} indicating Tethering is supported.
@@ -1209,7 +1302,7 @@ public class ConnectivityManager {
     * doing something unusual like general internal filtering this may be useful.  On
     * a private network where the proxy is not accessible, you may break HTTP using this.
     *
     * @param proxyProperties The a {@link ProxyProperites} object defining the new global
     * @param p The a {@link ProxyProperties} object defining the new global
     *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
     *
     * <p>This method requires the call to hold the permission
@@ -1362,7 +1455,7 @@ public class ConnectivityManager {
    /**
     * Supply the backend messenger for a network tracker
     *
     * @param type NetworkType to set
     * @param networkType NetworkType to set
     * @param messenger {@link Messenger}
     * {@hide}
     */
+62 −23
Original line number Diff line number Diff line
@@ -833,6 +833,13 @@ public abstract class BatteryStats implements Parcelable {
     */
    public abstract long getScreenOnTime(long batteryRealtime, int which);
    
    /**
     * Returns the number of times the screen was turned on.
     *
     * {@hide}
     */
    public abstract int getScreenOnCount(int which);

    public static final int SCREEN_BRIGHTNESS_DARK = 0;
    public static final int SCREEN_BRIGHTNESS_DIM = 1;
    public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
@@ -868,6 +875,13 @@ public abstract class BatteryStats implements Parcelable {
     */
    public abstract long getPhoneOnTime(long batteryRealtime, int which);
    
    /**
     * Returns the number of times a phone call was activated.
     *
     * {@hide}
     */
    public abstract int getPhoneOnCount(int which);

    /**
     * Returns the time in microseconds that the phone has been running with
     * the given signal strength.
@@ -918,7 +932,7 @@ public abstract class BatteryStats implements Parcelable {
    public abstract long getMobileRadioActiveUnknownTime(int which);

    /**
     * Return count of number of times radio was app that could not be blamed on apps.
     * Return count of number of times radio was up that could not be blamed on apps.
     *
     * {@hide}
     */
@@ -1820,7 +1834,7 @@ public abstract class BatteryStats implements Parcelable {
                formatTimeMs(sb, totalRealtime / 1000);
                sb.append("realtime, ");
                formatTimeMs(sb, totalUptime / 1000);
                sb.append("uptime, ");
                sb.append("uptime");
        pw.println(sb.toString());
        pw.print("  Start clock time: ");
        pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
@@ -1834,11 +1848,16 @@ public abstract class BatteryStats implements Parcelable {
        sb.append(prefix);
                sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
                sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
                sb.append("), Input events: "); sb.append(getInputEventCount(which));
                sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
                sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
                sb.append(")");
                sb.append(") "); sb.append(getScreenOnCount(which));
                sb.append("x, Input events: "); sb.append(getInputEventCount(which));
        pw.println(sb.toString());
        if (phoneOnTime != 0) {
            sb.setLength(0);
            sb.append(prefix);
                    sb.append("  Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
                    sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
                    sb.append(") "); sb.append(getPhoneOnCount(which));
        }
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Screen brightnesses:");
@@ -1848,7 +1867,8 @@ public abstract class BatteryStats implements Parcelable {
            if (time == 0) {
                continue;
            }
            if (didOne) sb.append(", ");
            sb.append("\n    ");
            sb.append(prefix);
            didOne = true;
            sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
            sb.append(" ");
@@ -1857,7 +1877,7 @@ public abstract class BatteryStats implements Parcelable {
            sb.append(formatRatioLocked(time, screenOnTime));
            sb.append(")");
        }
        if (!didOne) sb.append("No activity");
        if (!didOne) sb.append(" (no activity)");
        pw.println(sb.toString());
        
        // Calculate wakelock times across all uids.
@@ -1954,24 +1974,27 @@ public abstract class BatteryStats implements Parcelable {
        long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
        long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);

        pw.print(prefix);
                pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes));
                pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes));
                pw.print(" (packets received "); pw.print(mobileRxTotalPackets);
                pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")");
        pw.print(prefix);
                pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
                pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
                pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
                pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
        if (fullWakeLockTimeTotalMicros != 0) {
            sb.setLength(0);
            sb.append(prefix);
                    sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
                            (fullWakeLockTimeTotalMicros + 500) / 1000);
                sb.append(", Total partial wakelock time: "); formatTimeMsNoSpace(sb,
            pw.println(sb.toString());
        }

        if (partialWakeLockTimeTotalMicros != 0) {
            sb.setLength(0);
            sb.append(prefix);
                    sb.append("  Total partial wakelock time: "); formatTimeMsNoSpace(sb,
                            (partialWakeLockTimeTotalMicros + 500) / 1000);
            pw.println(sb.toString());
        }

        pw.print(prefix);
                pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes));
                pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes));
                pw.print(" (packets received "); pw.print(mobileRxTotalPackets);
                pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")");
        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Signal levels:");
@@ -1982,6 +2005,7 @@ public abstract class BatteryStats implements Parcelable {
                continue;
            }
            sb.append("\n    ");
            sb.append(prefix);
            didOne = true;
            sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
            sb.append(" ");
@@ -2011,6 +2035,7 @@ public abstract class BatteryStats implements Parcelable {
                continue;
            }
            sb.append("\n    ");
            sb.append(prefix);
            didOne = true;
            sb.append(DATA_CONNECTION_NAMES[i]);
            sb.append(" ");
@@ -2047,6 +2072,11 @@ public abstract class BatteryStats implements Parcelable {
            pw.println(sb.toString());
        }

        pw.print(prefix);
                pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
                pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
                pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
                pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
        sb.setLength(0);
        sb.append(prefix);
                sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
@@ -2207,6 +2237,7 @@ public abstract class BatteryStats implements Parcelable {
        sippers = helper.getMobilemsppList();
        if (sippers != null && sippers.size() > 0) {
            pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
            long totalTime = 0;
            for (int i=0; i<sippers.size(); i++) {
                BatterySipper bs = sippers.get(i);
                sb.setLength(0);
@@ -2215,9 +2246,17 @@ public abstract class BatteryStats implements Parcelable {
                sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
                sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
                sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
                sb.append(")");
                sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
                pw.println(sb.toString());
                totalTime += bs.mobileActive;
            }
            sb.setLength(0);
            sb.append(prefix);
            sb.append("    TOTAL TIME: ");
            formatTimeMs(sb, totalTime);
            sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
            sb.append(")");
            pw.println(sb.toString());
            pw.println();
        }

+24 −0
Original line number Diff line number Diff line
/* Copyright 2013, 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 android.os;

/**
 * @hide
 */
oneway interface INetworkActivityListener
{
    void onNetworkActive();
}
Loading