resolved conflicts for merge of 53686433 to master
Change-Id: I27004dc464f5771d3205ae5757c6eccc5b16854d
This commit is contained in:
160
api/current.xml
160
api/current.xml
@@ -93977,6 +93977,8 @@
|
||||
>
|
||||
<parameter name="uid" type="int">
|
||||
</parameter>
|
||||
<parameter name="ws" type="android.os.WorkSource">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="onDisable"
|
||||
return="void"
|
||||
@@ -94106,6 +94108,8 @@
|
||||
>
|
||||
<parameter name="uid" type="int">
|
||||
</parameter>
|
||||
<parameter name="ws" type="android.os.WorkSource">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="onRequiresCell"
|
||||
return="boolean"
|
||||
@@ -94167,6 +94171,8 @@
|
||||
>
|
||||
<parameter name="minTime" type="long">
|
||||
</parameter>
|
||||
<parameter name="ws" type="android.os.WorkSource">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="onSupportsAltitude"
|
||||
return="boolean"
|
||||
@@ -111503,6 +111509,19 @@
|
||||
<parameter name="refCounted" type="boolean">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setWorkSource"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="ws" type="android.os.WorkSource">
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
</package>
|
||||
<package name="android.opengl"
|
||||
@@ -138355,6 +138374,19 @@
|
||||
<parameter name="value" type="boolean">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setWorkSource"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="ws" type="android.os.WorkSource">
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
<class name="Process"
|
||||
extends="java.lang.Object"
|
||||
@@ -139503,6 +139535,134 @@
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
<class name="WorkSource"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<implements name="android.os.Parcelable">
|
||||
</implements>
|
||||
<constructor name="WorkSource"
|
||||
type="android.os.WorkSource"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</constructor>
|
||||
<constructor name="WorkSource"
|
||||
type="android.os.WorkSource"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="orig" type="android.os.WorkSource">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<method name="add"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="other" type="android.os.WorkSource">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="clear"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="describeContents"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="diff"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="other" type="android.os.WorkSource">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="remove"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="other" type="android.os.WorkSource">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="set"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="other" type="android.os.WorkSource">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="writeToParcel"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="dest" type="android.os.Parcel">
|
||||
</parameter>
|
||||
<parameter name="flags" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<field name="CREATOR"
|
||||
type="android.os.Parcelable.Creator"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
</class>
|
||||
</package>
|
||||
<package name="android.os.storage"
|
||||
>
|
||||
|
||||
@@ -64,7 +64,7 @@ public class PowerCommand extends Svc.Command {
|
||||
= IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));
|
||||
try {
|
||||
IBinder lock = new Binder();
|
||||
pm.acquireWakeLock(PowerManager.FULL_WAKE_LOCK, lock, "svc power");
|
||||
pm.acquireWakeLock(PowerManager.FULL_WAKE_LOCK, lock, "svc power", null);
|
||||
pm.setStayOnSetting(val);
|
||||
pm.releaseWakeLock(lock, 0);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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{"
|
||||
|
||||
18
core/java/android/os/WorkSource.aidl
Normal file
18
core/java/android/os/WorkSource.aidl
Normal 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;
|
||||
311
core/java/android/os/WorkSource.java
Normal file
311
core/java/android/os/WorkSource.java
Normal 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];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -939,7 +939,7 @@
|
||||
<permission android:name="android.permission.UPDATE_DEVICE_STATS"
|
||||
android:label="@string/permlab_batteryStats"
|
||||
android:description="@string/permdesc_batteryStats"
|
||||
android:protectionLevel="signature" />
|
||||
android:protectionLevel="signatureOrSystem" />
|
||||
|
||||
<!-- Allows an application to open windows that are for use by parts
|
||||
of the system user interface. Not for use by third party apps. -->
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.location.Criteria;
|
||||
import android.location.Location;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.WorkSource;
|
||||
|
||||
/**
|
||||
* Binder interface for services that implement location providers.
|
||||
@@ -43,7 +44,7 @@ interface ILocationProvider {
|
||||
long getStatusUpdateTime();
|
||||
String getInternalState();
|
||||
void enableLocationTracking(boolean enable);
|
||||
void setMinTime(long minTime);
|
||||
void setMinTime(long minTime, in WorkSource ws);
|
||||
void updateNetworkState(int state, in NetworkInfo info);
|
||||
void updateLocation(in Location location);
|
||||
boolean sendExtraCommand(String command, inout Bundle extras);
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.WorkSource;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
@@ -106,8 +107,8 @@ public abstract class LocationProvider {
|
||||
LocationProvider.this.onEnableLocationTracking(enable);
|
||||
}
|
||||
|
||||
public void setMinTime(long minTime) {
|
||||
LocationProvider.this.onSetMinTime(minTime);
|
||||
public void setMinTime(long minTime, WorkSource ws) {
|
||||
LocationProvider.this.onSetMinTime(minTime, ws);
|
||||
}
|
||||
|
||||
public void updateNetworkState(int state, NetworkInfo info) {
|
||||
@@ -123,11 +124,11 @@ public abstract class LocationProvider {
|
||||
}
|
||||
|
||||
public void addListener(int uid) {
|
||||
LocationProvider.this.onAddListener(uid);
|
||||
LocationProvider.this.onAddListener(uid, new WorkSource(uid));
|
||||
}
|
||||
|
||||
public void removeListener(int uid) {
|
||||
LocationProvider.this.onRemoveListener(uid);
|
||||
LocationProvider.this.onRemoveListener(uid, new WorkSource(uid));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -303,8 +304,9 @@ public abstract class LocationProvider {
|
||||
* the frequency of updates to match the requested frequency.
|
||||
*
|
||||
* @param minTime the smallest minTime value over all listeners for this provider.
|
||||
* @param ws the source this work is coming from.
|
||||
*/
|
||||
public abstract void onSetMinTime(long minTime);
|
||||
public abstract void onSetMinTime(long minTime, WorkSource ws);
|
||||
|
||||
/**
|
||||
* Updates the network state for the given provider. This function must
|
||||
@@ -340,14 +342,16 @@ public abstract class LocationProvider {
|
||||
* Notifies the location provider when a new client is listening for locations.
|
||||
*
|
||||
* @param uid user ID of the new client.
|
||||
* @param ws a WorkSource representation of the client.
|
||||
*/
|
||||
public abstract void onAddListener(int uid);
|
||||
public abstract void onAddListener(int uid, WorkSource ws);
|
||||
|
||||
/**
|
||||
* Notifies the location provider when a client is no longer listening for locations.
|
||||
*
|
||||
* @param uid user ID of the client no longer listening.
|
||||
* @param ws a WorkSource representation of the client.
|
||||
*/
|
||||
public abstract void onRemoveListener(int uid);
|
||||
public abstract void onRemoveListener(int uid, WorkSource ws);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ import android.os.PowerManager;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.WorkSource;
|
||||
import android.provider.Settings;
|
||||
import android.util.EventLog;
|
||||
import android.util.Slog;
|
||||
@@ -504,7 +505,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
parseLeftoverJournals();
|
||||
|
||||
// Power management
|
||||
mWakelock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "backup");
|
||||
mWakelock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*");
|
||||
|
||||
// Start the backup passes going
|
||||
setBackupEnabled(areEnabled);
|
||||
@@ -1363,6 +1364,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
? IApplicationThread.BACKUP_MODE_FULL
|
||||
: IApplicationThread.BACKUP_MODE_INCREMENTAL;
|
||||
try {
|
||||
mWakelock.setWorkSource(new WorkSource(request.appInfo.uid));
|
||||
agent = bindToAgentSynchronous(request.appInfo, mode);
|
||||
if (agent != null) {
|
||||
int result = processOneBackup(request, agent, transport);
|
||||
@@ -1378,6 +1380,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
mWakelock.setWorkSource(null);
|
||||
|
||||
return BackupConstants.TRANSPORT_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ import android.os.Message;
|
||||
import android.os.PowerManager;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.WorkSource;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
@@ -157,6 +158,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
||||
private final HashMap<String,ArrayList<UpdateRecord>> mRecordsByProvider =
|
||||
new HashMap<String,ArrayList<UpdateRecord>>();
|
||||
|
||||
/**
|
||||
* Temporary filled in when computing min time for a provider. Access is
|
||||
* protected by global lock mLock.
|
||||
*/
|
||||
private final WorkSource mTmpWorkSource = new WorkSource();
|
||||
|
||||
// Proximity listeners
|
||||
private Receiver mProximityReceiver = null;
|
||||
private ILocationListener mProximityListener = null;
|
||||
@@ -913,7 +920,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
||||
if (enabled) {
|
||||
p.enable();
|
||||
if (listeners > 0) {
|
||||
p.setMinTime(getMinTimeLocked(provider));
|
||||
p.setMinTime(getMinTimeLocked(provider), mTmpWorkSource);
|
||||
p.enableLocationTracking(true);
|
||||
}
|
||||
} else {
|
||||
@@ -925,9 +932,21 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
||||
private long getMinTimeLocked(String provider) {
|
||||
long minTime = Long.MAX_VALUE;
|
||||
ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
|
||||
mTmpWorkSource.clear();
|
||||
if (records != null) {
|
||||
for (int i=records.size()-1; i>=0; i--) {
|
||||
minTime = Math.min(minTime, records.get(i).mMinTime);
|
||||
UpdateRecord ur = records.get(i);
|
||||
long curTime = ur.mMinTime;
|
||||
if (curTime < minTime) {
|
||||
minTime = curTime;
|
||||
}
|
||||
}
|
||||
long inclTime = (minTime*3)/2;
|
||||
for (int i=records.size()-1; i>=0; i--) {
|
||||
UpdateRecord ur = records.get(i);
|
||||
if (ur.mMinTime <= inclTime) {
|
||||
mTmpWorkSource.add(ur.mUid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return minTime;
|
||||
@@ -1125,7 +1144,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
||||
boolean isProviderEnabled = isAllowedBySettingsLocked(provider);
|
||||
if (isProviderEnabled) {
|
||||
long minTimeForProvider = getMinTimeLocked(provider);
|
||||
p.setMinTime(minTimeForProvider);
|
||||
p.setMinTime(minTimeForProvider, mTmpWorkSource);
|
||||
// try requesting single shot if singleShot is true, and fall back to
|
||||
// regular location tracking if requestSingleShotFix() is not supported
|
||||
if (!singleShot || !p.requestSingleShotFix()) {
|
||||
@@ -1223,7 +1242,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
||||
LocationProviderInterface p = mProvidersByName.get(provider);
|
||||
if (p != null) {
|
||||
if (hasOtherListener) {
|
||||
p.setMinTime(getMinTimeLocked(provider));
|
||||
p.setMinTime(getMinTimeLocked(provider), mTmpWorkSource);
|
||||
} else {
|
||||
p.enableLocationTracking(false);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.WorkSource;
|
||||
import android.provider.Settings.SettingNotFoundException;
|
||||
import android.provider.Settings;
|
||||
import android.util.EventLog;
|
||||
@@ -310,7 +311,7 @@ class PowerManagerService extends IPowerManager.Stub
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken,
|
||||
MY_UID, MY_PID, mTag);
|
||||
MY_UID, MY_PID, mTag, null);
|
||||
mHeld = true;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
@@ -607,6 +608,7 @@ class PowerManagerService extends IPowerManager.Stub
|
||||
final int uid;
|
||||
final int pid;
|
||||
final int monitorType;
|
||||
WorkSource ws;
|
||||
boolean activated = true;
|
||||
int minState;
|
||||
}
|
||||
@@ -630,35 +632,74 @@ class PowerManagerService extends IPowerManager.Stub
|
||||
|| n == PowerManager.SCREEN_DIM_WAKE_LOCK;
|
||||
}
|
||||
|
||||
public void acquireWakeLock(int flags, IBinder lock, String tag) {
|
||||
void enforceWakeSourcePermission(int uid, int pid) {
|
||||
if (uid == Process.myUid()) {
|
||||
return;
|
||||
}
|
||||
mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
|
||||
pid, uid, null);
|
||||
}
|
||||
|
||||
public void acquireWakeLock(int flags, IBinder lock, String tag, WorkSource ws) {
|
||||
int uid = Binder.getCallingUid();
|
||||
int pid = Binder.getCallingPid();
|
||||
if (uid != Process.myUid()) {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
|
||||
}
|
||||
if (ws != null) {
|
||||
enforceWakeSourcePermission(uid, pid);
|
||||
}
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLocks) {
|
||||
acquireWakeLockLocked(flags, lock, uid, pid, tag);
|
||||
acquireWakeLockLocked(flags, lock, uid, pid, tag, ws);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag) {
|
||||
int acquireUid = -1;
|
||||
int acquirePid = -1;
|
||||
String acquireName = null;
|
||||
int acquireType = -1;
|
||||
void noteStartWakeLocked(WakeLock wl, WorkSource ws) {
|
||||
try {
|
||||
if (ws != null) {
|
||||
mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag,
|
||||
wl.monitorType);
|
||||
} else {
|
||||
mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
void noteStopWakeLocked(WakeLock wl, WorkSource ws) {
|
||||
try {
|
||||
if (ws != null) {
|
||||
mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag,
|
||||
wl.monitorType);
|
||||
} else {
|
||||
mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag,
|
||||
WorkSource ws) {
|
||||
if (mSpew) {
|
||||
Slog.d(TAG, "acquireWakeLock flags=0x" + Integer.toHexString(flags) + " tag=" + tag);
|
||||
}
|
||||
|
||||
if (ws != null && ws.size() == 0) {
|
||||
ws = null;
|
||||
}
|
||||
|
||||
int index = mLocks.getIndex(lock);
|
||||
WakeLock wl;
|
||||
boolean newlock;
|
||||
boolean diffsource;
|
||||
WorkSource oldsource;
|
||||
if (index < 0) {
|
||||
wl = new WakeLock(flags, lock, tag, uid, pid);
|
||||
switch (wl.flags & LOCK_MASK)
|
||||
@@ -687,10 +728,31 @@ class PowerManagerService extends IPowerManager.Stub
|
||||
return;
|
||||
}
|
||||
mLocks.addLock(wl);
|
||||
if (ws != null) {
|
||||
wl.ws = new WorkSource(ws);
|
||||
}
|
||||
newlock = true;
|
||||
diffsource = false;
|
||||
oldsource = null;
|
||||
} else {
|
||||
wl = mLocks.get(index);
|
||||
newlock = false;
|
||||
oldsource = wl.ws;
|
||||
if (oldsource != null) {
|
||||
if (ws == null) {
|
||||
wl.ws = null;
|
||||
diffsource = true;
|
||||
} else {
|
||||
diffsource = oldsource.diff(ws);
|
||||
}
|
||||
} else if (ws != null) {
|
||||
diffsource = true;
|
||||
} else {
|
||||
diffsource = false;
|
||||
}
|
||||
if (diffsource) {
|
||||
wl.ws = new WorkSource(ws);
|
||||
}
|
||||
}
|
||||
if (isScreenLock(flags)) {
|
||||
// if this causes a wakeup, we reactivate all of the locks and
|
||||
@@ -731,19 +793,41 @@ class PowerManagerService extends IPowerManager.Stub
|
||||
enableProximityLockLocked();
|
||||
}
|
||||
}
|
||||
if (newlock) {
|
||||
acquireUid = wl.uid;
|
||||
acquirePid = wl.pid;
|
||||
acquireName = wl.tag;
|
||||
acquireType = wl.monitorType;
|
||||
}
|
||||
|
||||
if (acquireType >= 0) {
|
||||
try {
|
||||
mBatteryStats.noteStartWakelock(acquireUid, acquirePid, acquireName, acquireType);
|
||||
} catch (RemoteException e) {
|
||||
// Ignore
|
||||
if (diffsource) {
|
||||
// If the lock sources have changed, need to first release the
|
||||
// old ones.
|
||||
noteStopWakeLocked(wl, oldsource);
|
||||
}
|
||||
if (newlock || diffsource) {
|
||||
noteStartWakeLocked(wl, ws);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
|
||||
int uid = Binder.getCallingUid();
|
||||
int pid = Binder.getCallingPid();
|
||||
if (ws != null && ws.size() == 0) {
|
||||
ws = null;
|
||||
}
|
||||
if (ws != null) {
|
||||
enforceWakeSourcePermission(uid, pid);
|
||||
}
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLocks) {
|
||||
int index = mLocks.getIndex(lock);
|
||||
if (index < 0) {
|
||||
throw new IllegalArgumentException("Wake lock not active");
|
||||
}
|
||||
WakeLock wl = mLocks.get(index);
|
||||
WorkSource oldsource = wl.ws;
|
||||
wl.ws = ws != null ? new WorkSource(ws) : null;
|
||||
noteStopWakeLocked(wl, oldsource);
|
||||
noteStartWakeLocked(wl, ws);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -759,11 +843,6 @@ class PowerManagerService extends IPowerManager.Stub
|
||||
}
|
||||
|
||||
private void releaseWakeLockLocked(IBinder lock, int flags, boolean death) {
|
||||
int releaseUid;
|
||||
int releasePid;
|
||||
String releaseName;
|
||||
int releaseType;
|
||||
|
||||
WakeLock wl = mLocks.removeLock(lock);
|
||||
if (wl == null) {
|
||||
return;
|
||||
@@ -804,17 +883,11 @@ class PowerManagerService extends IPowerManager.Stub
|
||||
}
|
||||
// Unlink the lock from the binder.
|
||||
wl.binder.unlinkToDeath(wl, 0);
|
||||
releaseUid = wl.uid;
|
||||
releasePid = wl.pid;
|
||||
releaseName = wl.tag;
|
||||
releaseType = wl.monitorType;
|
||||
|
||||
if (releaseType >= 0) {
|
||||
if (wl.monitorType >= 0) {
|
||||
long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mBatteryStats.noteStopWakelock(releaseUid, releasePid, releaseName, releaseType);
|
||||
} catch (RemoteException e) {
|
||||
// Ignore
|
||||
noteStopWakeLocked(wl, wl.ws);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.os.RemoteException;
|
||||
import android.os.IBinder;
|
||||
import android.os.Binder;
|
||||
import android.os.SystemClock;
|
||||
import android.os.WorkSource;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.util.LinkedList;
|
||||
@@ -39,6 +40,7 @@ public class VibratorService extends IVibratorService.Stub {
|
||||
|
||||
private final LinkedList<Vibration> mVibrations;
|
||||
private Vibration mCurrentVibration;
|
||||
private final WorkSource mTmpWorkSource = new WorkSource();
|
||||
|
||||
private class Vibration implements IBinder.DeathRecipient {
|
||||
private final IBinder mToken;
|
||||
@@ -46,22 +48,24 @@ public class VibratorService extends IVibratorService.Stub {
|
||||
private final long mStartTime;
|
||||
private final long[] mPattern;
|
||||
private final int mRepeat;
|
||||
private final int mUid;
|
||||
|
||||
Vibration(IBinder token, long millis) {
|
||||
this(token, millis, null, 0);
|
||||
Vibration(IBinder token, long millis, int uid) {
|
||||
this(token, millis, null, 0, uid);
|
||||
}
|
||||
|
||||
Vibration(IBinder token, long[] pattern, int repeat) {
|
||||
this(token, 0, pattern, repeat);
|
||||
Vibration(IBinder token, long[] pattern, int repeat, int uid) {
|
||||
this(token, 0, pattern, repeat, uid);
|
||||
}
|
||||
|
||||
private Vibration(IBinder token, long millis, long[] pattern,
|
||||
int repeat) {
|
||||
int repeat, int uid) {
|
||||
mToken = token;
|
||||
mTimeout = millis;
|
||||
mStartTime = SystemClock.uptimeMillis();
|
||||
mPattern = pattern;
|
||||
mRepeat = repeat;
|
||||
mUid = uid;
|
||||
}
|
||||
|
||||
public void binderDied() {
|
||||
@@ -98,7 +102,7 @@ public class VibratorService extends IVibratorService.Stub {
|
||||
mContext = context;
|
||||
PowerManager pm = (PowerManager)context.getSystemService(
|
||||
Context.POWER_SERVICE);
|
||||
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
||||
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
|
||||
mWakeLock.setReferenceCounted(true);
|
||||
|
||||
mVibrations = new LinkedList<Vibration>();
|
||||
@@ -113,6 +117,7 @@ public class VibratorService extends IVibratorService.Stub {
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
throw new SecurityException("Requires VIBRATE permission");
|
||||
}
|
||||
int uid = Binder.getCallingUid();
|
||||
// We're running in the system server so we cannot crash. Check for a
|
||||
// timeout of 0 or negative. This will ensure that a vibration has
|
||||
// either a timeout of > 0 or a non-null pattern.
|
||||
@@ -122,7 +127,7 @@ public class VibratorService extends IVibratorService.Stub {
|
||||
// longer than milliseconds.
|
||||
return;
|
||||
}
|
||||
Vibration vib = new Vibration(token, milliseconds);
|
||||
Vibration vib = new Vibration(token, milliseconds, uid);
|
||||
synchronized (mVibrations) {
|
||||
removeVibrationLocked(token);
|
||||
doCancelVibrateLocked();
|
||||
@@ -146,6 +151,7 @@ public class VibratorService extends IVibratorService.Stub {
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
throw new SecurityException("Requires VIBRATE permission");
|
||||
}
|
||||
int uid = Binder.getCallingUid();
|
||||
// so wakelock calls will succeed
|
||||
long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -165,7 +171,7 @@ public class VibratorService extends IVibratorService.Stub {
|
||||
return;
|
||||
}
|
||||
|
||||
Vibration vib = new Vibration(token, pattern, repeat);
|
||||
Vibration vib = new Vibration(token, pattern, repeat, uid);
|
||||
try {
|
||||
token.linkToDeath(vib, 0);
|
||||
} catch (RemoteException e) {
|
||||
@@ -280,6 +286,8 @@ public class VibratorService extends IVibratorService.Stub {
|
||||
|
||||
VibrateThread(Vibration vib) {
|
||||
mVibration = vib;
|
||||
mTmpWorkSource.set(vib.mUid);
|
||||
mWakeLock.setWorkSource(mTmpWorkSource);
|
||||
mWakeLock.acquire();
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ import android.os.INetworkManagementService;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.WorkSource;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Slog;
|
||||
@@ -1035,8 +1036,8 @@ public class WifiService extends IWifiManager.Stub {
|
||||
}
|
||||
|
||||
private class WifiLock extends DeathRecipient {
|
||||
WifiLock(int lockMode, String tag, IBinder binder) {
|
||||
super(lockMode, tag, binder);
|
||||
WifiLock(int lockMode, String tag, IBinder binder, WorkSource ws) {
|
||||
super(lockMode, tag, binder, ws);
|
||||
}
|
||||
|
||||
public void binderDied() {
|
||||
@@ -1106,33 +1107,70 @@ public class WifiService extends IWifiManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean acquireWifiLock(IBinder binder, int lockMode, String tag) {
|
||||
void enforceWakeSourcePermission(int uid, int pid) {
|
||||
if (uid == android.os.Process.myUid()) {
|
||||
return;
|
||||
}
|
||||
mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
|
||||
pid, uid, null);
|
||||
}
|
||||
|
||||
public boolean acquireWifiLock(IBinder binder, int lockMode, String tag, WorkSource ws) {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
|
||||
if (lockMode != WifiManager.WIFI_MODE_FULL && lockMode != WifiManager.WIFI_MODE_SCAN_ONLY) {
|
||||
return false;
|
||||
}
|
||||
WifiLock wifiLock = new WifiLock(lockMode, tag, binder);
|
||||
if (ws != null) {
|
||||
enforceWakeSourcePermission(Binder.getCallingUid(), Binder.getCallingPid());
|
||||
}
|
||||
if (ws != null && ws.size() == 0) {
|
||||
ws = null;
|
||||
}
|
||||
if (ws == null) {
|
||||
ws = new WorkSource(Binder.getCallingUid());
|
||||
}
|
||||
WifiLock wifiLock = new WifiLock(lockMode, tag, binder, ws);
|
||||
synchronized (mLocks) {
|
||||
return acquireWifiLockLocked(wifiLock);
|
||||
}
|
||||
}
|
||||
|
||||
private void noteAcquireWifiLock(WifiLock wifiLock) throws RemoteException {
|
||||
switch(wifiLock.mMode) {
|
||||
case WifiManager.WIFI_MODE_FULL:
|
||||
mBatteryStats.noteFullWifiLockAcquiredFromSource(wifiLock.mWorkSource);
|
||||
break;
|
||||
case WifiManager.WIFI_MODE_SCAN_ONLY:
|
||||
mBatteryStats.noteScanWifiLockAcquiredFromSource(wifiLock.mWorkSource);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void noteReleaseWifiLock(WifiLock wifiLock) throws RemoteException {
|
||||
switch(wifiLock.mMode) {
|
||||
case WifiManager.WIFI_MODE_FULL:
|
||||
mBatteryStats.noteFullWifiLockReleasedFromSource(wifiLock.mWorkSource);
|
||||
break;
|
||||
case WifiManager.WIFI_MODE_SCAN_ONLY:
|
||||
mBatteryStats.noteScanWifiLockReleasedFromSource(wifiLock.mWorkSource);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean acquireWifiLockLocked(WifiLock wifiLock) {
|
||||
Slog.d(TAG, "acquireWifiLockLocked: " + wifiLock);
|
||||
|
||||
mLocks.addLock(wifiLock);
|
||||
|
||||
int uid = Binder.getCallingUid();
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
noteAcquireWifiLock(wifiLock);
|
||||
switch(wifiLock.mMode) {
|
||||
case WifiManager.WIFI_MODE_FULL:
|
||||
++mFullLocksAcquired;
|
||||
mBatteryStats.noteFullWifiLockAcquired(uid);
|
||||
break;
|
||||
case WifiManager.WIFI_MODE_SCAN_ONLY:
|
||||
++mScanLocksAcquired;
|
||||
mBatteryStats.noteScanWifiLockAcquired(uid);
|
||||
break;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
@@ -1144,6 +1182,33 @@ public class WifiService extends IWifiManager.Stub {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateWifiLockWorkSource(IBinder lock, WorkSource ws) {
|
||||
int uid = Binder.getCallingUid();
|
||||
int pid = Binder.getCallingPid();
|
||||
if (ws != null && ws.size() == 0) {
|
||||
ws = null;
|
||||
}
|
||||
if (ws != null) {
|
||||
enforceWakeSourcePermission(uid, pid);
|
||||
}
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLocks) {
|
||||
int index = mLocks.findLockByBinder(lock);
|
||||
if (index < 0) {
|
||||
throw new IllegalArgumentException("Wifi lock not active");
|
||||
}
|
||||
WifiLock wl = mLocks.mList.get(index);
|
||||
noteReleaseWifiLock(wl);
|
||||
wl.mWorkSource = ws != null ? new WorkSource(ws) : new WorkSource(uid);
|
||||
noteAcquireWifiLock(wl);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean releaseWifiLock(IBinder lock) {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
|
||||
synchronized (mLocks) {
|
||||
@@ -1161,17 +1226,15 @@ public class WifiService extends IWifiManager.Stub {
|
||||
hadLock = (wifiLock != null);
|
||||
|
||||
if (hadLock) {
|
||||
int uid = Binder.getCallingUid();
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
noteAcquireWifiLock(wifiLock);
|
||||
switch(wifiLock.mMode) {
|
||||
case WifiManager.WIFI_MODE_FULL:
|
||||
++mFullLocksReleased;
|
||||
mBatteryStats.noteFullWifiLockReleased(uid);
|
||||
break;
|
||||
case WifiManager.WIFI_MODE_SCAN_ONLY:
|
||||
++mScanLocksReleased;
|
||||
mBatteryStats.noteScanWifiLockReleased(uid);
|
||||
break;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
@@ -1189,12 +1252,14 @@ public class WifiService extends IWifiManager.Stub {
|
||||
String mTag;
|
||||
int mMode;
|
||||
IBinder mBinder;
|
||||
WorkSource mWorkSource;
|
||||
|
||||
DeathRecipient(int mode, String tag, IBinder binder) {
|
||||
DeathRecipient(int mode, String tag, IBinder binder, WorkSource ws) {
|
||||
super();
|
||||
mTag = tag;
|
||||
mMode = mode;
|
||||
mBinder = binder;
|
||||
mWorkSource = ws;
|
||||
try {
|
||||
mBinder.linkToDeath(this, 0);
|
||||
} catch (RemoteException e) {
|
||||
@@ -1209,7 +1274,7 @@ public class WifiService extends IWifiManager.Stub {
|
||||
|
||||
private class Multicaster extends DeathRecipient {
|
||||
Multicaster(String tag, IBinder binder) {
|
||||
super(Binder.getCallingUid(), tag, binder);
|
||||
super(Binder.getCallingUid(), tag, binder, null);
|
||||
}
|
||||
|
||||
public void binderDied() {
|
||||
|
||||
@@ -6021,12 +6021,18 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
finisher = new IIntentReceiver.Stub() {
|
||||
public void performReceive(Intent intent, int resultCode,
|
||||
String data, Bundle extras, boolean ordered,
|
||||
boolean sticky)
|
||||
throws RemoteException {
|
||||
synchronized (ActivityManagerService.this) {
|
||||
mDidUpdate = true;
|
||||
}
|
||||
systemReady(goingCallback);
|
||||
boolean sticky) {
|
||||
// The raw IIntentReceiver interface is called
|
||||
// with the AM lock held, so redispatch to
|
||||
// execute our code without the lock.
|
||||
mHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
synchronized (ActivityManagerService.this) {
|
||||
mDidUpdate = true;
|
||||
}
|
||||
systemReady(goingCallback);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Process;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.WorkSource;
|
||||
import android.telephony.SignalStrength;
|
||||
import android.util.Slog;
|
||||
|
||||
@@ -107,6 +108,20 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
public void noteStartWakelockFromSource(WorkSource ws, int pid, String name, int type) {
|
||||
enforceCallingPermission();
|
||||
synchronized (mStats) {
|
||||
mStats.noteStartWakeFromSourceLocked(ws, pid, name, type);
|
||||
}
|
||||
}
|
||||
|
||||
public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, int type) {
|
||||
enforceCallingPermission();
|
||||
synchronized (mStats) {
|
||||
mStats.noteStopWakeFromSourceLocked(ws, pid, name, type);
|
||||
}
|
||||
}
|
||||
|
||||
public void noteStartSensor(int uid, int sensor) {
|
||||
enforceCallingPermission();
|
||||
synchronized (mStats) {
|
||||
@@ -317,6 +332,48 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
public void noteFullWifiLockAcquiredFromSource(WorkSource ws) {
|
||||
enforceCallingPermission();
|
||||
synchronized (mStats) {
|
||||
mStats.noteFullWifiLockAcquiredFromSourceLocked(ws);
|
||||
}
|
||||
}
|
||||
|
||||
public void noteFullWifiLockReleasedFromSource(WorkSource ws) {
|
||||
enforceCallingPermission();
|
||||
synchronized (mStats) {
|
||||
mStats.noteFullWifiLockReleasedFromSourceLocked(ws);
|
||||
}
|
||||
}
|
||||
|
||||
public void noteScanWifiLockAcquiredFromSource(WorkSource ws) {
|
||||
enforceCallingPermission();
|
||||
synchronized (mStats) {
|
||||
mStats.noteScanWifiLockAcquiredFromSourceLocked(ws);
|
||||
}
|
||||
}
|
||||
|
||||
public void noteScanWifiLockReleasedFromSource(WorkSource ws) {
|
||||
enforceCallingPermission();
|
||||
synchronized (mStats) {
|
||||
mStats.noteScanWifiLockReleasedFromSourceLocked(ws);
|
||||
}
|
||||
}
|
||||
|
||||
public void noteWifiMulticastEnabledFromSource(WorkSource ws) {
|
||||
enforceCallingPermission();
|
||||
synchronized (mStats) {
|
||||
mStats.noteWifiMulticastEnabledFromSourceLocked(ws);
|
||||
}
|
||||
}
|
||||
|
||||
public void noteWifiMulticastDisabledFromSource(WorkSource ws) {
|
||||
enforceCallingPermission();
|
||||
synchronized (mStats) {
|
||||
mStats.noteWifiMulticastDisabledFromSourceLocked(ws);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOnBattery() {
|
||||
return mStats.isOnBattery();
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.WorkSource;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.util.SparseIntArray;
|
||||
@@ -736,7 +737,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
|
||||
startNavigating(true);
|
||||
}
|
||||
|
||||
public void setMinTime(long minTime) {
|
||||
public void setMinTime(long minTime, WorkSource ws) {
|
||||
if (DEBUG) Log.d(TAG, "setMinTime " + minTime);
|
||||
|
||||
if (minTime >= 0) {
|
||||
@@ -779,7 +780,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
|
||||
public void addListener(int uid) {
|
||||
synchronized (mWakeLock) {
|
||||
mPendingListenerMessages++;
|
||||
mWakeLock.acquire();
|
||||
mWakeLock.acquire();
|
||||
Message m = Message.obtain(mHandler, ADD_LISTENER);
|
||||
m.arg1 = uid;
|
||||
mHandler.sendMessage(m);
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.location.Criteria;
|
||||
import android.location.Location;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.WorkSource;
|
||||
|
||||
/**
|
||||
* Location Manager's interface for location providers.
|
||||
@@ -47,7 +48,7 @@ public interface LocationProviderInterface {
|
||||
/* returns false if single shot is not supported */
|
||||
boolean requestSingleShotFix();
|
||||
String getInternalState();
|
||||
void setMinTime(long minTime);
|
||||
void setMinTime(long minTime, WorkSource ws);
|
||||
void updateNetworkState(int state, NetworkInfo info);
|
||||
void updateLocation(Location location);
|
||||
boolean sendExtraCommand(String command, Bundle extras);
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.WorkSource;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.location.DummyLocationProvider;
|
||||
@@ -52,6 +53,7 @@ public class LocationProviderProxy implements LocationProviderInterface {
|
||||
private boolean mLocationTracking = false;
|
||||
private boolean mEnabled = false;
|
||||
private long mMinTime = -1;
|
||||
private WorkSource mMinTimeSource = new WorkSource();
|
||||
private int mNetworkState;
|
||||
private NetworkInfo mNetworkInfo;
|
||||
|
||||
@@ -122,7 +124,7 @@ public class LocationProviderProxy implements LocationProviderInterface {
|
||||
provider.enableLocationTracking(true);
|
||||
}
|
||||
if (mMinTime >= 0) {
|
||||
provider.setMinTime(mMinTime);
|
||||
provider.setMinTime(mMinTime, mMinTimeSource);
|
||||
}
|
||||
if (mNetworkInfo != null) {
|
||||
provider.updateNetworkState(mNetworkState, mNetworkInfo);
|
||||
@@ -318,6 +320,7 @@ public class LocationProviderProxy implements LocationProviderInterface {
|
||||
mLocationTracking = enable;
|
||||
if (!enable) {
|
||||
mMinTime = -1;
|
||||
mMinTimeSource.clear();
|
||||
}
|
||||
ILocationProvider provider;
|
||||
synchronized (mServiceConnection) {
|
||||
@@ -339,15 +342,16 @@ public class LocationProviderProxy implements LocationProviderInterface {
|
||||
return mMinTime;
|
||||
}
|
||||
|
||||
public void setMinTime(long minTime) {
|
||||
mMinTime = minTime;
|
||||
public void setMinTime(long minTime, WorkSource ws) {
|
||||
mMinTime = minTime;
|
||||
mMinTimeSource.set(ws);
|
||||
ILocationProvider provider;
|
||||
synchronized (mServiceConnection) {
|
||||
provider = mProvider;
|
||||
}
|
||||
if (provider != null) {
|
||||
try {
|
||||
provider.setMinTime(minTime);
|
||||
provider.setMinTime(minTime, ws);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.location.LocationProvider;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.WorkSource;
|
||||
import android.util.Log;
|
||||
import android.util.PrintWriterPrinter;
|
||||
|
||||
@@ -201,7 +202,7 @@ public class MockProvider implements LocationProviderInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setMinTime(long minTime) {
|
||||
public void setMinTime(long minTime, WorkSource ws) {
|
||||
}
|
||||
|
||||
public void updateNetworkState(int state, NetworkInfo info) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.location.LocationProvider;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.WorkSource;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
@@ -123,7 +124,7 @@ public class PassiveProvider implements LocationProviderInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setMinTime(long minTime) {
|
||||
public void setMinTime(long minTime, WorkSource ws) {
|
||||
}
|
||||
|
||||
public void updateNetworkState(int state, NetworkInfo info) {
|
||||
|
||||
@@ -21,6 +21,8 @@ import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.DhcpInfo;
|
||||
|
||||
import android.os.WorkSource;
|
||||
|
||||
/**
|
||||
* Interface that allows controlling and querying Wi-Fi connectivity.
|
||||
*
|
||||
@@ -66,7 +68,9 @@ interface IWifiManager
|
||||
|
||||
DhcpInfo getDhcpInfo();
|
||||
|
||||
boolean acquireWifiLock(IBinder lock, int lockType, String tag);
|
||||
boolean acquireWifiLock(IBinder lock, int lockType, String tag, in WorkSource ws);
|
||||
|
||||
void updateWifiLockWorkSource(IBinder lock, in WorkSource ws);
|
||||
|
||||
boolean releaseWifiLock(IBinder lock);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.WorkSource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -1050,6 +1051,7 @@ public class WifiManager {
|
||||
int mLockType;
|
||||
private boolean mRefCounted;
|
||||
private boolean mHeld;
|
||||
private WorkSource mWorkSource;
|
||||
|
||||
private WifiLock(int lockType, String tag) {
|
||||
mTag = tag;
|
||||
@@ -1075,7 +1077,7 @@ public class WifiManager {
|
||||
synchronized (mBinder) {
|
||||
if (mRefCounted ? (++mRefCount > 0) : (!mHeld)) {
|
||||
try {
|
||||
mService.acquireWifiLock(mBinder, mLockType, mTag);
|
||||
mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource);
|
||||
synchronized (WifiManager.this) {
|
||||
if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
|
||||
mService.releaseWifiLock(mBinder);
|
||||
@@ -1147,6 +1149,32 @@ public class WifiManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void setWorkSource(WorkSource ws) {
|
||||
synchronized (mBinder) {
|
||||
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.updateWifiLockWorkSource(mBinder, mWorkSource);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String s1, s2, s3;
|
||||
synchronized (mBinder) {
|
||||
|
||||
Reference in New Issue
Block a user