下面列出了怎么用android.os.WorkSource的API类实例代码及写法,或者点击链接到github查看源代码。
private void setImplLocked(int type, long when, long whenElapsed, long windowLength,
long maxWhen, long interval, PendingIntent operation, IAlarmListener directReceiver,
String listenerTag, int flags, boolean doValidate, WorkSource workSource,
AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage) {
Alarm a = new Alarm(type, when, whenElapsed, windowLength, maxWhen, interval,
operation, directReceiver, listenerTag, workSource, flags, alarmClock,
callingUid, callingPackage);
try {
if (ActivityManager.getService().isAppStartModeDisabled(callingUid, callingPackage)) {
Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a
+ " -- package not allowed to start");
return;
}
} catch (RemoteException e) {
}
removeLocked(operation, directReceiver);
setImplLocked(a, false, doValidate);
}
public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen,
long _interval, PendingIntent _op, IAlarmListener _rec, String _listenerTag,
WorkSource _ws, int _flags, AlarmManager.AlarmClockInfo _info,
int _uid, String _pkgName) {
type = _type;
origWhen = _when;
wakeup = _type == AlarmManager.ELAPSED_REALTIME_WAKEUP
|| _type == AlarmManager.RTC_WAKEUP;
when = _when;
whenElapsed = _whenElapsed;
expectedWhenElapsed = _whenElapsed;
windowLength = _windowLength;
maxWhenElapsed = expectedMaxWhenElapsed = clampPositive(_maxWhen);
repeatInterval = _interval;
operation = _op;
listener = _rec;
listenerTag = _listenerTag;
statsTag = makeTag(_op, _listenerTag, _type);
workSource = _ws;
flags = _flags;
alarmClock = _info;
uid = _uid;
packageName = _pkgName;
sourcePackage = (operation != null) ? operation.getCreatorPackage() : packageName;
creatorUid = (operation != null) ? operation.getCreatorUid() : uid;
}
public void scheduleTimeTickEvent() {
final long currentTime = System.currentTimeMillis();
final long nextTime = 60000 * ((currentTime / 60000) + 1);
// Schedule this event for the amount of time that it would take to get to
// the top of the next minute.
final long tickEventDelay = nextTime - currentTime;
final WorkSource workSource = null; // Let system take blame for time tick events.
setImpl(ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 0,
0, mTimeTickSender, null, null, AlarmManager.FLAG_STANDALONE, workSource,
null, Process.myUid(), "android");
// Finally, remember when we set the tick alarm
synchronized (mLock) {
mLastTickSet = currentTime;
}
}
@Override
public void startHook() {
Method setImplmethod = RefInvoke.findMethodExact(
"android.app.AlarmManager", ClassLoader.getSystemClassLoader(),
"setImpl",int.class,long.class,long.class,long.class,PendingIntent.class,WorkSource.class);
hookhelper.hookMethod(setImplmethod, new AbstractBahaviorHookCallBack() {
@Override
public void descParam(HookParam param) {
Logger.log_behavior("The Alarm Information:");
PendingIntent intent = (PendingIntent) param.args[4];
descPendingIntent(intent);
Logger.log_behavior("TriggerAtMillis = "+param.args[1]);
Logger.log_behavior("windowMillis = "+param.args[2]);
Logger.log_behavior("intervalMillis = "+param.args[3]);
}
});
}
@Override // Binder call
public void updateWakeLockWorkSource(IBinder lock, WorkSource ws, String historyTag) {
if (lock == null) {
throw new IllegalArgumentException("lock must not be null");
}
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
if (ws != null && !ws.isEmpty()) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.UPDATE_DEVICE_STATS, null);
} else {
ws = null;
}
final int callingUid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
updateWakeLockWorkSourceInternal(lock, ws, historyTag, callingUid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
@Override
public void startHook() {
Method setImplmethod = RefInvoke.findMethodExact(
"android.app.AlarmManager", ClassLoader.getSystemClassLoader(),
"setImpl",int.class,long.class,long.class,long.class,PendingIntent.class,WorkSource.class);
hookhelper.hookMethod(setImplmethod, new AbstractBahaviorHookCallBack() {
@Override
public void descParam(HookParam param) {
Logger.log_behavior("The Alarm Information:");
PendingIntent intent = (PendingIntent) param.args[4];
if(intent != null)
descPendingIntent(intent);
Logger.log_behavior("TriggerAtMillis = "+param.args[1]);
Logger.log_behavior("windowMillis = "+param.args[2]);
Logger.log_behavior("intervalMillis = "+param.args[3]);
}
});
}
@Override
public void startHook() {
Method setImplmethod = RefInvoke.findMethodExact(
"android.app.AlarmManager", ClassLoader.getSystemClassLoader(),
"setImpl",int.class,long.class,long.class,long.class,PendingIntent.class,WorkSource.class);
hookhelper.hookMethod(setImplmethod, new AbstractBahaviorHookCallBack() {
@Override
public void descParam(HookParam param) {
Logger.log_behavior("The Alarm Information:");
PendingIntent intent = (PendingIntent) param.args[4];
descPendingIntent(intent);
Logger.log_behavior("TriggerAtMillis = "+param.args[1]);
Logger.log_behavior("windowMillis = "+param.args[2]);
Logger.log_behavior("intervalMillis = "+param.args[3]);
}
});
}
private Receiver getReceiverLocked(ILocationListener listener, int pid, int uid,
String packageName, WorkSource workSource, boolean hideFromAppOps) {
IBinder binder = listener.asBinder();
Receiver receiver = mReceivers.get(binder);
if (receiver == null) {
receiver = new Receiver(listener, null, pid, uid, packageName, workSource,
hideFromAppOps);
try {
receiver.getListener().asBinder().linkToDeath(receiver, 0);
} catch (RemoteException e) {
Slog.e(TAG, "linkToDeath failed:", e);
return null;
}
mReceivers.put(binder, receiver);
}
return receiver;
}
@Override
public void removeUpdates(ILocationListener listener, PendingIntent intent,
String packageName) {
checkPackageName(packageName);
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
synchronized (mLock) {
WorkSource workSource = null;
boolean hideFromAppOps = false;
Receiver receiver = checkListenerOrIntentLocked(listener, intent, pid, uid,
packageName, workSource, hideFromAppOps);
// providers may use public location API's, need to clear identity
long identity = Binder.clearCallingIdentity();
try {
removeUpdatesLocked(receiver);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
@Override
public void startHook() {
Method setImplmethod = RefInvoke.findMethodExact(
"android.app.AlarmManager", ClassLoader.getSystemClassLoader(),
"setImpl",int.class,long.class,long.class,long.class,PendingIntent.class,WorkSource.class);
hookhelper.hookMethod(setImplmethod, new AbstractBahaviorHookCallBack() {
@Override
public void descParam(HookParam param) {
Logger.log_behavior("The Alarm Information:");
PendingIntent intent = (PendingIntent) param.args[4];
descPendingIntent(intent);
Logger.log_behavior("TriggerAtMillis = "+param.args[1]);
Logger.log_behavior("windowMillis = "+param.args[2]);
Logger.log_behavior("intervalMillis = "+param.args[3]);
}
});
}
public void registerScanner(BleScanCallbackWrapper scanWrapper, WorkSource workSource) {
scanners.put(scanWrapper, workSource);
int i = 0;
for (BleScanCallbackWrapper wrapper : scanners.keySet()) {
if (wrapper.equals(scanWrapper)) {
break;
}
i++;
}
scanWrapper.onScannerRegistered(0, i);
}
public BleScanCallbackWrapper(IBluetoothGatt bluetoothGatt,
List<ScanFilter> filters, ScanSettings settings,
WorkSource workSource, ScanCallback scanCallback,
List<List<ResultStorageDescriptor>> resultStorages) {
mBluetoothGatt = bluetoothGatt;
mFilters = filters;
mSettings = settings;
mWorkSource = workSource;
mScanCallback = scanCallback;
mScannerId = 0;
mResultStorages = resultStorages;
}
/**
* Attribute blame for a WakeLock.
* @param pi PendingIntent to attribute blame to if ws is null.
* @param ws WorkSource to attribute blame.
* @param knownUid attribution uid; < 0 if we need to derive it from the PendingIntent sender
*/
void setWakelockWorkSource(PendingIntent pi, WorkSource ws, int type, String tag,
int knownUid, boolean first) {
try {
final boolean unimportant = pi == mTimeTickSender;
mWakeLock.setUnimportantForLogging(unimportant);
if (first || mLastWakeLockUnimportantForLogging) {
mWakeLock.setHistoryTag(tag);
} else {
mWakeLock.setHistoryTag(null);
}
mLastWakeLockUnimportantForLogging = unimportant;
if (ws != null) {
mWakeLock.setWorkSource(ws);
return;
}
final int uid = (knownUid >= 0)
? knownUid
: ActivityManager.getService().getUidForIntentSender(pi.getTarget());
if (uid >= 0) {
mWakeLock.setWorkSource(new WorkSource(uid));
return;
}
} catch (Exception e) {
}
// Something went wrong; fall back to attributing the lock to the OS
mWakeLock.setWorkSource(null);
}
public void scheduleDateChangedEvent() {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
calendar.add(Calendar.DAY_OF_MONTH, 1);
final WorkSource workSource = null; // Let system take blame for date change events.
setImpl(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, null, null,
AlarmManager.FLAG_STANDALONE, workSource, null,
Process.myUid(), "android");
}
public TimeController(JobSchedulerService service) {
super(service);
mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
mChainedAttributionEnabled = WorkSource.isChainedBatteryAttributionEnabled(mContext);
}
private WorkSource deriveWorkSource(int uid, @Nullable String packageName) {
if (mChainedAttributionEnabled) {
WorkSource ws = new WorkSource();
ws.createWorkChain()
.addNode(uid, packageName)
.addNode(Process.SYSTEM_UID, "JobScheduler");
return ws;
} else {
return packageName == null ? new WorkSource(uid) : new WorkSource(uid, packageName);
}
}
private void maybeUpdateAlarmsLocked(long delayExpiredElapsed, long deadlineExpiredElapsed,
WorkSource ws) {
if (delayExpiredElapsed < mNextDelayExpiredElapsedMillis) {
setDelayExpiredAlarmLocked(delayExpiredElapsed, ws);
}
if (deadlineExpiredElapsed < mNextJobExpiredElapsedMillis) {
setDeadlineExpiredAlarmLocked(deadlineExpiredElapsed, ws);
}
}
/**
* Set an alarm with the {@link android.app.AlarmManager} for the next time at which a job's
* delay will expire.
* This alarm <b>will</b> wake up the phone.
*/
private void setDelayExpiredAlarmLocked(long alarmTimeElapsedMillis, WorkSource ws) {
alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis);
mNextDelayExpiredElapsedMillis = alarmTimeElapsedMillis;
updateAlarmWithListenerLocked(DELAY_TAG, mNextDelayExpiredListener,
mNextDelayExpiredElapsedMillis, ws);
}
private void updateAlarmWithListenerLocked(String tag, OnAlarmListener listener,
long alarmTimeElapsed, WorkSource ws) {
ensureAlarmServiceLocked();
if (alarmTimeElapsed == Long.MAX_VALUE) {
mAlarmService.cancel(listener);
} else {
if (DEBUG) {
Slog.d(TAG, "Setting " + tag + " for: " + alarmTimeElapsed);
}
mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTimeElapsed,
AlarmManager.WINDOW_HEURISTIC, 0, tag, listener, null, ws);
}
}
private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws, String historyTag,
int callingUid) {
synchronized (mLock) {
int index = findWakeLockIndexLocked(lock);
if (index < 0) {
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakeLockWorkSourceInternal: lock=" + Objects.hashCode(lock)
+ " [not found], ws=" + ws);
}
throw new IllegalArgumentException("Wake lock not active: " + lock
+ " from uid " + callingUid);
}
WakeLock wakeLock = mWakeLocks.get(index);
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakeLockWorkSourceInternal: lock=" + Objects.hashCode(lock)
+ " [" + wakeLock.mTag + "], ws=" + ws);
}
if (!wakeLock.hasSameWorkSource(ws)) {
notifyWakeLockChangingLocked(wakeLock, wakeLock.mFlags, wakeLock.mTag,
wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid,
ws, historyTag);
wakeLock.mHistoryTag = historyTag;
wakeLock.updateWorkSource(ws);
}
}
}
private void notifyWakeLockChangingLocked(WakeLock wakeLock, int flags, String tag,
String packageName, int uid, int pid, WorkSource ws, String historyTag) {
if (mSystemReady && wakeLock.mNotifiedAcquired) {
mNotifier.onWakeLockChanging(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
wakeLock.mHistoryTag, flags, tag, packageName, uid, pid, ws, historyTag);
notifyWakeLockLongFinishedLocked(wakeLock);
// Changing the wake lock will count as releasing the old wake lock(s) and
// acquiring the new ones... we do this because otherwise once a wakelock
// becomes long, if we just continued to treat it as long we can get in to
// situations where we spam battery stats with every following change to it.
restartNofifyLongTimerLocked(wakeLock);
}
}
public WakeLock(IBinder lock, int flags, String tag, String packageName,
WorkSource workSource, String historyTag, int ownerUid, int ownerPid,
UidState uidState) {
mLock = lock;
mFlags = flags;
mTag = tag;
mPackageName = packageName;
mWorkSource = copyWorkSource(workSource);
mHistoryTag = historyTag;
mOwnerUid = ownerUid;
mOwnerPid = ownerPid;
mUidState = uidState;
}
public boolean hasSameProperties(int flags, String tag, WorkSource workSource,
int ownerUid, int ownerPid) {
return mFlags == flags
&& mTag.equals(tag)
&& hasSameWorkSource(workSource)
&& mOwnerUid == ownerUid
&& mOwnerPid == ownerPid;
}
@Override // Binder call
public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,
String packageName, int uid) {
if (uid < 0) {
uid = Binder.getCallingUid();
}
acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null);
}
@Override // Binder call
public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
WorkSource ws, String historyTag) {
if (lock == null) {
throw new IllegalArgumentException("lock must not be null");
}
if (packageName == null) {
throw new IllegalArgumentException("packageName must not be null");
}
PowerManager.validateWakeLockParameters(flags, tag);
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
if ((flags & PowerManager.DOZE_WAKE_LOCK) != 0) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
}
if (ws != null && !ws.isEmpty()) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.UPDATE_DEVICE_STATS, null);
} else {
ws = null;
}
final int uid = Binder.getCallingUid();
final int pid = Binder.getCallingPid();
final long ident = Binder.clearCallingIdentity();
try {
acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
/**
* Called when a wake lock is acquired.
*/
public void onWakeLockAcquired(int flags, String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
if (DEBUG) {
Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
+ "\", packageName=" + packageName
+ ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+ ", workSource=" + workSource);
}
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
if (monitorType >= 0) {
try {
final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
&& (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
if (workSource != null) {
mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
historyTag, monitorType, unimportantForLogging);
} else {
mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
monitorType, unimportantForLogging);
// XXX need to deal with disabled operations.
mAppOps.startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
}
} catch (RemoteException ex) {
// Ignore
}
}
}
/**
* Called when a wake lock is changing.
*/
public void onWakeLockChanging(int flags, String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
int newFlags, String newTag, String newPackageName, int newOwnerUid,
int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
if (workSource != null && newWorkSource != null
&& monitorType >= 0 && newMonitorType >= 0) {
if (DEBUG) {
Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
+ "\", packageName=" + newPackageName
+ ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
+ ", workSource=" + newWorkSource);
}
final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID
&& (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
try {
mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, historyTag,
monitorType, newWorkSource, newOwnerPid, newTag, newHistoryTag,
newMonitorType, unimportantForLogging);
} catch (RemoteException ex) {
// Ignore
}
} else {
onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag);
onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
newWorkSource, newHistoryTag);
}
}
/**
* @hide
*/
public static void noteAlarmFinish(PendingIntent ps, WorkSource workSource, int sourceUid,
String tag) {
try {
getService().noteAlarmFinish((ps != null) ? ps.getTarget() : null, workSource,
sourceUid, tag);
} catch (RemoteException ex) {
}
}
/**
* Whether a given {@code WorkSource} associated with a Location request is valid.
*/
private static boolean isValidWorkSource(WorkSource workSource) {
if (workSource.size() > 0) {
// If the WorkSource has one or more non-chained UIDs, make sure they're accompanied
// by tags.
return workSource.getName(0) != null;
} else {
// For now, make sure callers have supplied an attribution tag for use with
// AppOpsManager. This might be relaxed in the future.
final ArrayList<WorkChain> workChains = workSource.getWorkChains();
return workChains != null && !workChains.isEmpty() &&
workChains.get(0).getAttributionTag() != null;
}
}
private Receiver getReceiverLocked(PendingIntent intent, int pid, int uid, String packageName,
WorkSource workSource, boolean hideFromAppOps) {
Receiver receiver = mReceivers.get(intent);
if (receiver == null) {
receiver = new Receiver(null, intent, pid, uid, packageName, workSource,
hideFromAppOps);
mReceivers.put(intent, receiver);
}
return receiver;
}