knock, knock, who is there? doze

89
Yonatan Levin Google Developer Expert levin.yonatan parahall

Upload: yonatan-levin

Post on 16-Apr-2017

610 views

Category:

Software


4 download

TRANSCRIPT

Page 1: Knock, knock, who is there? Doze

Yonatan LevinGoogle Developer Expert

levin.yonatanparahall

Page 2: Knock, knock, who is there? Doze

72 Cities > 20M usersRuby, Go, Python, Microservices

Page 3: Knock, knock, who is there? Doze

~ 1600 members Largest Android Active Community

Page 4: Knock, knock, who is there? Doze

:)

The story about the shy guy

Doze Mode

Page 5: Knock, knock, who is there? Doze
Page 6: Knock, knock, who is there? Doze
Page 7: Knock, knock, who is there? Doze
Page 8: Knock, knock, who is there? Doze
Page 9: Knock, knock, who is there? Doze

Doze, the bro :)

No network access

No jobs/ No syncs

No wakelocks

No alarms

No GPS / Wifi Scans

Page 10: Knock, knock, who is there? Doze

Doze Mode on Marshmallow

Page 11: Knock, knock, who is there? Doze
Page 12: Knock, knock, who is there? Doze
Page 13: Knock, knock, who is there? Doze

Not shy anymore

Page 14: Knock, knock, who is there? Doze

Doze Mode on Nougat

Page 15: Knock, knock, who is there? Doze

When?

All intervals are configurable by Google/Manufacturer.

Page 16: Knock, knock, who is there? Doze

DeviceIdleControler

PowerManagerService

NetworkPolicyManagerService

BatteryStatsServicedeviceidle.xml

Page 17: Knock, knock, who is there? Doze

Statistics on OnePlus 3 (Marshmallow)

Page 18: Knock, knock, who is there? Doze

Statistics on Nexus 6P (Nougat)

Page 19: Knock, knock, who is there? Doze

Time

5m

5m

5s

10m

7s

14m

12s

14m

12s

11m 57 minutes

51s

2 hours

30s

3 hours 44 minutes

Maintenance Light Doze Doze

Page 20: Knock, knock, who is there? Doze

Statistics on Nexus 6P (Nougat)

Page 21: Knock, knock, who is there? Doze
Page 22: Knock, knock, who is there? Doze

Doze, sweet, Doze,Let me go...

Page 23: Knock, knock, who is there? Doze

Charge it...

Page 25: Knock, knock, who is there? Doze

No network access

Page 26: Knock, knock, who is there? Doze

GCM/FCM

Use FCM with High priority - but treat it with special care

{

"to" : "...",

"priority" : "high",

"notification" : {

...

},

"data" : {

...

}

}

Page 27: Knock, knock, who is there? Doze

WhiteList

● An app can fire the ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS intent to take the user directly to the Battery Optimization, where they can add the app.

Page 28: Knock, knock, who is there? Doze

Note: Google Play policies prohibit apps from requesting direct exemption from Power

Management features in Android 6.0+ (Doze and App Standby) unless the core function of

the app is adversely affected.

Page 29: Knock, knock, who is there? Doze

And it’s not all, folks

Page 30: Knock, knock, who is there? Doze

CONNECTIVITY_CHANGES

Page 31: Knock, knock, who is there? Doze
Page 32: Knock, knock, who is there? Doze
Page 33: Knock, knock, who is there? Doze

My shiny new app

git clone [email protected]:parahall/final_battle_doze.git

Page 34: Knock, knock, who is there? Doze
Page 35: Knock, knock, who is there? Doze
Page 36: Knock, knock, who is there? Doze
Page 37: Knock, knock, who is there? Doze
Page 38: Knock, knock, who is there? Doze

public class FinalBattleActivity

public void onClick(View v) {

switch (v.getId()) {

case R.id.kill_button:

StarWarsUtils.makeDecision(

LukeDecision.LUKE_KILL_DARTH_VADER, this);

break;

case R.id.light_side_button:

StarWarsUtils.makeDecision(

LukeDecision.STAY_ON_LIGHT_SIDE, this);

Break;

}

}

Page 39: Knock, knock, who is there? Doze

public class StarWarsUtils {

public static void makeDecision(LukeDecision decision,Context

context) {

Intent nowIntent = new Intent(context, NowIntentService.class);

nowIntent.putExtra(..., decision);

context.startService(nowIntent);

}

Page 40: Knock, knock, who is there? Doze

public class NowIntentService extends IntentService {

protected void onHandleIntent(Intent intent) {

LukeDecision decision =

(LukeDecision)intent.getSerializableExtra(...);

if (decision != null) {

makeNetworkCall(decision);

}

...

}

Page 41: Knock, knock, who is there? Doze

public class NowIntentService extends IntentService {

private void makeNetworkCall(LukeDecision decision) {

boolean isCompleted = false;

if(StarWarsUtils.isNetworkActive()) {

isCompleted = doingNetworkCommunication();

}

...

}

Page 42: Knock, knock, who is there? Doze

public class NowIntentService extends IntentService {

private void makeNetworkCall(LukeDecision decision) {

...

if (!isCompleted) {

StarWarsUtils.addRetryTask(decision, this);

return;

}

...

}

Page 43: Knock, knock, who is there? Doze

How we will retry the request if it’s failed?

Page 44: Knock, knock, who is there? Doze

Connectivity Manager

Page 45: Knock, knock, who is there? Doze

AndroidManifest.xml

<receiver android:name=".ConnectivityChangeReceiver">

<intent-filter>

<action

android:name="android.net.conn.CONNECTIVITY_CHANGE"/>

</intent-filter>

</receiver>

Page 46: Knock, knock, who is there? Doze

public void onReceive(Context context, Intent intent) {

LukeDecision decisionToRetry =

StarWarsUtils.getDecisionToRetry(context);

StarWarsUtils.makeDecision(decisionToRetry, context);

}

public class ConnectivityChangeReceiver extends WakefulBroadcastReceiver

Page 47: Knock, knock, who is there? Doze
Page 48: Knock, knock, who is there? Doze

Han Solo reporting to Rebels

Page 49: Knock, knock, who is there? Doze
Page 50: Knock, knock, who is there? Doze

public class FinalBattleActivity extends AppCompatActivity

protected void onCreate(Bundle savedInstanceState) {

...

scheduleHanSoloReport();

...

}

Page 51: Knock, knock, who is there? Doze

public class FinalBattleActivity extends AppCompatActivity

private void scheduleHanSoloReport() {

AlarmManager alarmManager = (AlarmManager)

getSystemService(ALARM_SERVICE);

PendingIntent broadcast = getPendingIntent();

alarmManager.setRepeating(

AlarmManager.RTC_WAKEUP,

System.currentTimeMillis(),

ONE_MINUTE,

broadcast);

}

Page 52: Knock, knock, who is there? Doze

public class HanSoloReceiver

public void onReceive(Context context, Intent intent) {

LocationManager locationService = (LocationManager)

context.getSystemService(Context.LOCATION_SERVICE);

PendingIntent pendingIntent = getPendingIntent(context);

String provider = getLocationProvider(locationService);

locationService.requestSingleUpdate(provider, pendingIntent);

}

Page 53: Knock, knock, who is there? Doze

public class NowIntentService extends IntentService {

@Override protected void onHandleIntent(Intent intent) {

...

Location HanSoloLocation =

intent.getParcelableExtra(LocationManager.KEY_LOCATION_CHANGED);

if (HanSoloLocation != null) {

checkIfRebelsReady(HanSoloLocation);

}

}

Page 54: Knock, knock, who is there? Doze

RebelService

Page 55: Knock, knock, who is there? Doze

public class RebelService extends Service implements Handler.Callback

public void onCreate() {

handlerThread = new HandlerThread("RebelServiceHandlerThread");

handlerThread.start();

Looper looper = handlerThread.getLooper();

handler = new Handler(looper, this);

handler.sendEmptyMessage(WHAT_MAKE_NETWORK_REQUEST);

}

Page 56: Knock, knock, who is there? Doze

public class RebelService extends Service implements Handler.Callback

@Override public boolean handleMessage(Message msg) {

StarWarsUtils.doingNetworkCommunication();

handler.sendEmptyMessageDelayed(

WHAT_MAKE_NETWORK_REQUEST,

DELAY_MILLIS);

return true;

}

Page 57: Knock, knock, who is there? Doze

So what is affected by Doze my app?

Page 58: Knock, knock, who is there? Doze

What is affected

- Pending network transactions will never be fired...- Han Solo Alarms will be postponed.- No location updates

But...

Page 59: Knock, knock, who is there? Doze

There is still some place for...

Page 60: Knock, knock, who is there? Doze

JobSchedulerGCMNetworkManager

Firebase JobDispatcher

Page 61: Knock, knock, who is there? Doze

What?

Schedule the task to execute it when certain conditions met.

(charging, idle, connected to a network or connected to an unmetered network)

Page 62: Knock, knock, who is there? Doze

What’s the difference?

JobScheduler was introduced in API >= 21 (Lollipop).

GCMNetworkManager - is part of GCM package. When using on devices >= 21, use JobScheduler underneath.

Page 63: Knock, knock, who is there? Doze

build.gradledependencies {

...

compile 'com.google.android.gms:play-services-gcm:9.6.1'

...

}

Page 64: Knock, knock, who is there? Doze

public class StarWarsUtilities

void addRetryTask(LukeDecision decision,Context context){

GcmNetworkManager gcmNetworkManager =

GcmNetworkManager.getInstance(context);

}

Page 65: Knock, knock, who is there? Doze

public class StarWarsUtilities

Task task = new

OneoffTask.Builder().setService(BestTimeService.class)

.setExecutionWindow(0, 30)

.setTag(BestTimeService.LUKE_DECISION)

.setUpdateCurrent(false)

.setRequiredNetwork(Task.NETWORK_STATE_CONNECTED)

.setRequiresCharging(false)

.setExtras(bundle)

.build();

Page 66: Knock, knock, who is there? Doze

public class StarWarsUtilities

void addRetryTask(LukeDecision decision,Context context){

...

gcmNetworkManager.schedule(task);

}

Page 67: Knock, knock, who is there? Doze

AndroidManifest.xml<service

android:name=".BestTimeService" android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE"android:exported="true">

<intent-filter>

<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>

</intent-filter>

</service>

Page 68: Knock, knock, who is there? Doze

BestTimeService.java/**

* Task run by GcmNetworkManager when all the

requirements of the scheduled

* task are met.

*/

public class BestTimeService extends GcmTaskService {

...

}

Page 69: Knock, knock, who is there? Doze

BestTimeService.java@Override public int onRunTask(TaskParams taskParams) {

switch (taskParams.getTag()) {

case LUKE_DECISION:

...

return GcmNetworkManager.RESULT_SUCCESS;

case HAN_SOLO_LOCATION:

...

return GcmNetworkManager.RESULT_RESCHEDULE;

default:

return GcmNetworkManager.RESULT_FAILURE;

}

}

Page 70: Knock, knock, who is there? Doze

BestTimeService.java

public int onRunTask(TaskParams taskParams) {

case LUKE_DECISION:

Bundle extras = taskParams.getExtras();

LukeDecision decision = (LukeDecision)

extras.getSerializable(...);

StarWarsUtils.makeDecision(decision, this);

return GcmNetworkManager.RESULT_SUCCESS;

}

}

Page 71: Knock, knock, who is there? Doze

Han Solo Recurring Location task?

Page 72: Knock, knock, who is there? Doze

Task task = new PeriodicTask.Builder()

.setService(BestTimeService.class)

.setPeriod(SIXTY_SEC)

.setFlex(10)

.setTag(BestTimeService.HAN_SOLO_LOCATION)

.setPersisted(true)

.build();

public class FinalBattleActivity

Page 73: Knock, knock, who is there? Doze

BestTimeService.javapublic int onRunTask(TaskParams taskParams) {

case HAN_SOLO_LOCATION:

.. request location...

return GcmNetworkManager.RESULT_SUCCESS;

}

Page 74: Knock, knock, who is there? Doze

Canceling TaskmGcmNetworkManager.cancelAllTasks(BestTimeService.class);

mGcmNetworkManager.cancelTask(

TAG,

BestTimeService.class

);

Page 75: Knock, knock, who is there? Doze

There is a problem hiding here

Page 76: Knock, knock, who is there? Doze

Not all devices shipped with Play Servicesint resultCode =

GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

if (resultCode == ConnectionResult.SUCCESS) {

mGcmNetworkManager.schedule(task);

} else {

// Deal with this networking task some other way

}

Page 77: Knock, knock, who is there? Doze

When Google Play updated it removes all scheduled periodic tasks

public class BestTimeService extends GcmTaskService {

@Override

public void onInitializeTasks() {

super.onInitializeTasks();

// Reschedule removed tasks here

}

}

Page 78: Knock, knock, who is there? Doze

Can we do better?

Page 79: Knock, knock, who is there? Doze

FCM/GCM with High Priority

{

"to" : "...",

"priority" : "high",

"notification" : {

...

},

"data" : {

...

}

}

Page 80: Knock, knock, who is there? Doze

AndroidManifest.xml

<service

android:name=".RebelsMessagingService">

<intent-filter>

<action

android:name="com.google.firebase.MESSAGING_EVENT"/>

</intent-filter>

</service>

Page 81: Knock, knock, who is there? Doze

public class RebelsMessagingService extends FirebaseMessagingService

@Override public void onMessageReceived(RemoteMessage remoteMessage) { Intent intent = new Intent(HanSoloReceiver.ACTION);

LocalBroadcastManager. getInstance(this). sendBroadcast(intent); }

Page 82: Knock, knock, who is there? Doze

Some dirty tricks. Be aware when using it…

Page 83: Knock, knock, who is there? Doze

public class RebelService extends Service implements Handler.Callback

public boolean handleMessage(Message msg) {

StarWarsUtils.doingNetworkCommunication());

handler.sendEmptyMessageDelayed(

WHAT_MAKE_NETWORK_REQUEST,

DELAY_MILLIS);

return true;

}

Page 84: Knock, knock, who is there? Doze

public class RebelService extends Service implements Handler.Callback

public void onCreate() {

Notification notification =

...

startForeground(101, notification);

}

Page 85: Knock, knock, who is there? Doze

When doze mode is kicked inmPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

mDozeBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { boolean isDeviceIdleMode = mPowerManager.isDeviceIdleMode(); } };

registerReceiver(mDozeBroadcastReceiver, new IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED));}

Page 86: Knock, knock, who is there? Doze
Page 87: Knock, knock, who is there? Doze

Yonatan LevinGoogle Developer Expert

levin.yonatanparahall

Page 88: Knock, knock, who is there? Doze

Examples of daily usage apps

Page 89: Knock, knock, who is there? Doze

File explorer over wifi

Whatsapp

Long Running Upload/Download