resolved conflicts for merge of 53686433 to master

Change-Id: I27004dc464f5771d3205ae5757c6eccc5b16854d
This commit is contained in:
Dianne Hackborn
2010-09-13 16:02:57 -07:00
27 changed files with 963 additions and 91 deletions

View File

@@ -47,6 +47,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.WorkSource;
import android.provider.Settings;
import android.text.format.DateUtils;
import android.text.format.Time;
@@ -129,8 +130,8 @@ public class SyncManager implements OnAccountsUpdateListener {
private static final int INITIALIZATION_UNBIND_DELAY_MS = 5000;
private static final String SYNC_WAKE_LOCK_PREFIX = "SyncWakeLock";
private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarmWakeLock";
private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*";
private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm";
private Context mContext;
@@ -1713,6 +1714,7 @@ public class SyncManager implements OnAccountsUpdateListener {
Log.v(TAG, "runStateIdle: setting mActiveSyncContext to " + mActiveSyncContext);
}
mSyncStorageEngine.setActiveSync(mActiveSyncContext);
mSyncWakeLock.setWorkSource(new WorkSource(syncAdapterInfo.uid));
if (!activeSyncContext.bindToSyncAdapter(syncAdapterInfo)) {
Log.e(TAG, "Bind attempt failed to " + syncAdapterInfo);
mActiveSyncContext.close();

View File

@@ -404,6 +404,7 @@ public abstract class BatteryStats implements Parcelable {
public static final byte CMD_UPDATE = 0;
public static final byte CMD_START = 1;
public static final byte CMD_OVERFLOW = 2;
public byte cmd;
@@ -1703,6 +1704,8 @@ public abstract class BatteryStats implements Parcelable {
pw.print(" ");
if (rec.cmd == HistoryItem.CMD_START) {
pw.println(" START");
} else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
pw.println(" *OVERFLOW*");
} else {
if (rec.batteryLevel < 10) pw.print("00");
else if (rec.batteryLevel < 100) pw.print("0");

View File

@@ -17,10 +17,13 @@
package android.os;
import android.os.WorkSource;
/** @hide */
interface IPowerManager
{
void acquireWakeLock(int flags, IBinder lock, String tag);
void acquireWakeLock(int flags, IBinder lock, String tag, in WorkSource ws);
void updateWakeLockWorkSource(IBinder lock, in WorkSource ws);
void goToSleep(long time);
void goToSleepWithReason(long time, int reason);
void releaseWakeLock(IBinder lock, int flags);

View File

@@ -209,6 +209,7 @@ public class PowerManager
int mCount = 0;
boolean mRefCounted = true;
boolean mHeld = false;
WorkSource mWorkSource;
WakeLock(int flags, String tag)
{
@@ -247,7 +248,7 @@ public class PowerManager
synchronized (mToken) {
if (!mRefCounted || mCount++ == 0) {
try {
mService.acquireWakeLock(mFlags, mToken, mTag);
mService.acquireWakeLock(mFlags, mToken, mTag, mWorkSource);
} catch (RemoteException e) {
}
mHeld = true;
@@ -313,6 +314,32 @@ public class PowerManager
}
}
public void setWorkSource(WorkSource ws) {
synchronized (mToken) {
if (ws != null && ws.size() == 0) {
ws = null;
}
boolean changed = true;
if (ws == null) {
mWorkSource = null;
} else if (mWorkSource == null) {
changed = mWorkSource != null;
mWorkSource = new WorkSource(ws);
} else {
changed = mWorkSource.diff(ws);
if (changed) {
mWorkSource.set(ws);
}
}
if (changed && mHeld) {
try {
mService.updateWakeLockWorkSource(mToken, mWorkSource);
} catch (RemoteException e) {
}
}
}
}
public String toString() {
synchronized (mToken) {
return "WakeLock{"

View File

@@ -0,0 +1,18 @@
/* Copyright 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 android.os;
parcelable WorkSource;

View File

@@ -0,0 +1,311 @@
package android.os;
/**
* Describes the source of some work that may be done by someone else.
* Currently the public representation of what a work source is is not
* defined; this is an opaque container.
*/
public class WorkSource implements Parcelable {
int mNum;
int[] mUids;
/**
* Internal statics to avoid object allocations in some operations.
* The WorkSource object itself is not thread safe, but we need to
* hold sTmpWorkSource lock while working with these statics.
*/
static final WorkSource sTmpWorkSource = new WorkSource(0);
/**
* For returning newbie work from a modification operation.
*/
static WorkSource sNewbWork;
/**
* For returning gone work form a modification operation.
*/
static WorkSource sGoneWork;
/**
* Create an empty work source.
*/
public WorkSource() {
mNum = 0;
}
/**
* Create a new WorkSource that is a copy of an existing one.
* If <var>orig</var> is null, an empty WorkSource is created.
*/
public WorkSource(WorkSource orig) {
if (orig == null) {
mNum = 0;
return;
}
mNum = orig.mNum;
if (orig.mUids != null) {
mUids = orig.mUids.clone();
} else {
mUids = null;
}
}
/** @hide */
public WorkSource(int uid) {
mNum = 1;
mUids = new int[] { uid, 0 };
}
WorkSource(Parcel in) {
mNum = in.readInt();
mUids = in.createIntArray();
}
/** @hide */
public int size() {
return mNum;
}
/** @hide */
public int get(int index) {
return mUids[index];
}
/**
* Clear this WorkSource to be empty.
*/
public void clear() {
mNum = 0;
}
/**
* Compare this WorkSource with another.
* @param other The WorkSource to compare against.
* @return If there is a difference, true is returned.
*/
public boolean diff(WorkSource other) {
int N = mNum;
if (N != other.mNum) {
return true;
}
final int[] uids1 = mUids;
final int[] uids2 = other.mUids;
for (int i=0; i<N; i++) {
if (uids1[i] != uids2[i]) {
return true;
}
}
return false;
}
/**
* Replace the current contents of this work source with the given
* work source. If <var>other</var> is null, the current work source
* will be made empty.
*/
public void set(WorkSource other) {
if (other == null) {
mNum = 0;
return;
}
mNum = other.mNum;
if (other.mUids != null) {
if (mUids != null && mUids.length >= mNum) {
System.arraycopy(other.mUids, 0, mUids, 0, mNum);
} else {
mUids = other.mUids.clone();
}
} else {
mUids = null;
}
}
/** @hide */
public void set(int uid) {
mNum = 1;
if (mUids == null) mUids = new int[2];
mUids[0] = uid;
}
/** @hide */
public WorkSource[] setReturningDiffs(WorkSource other) {
synchronized (sTmpWorkSource) {
sNewbWork = null;
sGoneWork = null;
updateLocked(other, true, true);
if (sNewbWork != null || sGoneWork != null) {
WorkSource[] diffs = new WorkSource[2];
diffs[0] = sNewbWork;
diffs[1] = sGoneWork;
return diffs;
}
return null;
}
}
/**
* Merge the contents of <var>other</var> WorkSource in to this one.
*
* @param other The other WorkSource whose contents are to be merged.
* @return Returns true if any new sources were added.
*/
public boolean add(WorkSource other) {
synchronized (sTmpWorkSource) {
return updateLocked(other, false, false);
}
}
/** @hide */
public WorkSource addReturningNewbs(WorkSource other) {
synchronized (sTmpWorkSource) {
sNewbWork = null;
updateLocked(other, false, true);
return sNewbWork;
}
}
/** @hide */
public boolean add(int uid) {
synchronized (sTmpWorkSource) {
sTmpWorkSource.mUids[0] = uid;
return updateLocked(sTmpWorkSource, false, false);
}
}
/** @hide */
public WorkSource addReturningNewbs(int uid) {
synchronized (sTmpWorkSource) {
sNewbWork = null;
sTmpWorkSource.mUids[0] = uid;
updateLocked(sTmpWorkSource, false, true);
return sNewbWork;
}
}
public boolean remove(WorkSource other) {
int N1 = mNum;
final int[] uids1 = mUids;
final int N2 = other.mNum;
final int[] uids2 = other.mUids;
boolean changed = false;
int i1 = 0;
for (int i2=0; i2<N2 && i1<N1; i2++) {
if (uids2[i2] == uids1[i1]) {
N1--;
if (i1 < N1) System.arraycopy(uids1, i1, uids1, i1-1, N1-i1);
}
while (i1 < N1 && uids2[i2] > uids1[i1]) {
i1++;
}
}
mNum = N1;
return changed;
}
private boolean updateLocked(WorkSource other, boolean set, boolean returnNewbs) {
int N1 = mNum;
int[] uids1 = mUids;
final int N2 = other.mNum;
final int[] uids2 = other.mUids;
boolean changed = false;
int i1 = 0;
for (int i2=0; i2<N2; i2++) {
if (i1 >= N1 || uids2[i2] < uids1[i1]) {
// Need to insert a new uid.
changed = true;
if (uids1 == null) {
uids1 = new int[4];
uids1[0] = uids2[i2];
} else if (i1 >= uids1.length) {
int[] newuids = new int[(uids1.length*3)/2];
if (i1 > 0) System.arraycopy(uids1, 0, newuids, 0, i1);
if (i1 < N1) System.arraycopy(uids1, i1, newuids, i1+1, N1-i1);
uids1 = newuids;
uids1[i1] = uids2[i2];
} else {
if (i1 < N1) System.arraycopy(uids1, i1, uids1, i1+1, N1-i1);
uids1[i1] = uids2[i2];
}
if (returnNewbs) {
if (sNewbWork == null) {
sNewbWork = new WorkSource(uids2[i2]);
} else {
sNewbWork.addLocked(uids2[i2]);
}
}
N1++;
i1++;
} else {
if (!set) {
// Skip uids that already exist or are not in 'other'.
do {
i1++;
} while (i1 < N1 && uids2[i2] >= uids1[i1]);
} else {
// Remove any uids that don't exist in 'other'.
int start = i1;
while (i1 < N1 && uids2[i2] > uids1[i1]) {
if (sGoneWork == null) {
sGoneWork = new WorkSource(uids1[i1]);
} else {
sGoneWork.addLocked(uids1[i1]);
}
i1++;
}
if (start < i1) {
System.arraycopy(uids1, i1, uids1, start, i1-start);
N1 -= i1-start;
i1 = start;
}
// If there is a matching uid, skip it.
if (i1 < N1 && uids2[i1] == uids1[i1]) {
i1++;
}
}
}
}
mNum = N1;
mUids = uids1;
return changed;
}
private void addLocked(int uid) {
if (mUids == null) {
mUids = new int[4];
mUids[0] = uid;
mNum = 1;
return;
}
if (mNum >= mUids.length) {
int[] newuids = new int[(mNum*3)/2];
System.arraycopy(mUids, 0, newuids, 0, mNum);
mUids = newuids;
}
mUids[mNum] = uid;
mNum++;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mNum);
dest.writeIntArray(mUids);
}
public static final Parcelable.Creator<WorkSource> CREATOR
= new Parcelable.Creator<WorkSource>() {
public WorkSource createFromParcel(Parcel in) {
return new WorkSource(in);
}
public WorkSource[] newArray(int size) {
return new WorkSource[size];
}
};
}

View File

@@ -18,6 +18,7 @@ package com.android.internal.app;
import com.android.internal.os.BatteryStatsImpl;
import android.os.WorkSource;
import android.telephony.SignalStrength;
interface IBatteryStats {
@@ -33,6 +34,9 @@ interface IBatteryStats {
SensorService.cpp */
void noteStopSensor(int uid, int sensor);
void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, int type);
void noteStopWakelockFromSource(in WorkSource ws, int pid, String name, int type);
void noteStartGps(int uid);
void noteStopGps(int uid);
void noteScreenOn();
@@ -57,6 +61,12 @@ interface IBatteryStats {
void noteScanWifiLockReleased(int uid);
void noteWifiMulticastEnabled(int uid);
void noteWifiMulticastDisabled(int uid);
void noteFullWifiLockAcquiredFromSource(in WorkSource ws);
void noteFullWifiLockReleasedFromSource(in WorkSource ws);
void noteScanWifiLockAcquiredFromSource(in WorkSource ws);
void noteScanWifiLockReleasedFromSource(in WorkSource ws);
void noteWifiMulticastEnabledFromSource(in WorkSource ws);
void noteWifiMulticastDisabledFromSource(in WorkSource ws);
void setBatteryState(int status, int health, int plugType, int level, int temp, int volt);
long getAwakeTimeBattery();
long getAwakeTimePlugged();

View File

@@ -29,6 +29,7 @@ import android.os.ParcelFormatException;
import android.os.Parcelable;
import android.os.Process;
import android.os.SystemClock;
import android.os.WorkSource;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
@@ -68,12 +69,12 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int VERSION = 50;
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 1000;
private static final int MAX_HISTORY_ITEMS = 2000;
// The maximum number of names wakelocks we will keep track of
// per uid; once the limit is reached, we batch the remaining wakelocks
// in to one common name.
private static final int MAX_WAKELOCKS_PER_UID = 20;
private static final int MAX_WAKELOCKS_PER_UID = 30;
private static final String BATCHED_WAKELOCK_NAME = "*overflow*";
@@ -1173,7 +1174,7 @@ public final class BatteryStatsImpl extends BatteryStats {
// If the current time is basically the same as the last time,
// just collapse into one record.
if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
&& (mHistoryBaseTime+curTime) < (mHistoryEnd.time+100)) {
&& (mHistoryBaseTime+curTime) < (mHistoryEnd.time+500)) {
// If the current is the same as the one before, then we no
// longer need the entry.
if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
@@ -1189,6 +1190,10 @@ public final class BatteryStatsImpl extends BatteryStats {
return;
}
if (mNumHistoryItems == MAX_HISTORY_ITEMS) {
addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW);
}
if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
// Once we've reached the maximum number of items, we only
// record changes to the battery level.
@@ -1329,6 +1334,20 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
int N = ws.size();
for (int i=0; i<N; i++) {
noteStartWakeLocked(ws.get(i), pid, name, type);
}
}
public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
int N = ws.size();
for (int i=0; i<N; i++) {
noteStopWakeLocked(ws.get(i), pid, name, type);
}
}
public int startAddingCpuLocked() {
mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
@@ -1949,6 +1968,48 @@ public final class BatteryStatsImpl extends BatteryStats {
getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
}
public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
int N = ws.size();
for (int i=0; i<N; i++) {
noteFullWifiLockAcquiredLocked(ws.get(i));
}
}
public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
int N = ws.size();
for (int i=0; i<N; i++) {
noteFullWifiLockReleasedLocked(ws.get(i));
}
}
public void noteScanWifiLockAcquiredFromSourceLocked(WorkSource ws) {
int N = ws.size();
for (int i=0; i<N; i++) {
noteScanWifiLockAcquiredLocked(ws.get(i));
}
}
public void noteScanWifiLockReleasedFromSourceLocked(WorkSource ws) {
int N = ws.size();
for (int i=0; i<N; i++) {
noteScanWifiLockReleasedLocked(ws.get(i));
}
}
public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
int N = ws.size();
for (int i=0; i<N; i++) {
noteWifiMulticastEnabledLocked(ws.get(i));
}
}
public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
int N = ws.size();
for (int i=0; i<N; i++) {
noteWifiMulticastDisabledLocked(ws.get(i));
}
}
@Override public long getScreenOnTime(long batteryRealtime, int which) {
return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
}