Presentation from droidcon Zagreb 2015
While going through JobScheduler internals try to answer the following question: How big is the gap between us and rockstar developers from Google or Square
13. The APIs arms race
● each new release thousands new APIs
● iOS 8 includes over 4,000 new APIs
● thousands of new Material Designs or new
Bluetooth stacks?
14. The APIs arms race
● the more, the better
● … or just a marketing?
● Android Weekly pressure ;-)
42. BatteryController
public void onReceiveInternal(Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_BATTERY_LOW.equals(action)) {
[...]
// If we get this action, the battery is discharging => it isn't plugged in so
// there's no work to cancel. We track this variable for the case where it is
// charging, but hasn't been for long enough to be healthy.
mBatteryHealthy = false;
} else if (Intent.ACTION_BATTERY_OKAY.equals(action)) {
[...]
mBatteryHealthy = true;
maybeReportNewChargingState();
}
[...]
}
52. Many Googles
● not the same Google for every one of us
● different search results
● different ads
● fine-grained targeting of contents
53.
54.
55.
56. Almost there...
● strong technology marketing
videos, blog posts, APIs arms race
● bold statements about possibilities
idle state, at night, next to the bed
● proven track record
search and ads tailored to our behaviour
58. // Policy: we decide that we're "idle" if the device has been unused
/
// screen off or dreaming for at least this long
private static final long INACTIVITY_IDLE_THRESHOLD = 71 * 60 * 1000;
// millis; 71 min
private static final long IDLE_WINDOW_SLOP = 5 * 60 * 1000;
// 5 minute window, to be nice
quotes are here ;-)
59. The “idle” state algorithm
1. display turns off
2. start the timer for 71 minutes +/- 5 minutes
3. alarm goes off
4. if screen still turned off
we are in the idle state
60. @Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(Intent.ACTION_SCREEN_ON)
|| action.equals(Intent.ACTION_DREAMING_STOPPED)) {
// possible transition to not-idle
if (mIdle) {
[...]
mAlarm.cancel(mIdleTriggerIntent);
mIdle = false;
reportNewIdleState(mIdle);
}
[...]
61. @Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
[...]
} else if (action.equals(Intent.ACTION_SCREEN_OFF)
|| action.equals(Intent.ACTION_DREAMING_STARTED)) {
// when the screen goes off or dreaming starts, we schedule the
// alarm that will tell us when we have decided the device is
// truly idle.
final long nowElapsed = SystemClock.elapsedRealtime();
final long when = nowElapsed + INACTIVITY_IDLE_THRESHOLD;
if (DEBUG) {
Slog.v(TAG, "Scheduling idle : " + action + " now:" + nowElapsed + " when="
+ when);
}
mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
when, IDLE_WINDOW_SLOP, mIdleTriggerIntent);
}
[...]
62. @Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
[...]
} else if (action.equals(ACTION_TRIGGER_IDLE)) {
// idle time starts now
if (!mIdle) {
if (DEBUG) {
Slog.v(TAG, "Idle trigger fired @ " + SystemClock.elapsedRealtime());
}
mIdle = true;
reportNewIdleState(mIdle);
}
}
}
63. The “idle” state algorithm
● time is not a factor
at night
● sensors not used
lying next to the bed
64. The “idle” state algorithm
● display the only factor
how long is being turned off
● not tuned per user
same for everyone
not based on our own behaviour
65. The “idle” state algorithm
● random 71 minutes
or maybe there is some magic here?
66. Takeaways
● don’t be afraid to look at the code
not a rocket science there
can cure from inferiority complex
● write code to get better
it always sucks with the first version
gets better which each commit or PR