Slide 1

Slide 1 text

BUILDING MY OWN DEBUGGING TOOL ON OVERLAY Keishin Yokomaku / DroidKaigi 2017 DAY.02 - Room 2

Slide 2

Slide 2 text

Building my own debugging tool on overlay About me ▸ ԣນܓਅ (Keishin Yokomaku) ▸ Drivemode, Inc. / ΤϯδχΞ ▸ KeithYokoma: GitHub / Twitter / Ωʔλ / Stack Overflow ▸ Books: Android ΞΧσϛΞ / AZ ҟຊ / ͳͳ͍Ζ Android ▸ Fun: ثցମૢ / ࣗసं / ࣸਅ / ےτϨ / / ▸ Today’s Quote: “Happy DroidKaigi!” 2

Slide 3

Slide 3 text

BUILDING MY OWN DEBUGGING TOOL ON OVERLAY

Slide 4

Slide 4 text

Building my own debugging tool on overlay ͍͞͠ΐʹ ▸ ͜ͷτʔΫʹ͸एׯͷࠇຐज़త಺༰ؚ͕·Ε͍ͯ·͢ ▸ Ԡ༻͢Δ৔߹ɺ༻๏༻ྔΛकָ͓ͬͯ͘͠࢖͍͍ͩ͘͞ 4

Slide 5

Slide 5 text

Building my own debugging tool on overlay 5

Slide 6

Slide 6 text

Building my own debugging tool on overlay ͜Ε͸Կʁ ▸ ৗʹखલʹදࣔ͞Εଓ͚Δ View ▸ ։ൃऀΦϓγϣϯ ▸ ͲͷΞϓϦΛ։͍͍ͯͯ΋ݟ͑Δ ▸ ఆظతʹ৘ใ͕ߋ৽͞Εଓ͚Δ 6

Slide 7

Slide 7 text

Building my own debugging tool on overlay ͜Ε͸Կʁ ▸ ৗʹखલʹදࣔ͞Εଓ͚Δ View ▸ ։ൃऀΦϓγϣϯ ▸ ͲͷΞϓϦΛ։͍͍ͯͯ΋ݟ͑Δ ▸ ఆظతʹ৘ใ͕ߋ৽͞Εଓ͚Δ 7 ࣗ෼Ͱ࡞Γ͍ͨ

Slide 8

Slide 8 text

Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 8

Slide 9

Slide 9 text

Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 9

Slide 10

Slide 10 text

Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 10

Slide 11

Slide 11 text

Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 11

Slide 12

Slide 12 text

Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 12

Slide 13

Slide 13 text

Building my own debugging tool on overlay ຊ୊ʹೖΔલʹ ▸ DroidKaigi ΞϓϦʹαϯϓϧ࣮૷Λ૊ΈࠐΈ·ͨ͠ ▸ ϦϙδτϦ: http://bit.ly/2lGA6Aj ▸ ઃఆ -> Developer Menu -> Debug Overlay View ▸ ݴޠઃఆΛมߋͨ͠Γɺը໘ճస͢Δͱ… 13

Slide 14

Slide 14 text

ಛผͳϨΠϠʹ VIEW Λදࣔ͢Δ

Slide 15

Slide 15 text

Building my own debugging tool on overlay ొ৔͢ΔΫϥε ▸ android.view.WindowManager ▸ γεςϜαʔϏε ▸ View Λ௥Ճɾ࡟আɾߋ৽͢ΔϝιουΛ΋ͭ ▸ android.view.WindowManager.LayoutParams ▸ WindowManager Ͱඳը͢Δ View ͷͨΊͷύϥϝʔλ 15

Slide 16

Slide 16 text

Building my own debugging tool on overlay ొ৔͢ΔΫϥε ▸ android.view.WindowManager ▸ γεςϜαʔϏε ▸ View Λ௥Ճɾ࡟আɾߋ৽͢ΔϝιουΛ΋ͭ ▸ android.view.WindowManager.LayoutParams ▸ WindowManager Ͱඳը͢Δ View ͷͨΊͷύϥϝʔλ 16

Slide 17

Slide 17 text

Building my own debugging tool on overlay ొ৔͢ΔΫϥε ▸ android.view.WindowManager ▸ γεςϜαʔϏε ▸ View Λ௥Ճɾ࡟আɾߋ৽͢ΔϝιουΛ΋ͭ ▸ android.view.WindowManager.LayoutParams ▸ WindowManager Ͱඳը͢Δ View ͷͨΊͷύϥϝʔλ 17

Slide 18

Slide 18 text

Building my own debugging tool on overlay WindowManager ͱύʔϛογϣϯ ▸ ಛผͳύʔϛογϣϯ ▸ “ଞͷΞϓϦʹॏͶͯදࣔ” ▸ ▸ android.permission.SYSTEM_ALERT_WINDOW ▸ Πϯετʔϧ࣌ʹࣗಈͰڐՄ͞ΕΔ ▸ ͋ͱͰڐՄΛऔΓԼ͛Δ͜ͱ͕Ͱ͖Δ 18

Slide 19

Slide 19 text

Building my own debugging tool on overlay WindowManager ͱύʔϛογϣϯ ▸ ઃఆը໘Λ։͘ Intent ͷΞΫγϣϯ ▸ android.settings.action.MANAGE_OVERLAY_PERMISSIO N ▸ ڐՄ͕͋Δ͔Ͳ͏͔νΣοΫ͢Δϝιου ▸ Settings.canDrawOverlays(Context) ▸ ύʔϛογϣϯΛऔͬͨΞϓϦͷϓϩηε͕ੜ͖͍ͯΔͱɺ ଞͷΞϓϦͷΠϯετʔϧϘλϯ͕ԡͤͳ͘ͳΔ͜ͱʹ஫ҙ 19

Slide 20

Slide 20 text

Building my own debugging tool on overlay WindowManager ͷϝιου ▸ WindowManager#addView(View, LayoutParams) ▸ View ͷ௥Ճ ▸ WindowManager#removeView(View) ▸ View ͷ࡟আ ▸ WindowManager#updateViewLayout(View, LayoutParams) ▸ View ͷύϥϝʔλߋ৽ 20

Slide 21

Slide 21 text

Building my own debugging tool on overlay WindowManager Ͱ࢖͏ύϥϝʔλ ▸ WindowManager.LayoutParams ▸ ॎɾԣͷαΠζ ▸ ϨΠϠ ▸ ϑϥά ▸ ϐΫηϧϑΥʔϚοτ 21

Slide 22

Slide 22 text

Building my own debugging tool on overlay WindowManager ͷϨΠϠ 22 TYPE_WALLPAPER TYPE_APPLICATION TYPE_PHONE TYPE_SYSTEM_DIALOG TYPE_TOAST TYPE_SYSTEM_ALERT TYPE_INPUT_METHOD TYPE_KEYGUARD_DIALOG TYPE_SYSTEM_OVERLAY TYPE_SYSTEM_ERROR

Slide 23

Slide 23 text

Building my own debugging tool on overlay WindowManager ͷϨΠϠ 23 TYPE_WALLPAPER TYPE_APPLICATION TYPE_PHONE TYPE_SYSTEM_DIALOG TYPE_TOAST TYPE_SYSTEM_ALERT TYPE_INPUT_METHOD TYPE_KEYGUARD_DIALOG TYPE_SYSTEM_OVERLAY TYPE_SYSTEM_ERROR ଟ͗͢Δ

Slide 24

Slide 24 text

Building my own debugging tool on overlay (ଟ෼)Α͘࢖͏WindowManager ͷϨΠϠ 24 TYPE_SYSTEM_DIALOG TYPE_SYSTEM_ALERT TYPE_SYSTEM_OVERLAY TYPE_APPLICATION

Slide 25

Slide 25 text

Building my own debugging tool on overlay (ଟ෼)Α͘࢖͏WindowManager ͷϨΠϠ ▸ TYPE_SYSTEM_OVERLAY ▸ ϩοΫը໘ͷ্ɻλονΠϕϯτΛरͬͯ͸μϝɻ ▸ TYPE_SYSTEM_ALERT ▸ Toast ΑΓ΋্ɻ ▸ TYPE_SYSTEM_DIALOG ▸ ΞϓϦέʔγϣϯΑΓ΋্ɻ 25

Slide 26

Slide 26 text

Building my own debugging tool on overlay WindowManager ͷϑϥά ▸ WindowManager ʹ௥Ճ͢Δ View ͷৼΔ෣͍ΛܾΊΔ ▸ λονΠϕϯτ΍ϑΥʔΧεͷऔಘΛ͢Δ͔Ͳ͏͔ ▸ ྖҬ֎΁ͷඳըͷՄ൱ 26

Slide 27

Slide 27 text

Building my own debugging tool on overlay λονΠϕϯτ΍ϑΥʔΧεͷϑϥά ▸ FLAG_NOT_FOCUSABLE ▸ ϑΥʔΧεΛୣΘͳ͍ ▸ FLAG_NOT_TOUCH_MODAL ΋ࣗಈͰ௥Ճ͞ΕΔ ▸ FLAG_NOT_TOUCH_MODAL ▸ WindowManager ʹ௥Ճͨ͠ View ͷྖҬ֎ͷλονΠϕ ϯτΛഎޙͷΞϓϦʹྲྀ͢ 27

Slide 28

Slide 28 text

Building my own debugging tool on overlay λονΠϕϯτ΍ϑΥʔΧεͷϑϥά ▸ FLAG_NOT_TOUCHABLE ▸ λονΠϕϯτΛ͢΂ͯഎޙͷΞϓϦʹྲྀ͢ 28

Slide 29

Slide 29 text

Building my own debugging tool on overlay ྖҬ֎΁ͷඳըͷՄ൱ΛܾΊΔϑϥά ▸ FLAG_LAYOUT_IN_SCREEN ▸ ը໘ͷαΠζ͕ View ͷେ͖͞ͷݶք஋ʹͳΔ ▸ FLAG_LAYOUT_NO_LIMITS ▸ ը໘αΠζΛ௒͑ͯ View ͷେ͖͞ΛઃఆͰ͖Δ ▸ ࠨ্Λݪ఺ͱͯ͠ɺϚΠφεํ޲ʹ΋ View Λ഑ஔͰ͖Δ 29

Slide 30

Slide 30 text

Building my own debugging tool on overlay ϐΫηϧϑΥʔϚοτ ▸ ඳը͢Δ View ͷϐΫηϧ͕΋ͭΞϧϑΝ஋ ▸ android.graphics.PixelFormat ▸ OPAQUE: ΞϧϑΝ஋ͳ͠ɾෆಁ໌ ▸ TRANSLUCENT: ෳ਺ϏοτͰΞϧϑΝ஋Λදݱ ▸ TRANSPARENT: ࠷௿1ϏοτͰΞϧϑΝ஋Λදݱ 30

Slide 31

Slide 31 text

Building my own debugging tool on overlay View ͷ௥Ճίʔυ public class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 31

Slide 32

Slide 32 text

Building my own debugging tool on overlay View ͷ௥Ճίʔυ public class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 32

Slide 33

Slide 33 text

Building my own debugging tool on overlay View ͷ௥Ճίʔυ public class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 33

Slide 34

Slide 34 text

Building my own debugging tool on overlay View ͷ௥Ճίʔυ public class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 34

Slide 35

Slide 35 text

Building my own debugging tool on overlay View ͷ௥Ճίʔυ public class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 35

Slide 36

Slide 36 text

Building my own debugging tool on overlay View ͷ௥Ճίʔυ public class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onCreate(Bundle icicle) { // …… WindowManager.LayoutParams p = new WM.LP( WRAP_CONTENT, WRAP_CONTENT, TYPE_SYSTEM_DIALOG, FLAG_NOT_FOCUSABLE, PicelFormat.TRANSLUCENT ); mWindowManager.addView(mOverlayView, p); } } 36

Slide 37

Slide 37 text

Building my own debugging tool on overlay View ͷ࡟আίʔυ public class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onDestroy() { // …… mWindowManager.removeView(mOverlayView); } } 37

Slide 38

Slide 38 text

Building my own debugging tool on overlay View ͷ࡟আίʔυ public class MainActivity extends Activity{ private View mOverlayView; private WindowManager mWindowManager; @Override protected void onDestroy() { // …… mWindowManager.removeView(mOverlayView); } } 38

Slide 39

Slide 39 text

Building my own debugging tool on overlay ඳը͢Δ View ͷ؅ཧ ▸ WindowManager ͸ View ͷ௥Ճɾ࡟আɾߋ৽͔͠͠ͳ͍ ▸ ͲͷλΠϛϯάͰ௥Ճɾ࡟আɾߋ৽͢Δ͔͸ࣗ෼Ͱ؅ཧ ▸ WindowManager ʹ findViewById ͷΑ͏ͳ΋ͷ͸ͳ͍ ▸ View ͷΠϯελϯεΛϝϯόʔʹ͓͔࣋ͬͯͳ͍ͱ࡟আ Ͱ͖ͳ͘ͳΔ ▸ View ͷϓϩύςΟΛมߋ͢ΔͨΊʹ΋ඞཁ 39

Slide 40

Slide 40 text

Building my own debugging tool on overlay શͯ͸ View Ͱ͋Δ 40 View http://slides.com/robwormald/everything-is-a-stream#/

Slide 41

Slide 41 text

Building my own debugging tool on overlay ଞͷΞϓϦʹ΋ View ΛॏͶ͍ͨʁ ▸ Activity Ͱ؅ཧ͢Δ৔߹͸ࣗ෼ͷΞϓϦʹ͔͠ॏͳΒͳ͍ ▸ ϥΠϑαΠΫϧΛ௒͑ͨ View ͷ؅ཧΛ͢Δඞཁੑ ▸ View ࣗମ͸ Activity ͱ͸ಠཱ͍ͯ͠Δ ▸ ϥΠϑαΠΫϧΛ௒͑ΒΕΔ View ͷ؅ཧํ๏ʁ ▸ Service 41

Slide 42

Slide 42 text

Building my own debugging tool on overlay ଞͷΞϓϦʹ΋ View ΛॏͶ͍ͨʁ ▸ Activity Ͱ؅ཧ͢Δ৔߹͸ࣗ෼ͷΞϓϦʹ͔͠ॏͳΒͳ͍ ▸ ϥΠϑαΠΫϧΛ௒͑ͨ View ͷ؅ཧΛ͢Δඞཁੑ ▸ View ࣗମ͸ Activity ͱ͸ಠཱ͍ͯ͠Δ ▸ ϥΠϑαΠΫϧΛ௒͑ΒΕΔ View ͷ؅ཧํ๏ʁ ▸ Service 42

Slide 43

Slide 43 text

ཪͰ VIEW Λ ߋ৽͠ଓ͚Δ

Slide 44

Slide 44 text

Building my own debugging tool on overlay όοΫάϥϯυͰ View Λදࣔ͠ଓ͚Δʹ͸ ✓ View ͸ Service Ͱ΋ੜ੒Ͱ͖Δ ▸ Service ͸ϝΠϯεϨουͰಈ࡞͢Δ ✓ Activity ͱ͸͜ͱͳΔϥΠϑαΠΫϧͰಈ͔͢ ▸ όοΫάϥ΢ϯυͰৗʹಈ͖ଓ͚ΒΕΔ ➡ Service Ͱ View Λ WindowManager ʹ౉ͤ͹ɺ
 ଞͷΞϓϦʹॏͶͯදࣔ͠ଓ͚ΒΕΔ 44

Slide 45

Slide 45 text

Building my own debugging tool on overlay Service Ͱ View Λඳը͢Δͱ͖ͷઃܭ ▸ ඳը͢Δ View ͷϥΠϑαΠΫϧ؅ཧ ▸ Activity ͕ͯ͘͠ΕΔ͜ͱΛ Service Ͱ࠶࣮૷͢Δ ๏ ϥΠϑαΠΫϧͷ։࢝: Service#onCreate ͳͲ ๏ ϥΠϑαΠΫϧͷऴྃ: Service#onDestroy ๏ ConfigurationChange: BroadcastReceiver 45

Slide 46

Slide 46 text

Building my own debugging tool on overlay Sort of … 46

Slide 47

Slide 47 text

Building my own debugging tool on overlay Sort of … 47

Slide 48

Slide 48 text

Building my own debugging tool on overlay Service Ͱ View Λඳը͢Δͱ͖ͷઃܭ ▸ DroidKaigi ΞϓϦͰͷ࣮૷ ▸ OverlayViewManager ▸ Service ಺Ͱͷ View ͷϥΠϑαΠΫϧΛѲ͍ͬͯΔ ▸ ը໘ભҠ౳͸ߟྀ͍ͯ͠ͳ͍ ▸ ը໘ભҠ౳ΛؚΊͨ View ϕʔεͷը໘ߏஙϑϨʔϜϫʔΫ ▸ e.g. square/flow and square/mortar 48

Slide 49

Slide 49 text

Building my own debugging tool on overlay Service Ͱ View Λඳը͢Δͱ͖ͷઃܭ 49 OverlayViewManager create destroy configChanges WindowManager Service onCreate addView onDestroy removeView configChanges updateViewLayout

Slide 50

Slide 50 text

Building my own debugging tool on overlay OverlayViewManger Ͱ͢Δ͜ͱ ▸ OverlayViewManger#create ▸ WindowManager#addView ΛݺͿ ▸ OverlayViewManger#changeConfiguration ▸ WindowManager#updateViewLayout ΛݺͿ ▸ OverlayViewManger#destroy ▸ WindowManager#removeView ΛݺͿ 50

Slide 51

Slide 51 text

Building my own debugging tool on overlay OverlayViewManager ͷ࣮૷ public class OverlayViewManager { private final Context mContext; // Service private final WindowManager mWindowManager; private final WindowManager.LayoutParams mParams; private View mRootView; public void create() { mRootView = LayoutInflater.from(mContext).inflate( R.layout.view_root_overlay, null, false); mWindowManager.addView(mRootView, mParams) } } 51

Slide 52

Slide 52 text

Building my own debugging tool on overlay OverlayViewManager ͷ࣮૷ public class OverlayViewManager { private final Context mContext; // Service private final WindowManager mWindowManager; private final WindowManager.LayoutParams mParams; private View mRootView; public void destroy() { if (mRootView == null) return; mWindowManager.removeView(mRootView) } } 52

Slide 53

Slide 53 text

Building my own debugging tool on overlay Service Ͱ ConfigurationChange Λѻ͏ ▸ BroadcastReceiver Ͱ ConfigurationChange Λݕ஌ ▸ BroadcastReceiver#onReceive Ͱ View Λ࠶ඳը ▸ ref. WindowManager#updateViewLayout 53

Slide 54

Slide 54 text

Building my own debugging tool on overlay Service Ͱ ConfigurationChange Λѻ͏ public class OverlayViewService extends Service { private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context c, Intent i) { mOverlayViewManager.changeConfiguration(); } } } 54

Slide 55

Slide 55 text

Building my own debugging tool on overlay Service Ͱ ConfigurationChange Λѻ͏ public class OverlayViewService extends Service { private final BroadcastReceiver mReceiver = //… @Override public void onCreate() { //…… IntentFilter filter = new IntentFilter( Intent.ACTION_CONFIGURATION_CHANGE); registerReceiver(mReceiver, filter); } } 55

Slide 56

Slide 56 text

Building my own debugging tool on overlay Service Ͱ ConfigurationChange Λѻ͏ public class OverlayViewService extends Service { private final BroadcastReceiver mReceiver = //… @Override public void onCreate() { //…… IntentFilter filter = new IntentFilter( Intent.ACTION_CONFIGURATION_CHANGE); registerReceiver(mReceiver, filter); } } 56

Slide 57

Slide 57 text

Building my own debugging tool on overlay Service Ͱ ConfigurationChange Λѻ͏ public class OverlayViewService extends Service { private final BroadcastReceiver mReceiver = //… @Override public void onDestroy() { //…… unregisterReceiver(mReceiver); } } 57

Slide 58

Slide 58 text

Building my own debugging tool on overlay LayoutInflater.from(Context) ͷҾ਺ ▸ Context ͔Β LayoutInflater ΛऔΓग़͢ ▸ LayoutInflater ͔Βੜ੒͞ΕΔ Veiw ͸ৗʹಉ͡Ͱ͸ͳ͍ ▸ Context ʹΑͬͯৼΔ෣͍͕͕ͪ͏ ▸ ద੾ͳ Context Λ࢖Θͳ͍ͱݟͨ໨͕มΘͬͯ͠·͏ 58

Slide 59

Slide 59 text

Building my own debugging tool on overlay Activity ͱ Service ͷҧ͍ ▸ Activity ▸ ContextThemeWrapper ͷࢠΫϥε ▸ ςʔϚͰઃఆͨ͠ଐੑ஋Λ͍࣋ͬͯΔ ▸ Service ▸ ContextWrapper ͷࢠΫϥε ▸ ςʔϚ͸ଘࡏ͠ͳ͍ 59

Slide 60

Slide 60 text

Building my own debugging tool on overlay Context ͷϥοϓ ▸ Service Λ ContextThemeWrapper Ͱϥοϓ͠Α͏ ▸ Composite ύλʔϯ ▸ ϥοϓͨ͠ Context Λ࢖͑͹ Service ಺Ͱ΋ςʔϚ͕ద༻ Ͱ͖Δ 60

Slide 61

Slide 61 text

Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷ public class OverlayViewManager { private final Context mContext; // Service private Context mThemedContext; private View mRootView; public void create() { mThemedContext = new OverlayViewContext(mContext); mRootView = LayoutInflater.from(mThemedContext).inflate( R.layout.view_root_overlay, null, false); } } 61

Slide 62

Slide 62 text

Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷ public class OverlayViewManager { private final Context mContext; // Service private Context mThemedContext; private View mRootView; public void create() { mThemedContext = new OverlayViewContext(mContext); mRootView = LayoutInflater.from(mThemedContext).inflate( R.layout.view_root_overlay, null, false); } } 62

Slide 63

Slide 63 text

Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷ /* package */ class OverlayViewContext extends ContextThemeWrapper { public OverlayViewContext(Context base) { super(context, R.style.AppTheme); } } 63

Slide 64

Slide 64 text

Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷ /* package */ class OverlayViewContext extends ContextThemeWrapper { public OverlayViewContext(Context base) { super(context, R.style.AppTheme); } } 64

Slide 65

Slide 65 text

Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷ /* package */ class OverlayViewContext extends ContextThemeWrapper { private LayoutInflater mInflater; @Override public Object getSystemServcie(String name) { // …… } } 65

Slide 66

Slide 66 text

Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷ private LayoutInflater mInflater; @Override public Object getSystemServcie(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from( getBaseContext()).cloneInContext(this); } return mInflater; } return super.getSystemService(name); } 66

Slide 67

Slide 67 text

Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷ private LayoutInflater mInflater; @Override public Object getSystemServcie(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from( getBaseContext()).cloneInContext(this); } return mInflater; } return super.getSystemService(name); } 67

Slide 68

Slide 68 text

Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷ private LayoutInflater mInflater; @Override public Object getSystemServcie(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from( getBaseContext()).cloneInContext(this); } return mInflater; } return super.getSystemService(name); } 68

Slide 69

Slide 69 text

Building my own debugging tool on overlay ࠶ͼ OverlayViewManager ͷ࣮૷ private LayoutInflater mInflater; @Override public Object getSystemServcie(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from( getBaseContext()).cloneInContext(this); } return mInflater; } return super.getSystemService(name); } 69

Slide 70

Slide 70 text

Building my own debugging tool on overlay Service ͷऴྃͱϓϩηεͷऴྃ ▸ Service ͕ಈ͖ଓ͚ΔݶΓϓϩηε͸ੜ͖͍ͯΔ ▸ Service ΛࢭΊΔํ๏ ▸ Context#stopService(Intent) ▸ Service#stopSelf() ▸ ϓϩηεΛࢭΊΔͨΊʹϢʔβ͕औΔߦಈ ▸ λεΫϦετ͔ΒΞϓϦΛফ͢ 70

Slide 71

Slide 71 text

Building my own debugging tool on overlay Service ͷऴྃͱϓϩηεͷऴྃ ▸ λεΫϦετ͔ΒΞϓϦΛऴྃ ▸ Service#onTaskRemoved ▸ ͜͜Ͱ Service ΛࢭΊͳ͍ͱϓϩ ηε͸ੜ͖ଓ͚ͯ͠·͏ ▸ ͳΜ͔ແݶʹੜ͖͍ͯΔΞϓϦ ͕͍Δ => ˑ1 71

Slide 72

Slide 72 text

Building my own debugging tool on overlay Service ͷऴྃͱϓϩηεͷऴྃ ▸ γεςϜ͕ڧ੍తʹϓϩηεΛऴྃ͢Δ৔߹΋͋Δ ▸ ද͍ࣔͯͨ͠ View ͕ٸʹ͍ͳ͘ͳΔ ▸ ϢʔβͷΠϯλϥΫγϣϯ͕͋Δͱ͖͸க໋త… ▸ ग़དྷΔݶΓϓϩηεΛ௕ੜ͖͍ͤͨ͞ 72

Slide 73

Slide 73 text

Building my own debugging tool on overlay Service ͷऴྃͱϓϩηεͷऴྃ ▸ γεςϜ͕ڧ੍తʹϓϩηεΛऴྃ͢Δ৔߹΋͋Δ ▸ ද͍ࣔͯͨ͠ View ͕ٸʹ͍ͳ͘ͳΔ ▸ ϢʔβͷΠϯλϥΫγϣϯ͕͋Δͱ͖͸க໋త… ▸ ग़དྷΔݶΓϓϩηεΛ௕ੜ͖͍ͤͨ͞ 73

Slide 74

Slide 74 text

ϓϩηεΛ ಈ͔͠ଓ͚Δ

Slide 75

Slide 75 text

Building my own debugging tool on overlay Android ʹ͓͚Δϓϩηεͷ༏ઌ౓ ▸ 4 छྨͷ༏ઌ౓ ▸ Foreground Process ▸ Visible Process ▸ Service Process ▸ Cached Process ▸ Լͷ΋ͷ΄Ͳ༏ઌ౓΋௿͍ͷͰɺkill ͷର৅ʹͳΔ 75

Slide 76

Slide 76 text

Building my own debugging tool on overlay Android ʹ͓͚Δϓϩηεͷ༏ઌ౓ ▸ Service ͕ؔ܎͢Δϓϩηεͷ༏ઌ౓ ▸ Visible Process ▸ Service Process ▸ ͳΜͱ͔ Visible Process ʹঢ֨͢Ε͹௕ੜ͖Ͱ͖Δ 76

Slide 77

Slide 77 text

Building my own debugging tool on overlay Android ʹ͓͚Δϓϩηεͷ༏ઌ౓ ▸ Service ͕ؔ܎͢Δϓϩηεͷ༏ઌ౓ ▸ Visible Process ▸ Service Process ▸ ͳΜͱ͔ Visible Process ʹঢ֨͢Ε͹௕ੜ͖Ͱ͖Δ 77

Slide 78

Slide 78 text

Building my own debugging tool on overlay Service Process ▸ Service#startService Ͱৗற͢Δ Service Λ΋ͭϓϩηε ▸ ϝϞϦ͕ṧഭͯ͘͠Δͱ kill ͞ΕΔ ▸ ௕ੜ͖͍ͯ͠Δϓϩηε͸ kill ͷର৅ʹͳΔ ▸ ΋͠ϝϞϦϦʔΫ౳Ͱ Service ͕ਖ਼ৗऴྃͰ͖͍ͯͳ͍ ৔߹ʹϝϞϦΛઐ༗͠ଓ͚ͯ͠·͏ͨΊ 78

Slide 79

Slide 79 text

Building my own debugging tool on overlay Android ʹ͓͚Δϓϩηεͷ༏ઌ౓ ▸ Service ͕ؔ܎͢Δϓϩηεͷ༏ઌ౓ ▸ Visible Process ▸ Service Process ▸ ͳΜͱ͔ Visible Process ʹঢ֨͢Ε͹௕ੜ͖Ͱ͖Δ 79

Slide 80

Slide 80 text

Building my own debugging tool on overlay Visible Process ▸ Ϣʔβʹͱͬͯॏཁͳ৘ใΛද͍ࣔͯ͠Δϓϩηε ▸ e.g. μΠΞϩάͷཪʹ͍Δ Activity Λ͍࣋ͬͯΔ ▸ e.g. Service#startForeground Ͱ௨஌Λग़͍ͯ͠Δ ▸ WindowManager ʹ View Λग़͍ͯͯ͠΋௚઀͸ Visible Process ʹͳΒͳ͍ 80

Slide 81

Slide 81 text

Building my own debugging tool on overlay Visible Process ▸ Ϣʔβʹͱͬͯॏཁͳ৘ใΛද͍ࣔͯ͠Δϓϩηε ▸ e.g. μΠΞϩάͷཪʹ͍Δ Activity Λ͍࣋ͬͯΔ ▸ e.g. Service#startForeground Ͱ௨஌Λग़͍ͯ͠Δ ▸ WindowManager ʹ View Λग़͍ͯͯ͠΋௚઀͸ Visible Process ʹͳΒͳ͍ 81

Slide 82

Slide 82 text

Building my own debugging tool on overlay ϝϞϦʹ༏͍͠ Service ▸ Visible Service Ͱ΋ϝϞϦ͕ݫ͍͠ͱ kill ͞ΕΔ ▸ ϝϞϦʹ༏͍͠ Service Λ࡞Ζ͏ ▸ ϝϞϦϦʔΫ͸͝๏౓ ▸ Service ʹ΋ϥΠϑαΠΫϧ͕͋Δ͜ͱʹ஫ҙ͢Δ ▸ ը໘ભҠΛ࡞Δ৔߹ɺ౎౓ඞཁͳ͍ View Λ remove ͢Δ 82

Slide 83

Slide 83 text

Building my own debugging tool on overlay ॏͶͨ View ʹ৘ใΛදࣔ͢Δ ▸ ߏஙͨ͠ View ʹσʔλΛ౉͍ͨ͠ ▸ σόοά༻ͷ৘ใΛग़͢ ▸ ΞϓϦͷ͍Ζ͍Ζͳ෦෼͔Βσʔ λΛ౉ͤΔઃܭ͕ඞཁ 83

Slide 84

Slide 84 text

Building my own debugging tool on overlay ॏͶͨ View ʹ৘ใΛදࣔ͢Δ ▸ ߏஙͨ͠ View ʹσʔλΛ౉͍ͨ͠ ▸ σόοά༻ͷ৘ใΛग़͢ ▸ ΞϓϦͷ͍Ζ͍Ζͳ෦෼͔Βσʔ λΛ౉ͤΔઃܭ͕ඞཁ 84

Slide 85

Slide 85 text

Activity ͳͲ ͱͭͳ͗͜Ή

Slide 86

Slide 86 text

Building my own debugging tool on overlay Service ʹͭͳ͗͜Ή 3 ͭͷํ๏ ▸ Service ʹσʔλΛΘͨ͢ 3ͭͷํ๏ ▸ startService ͷ Intent ʹσʔλΛͭΊΔ ▸ EventBus Λ׆༻ͯ͠σʔλΛΘͨ͢ ▸ Dagger ౳ͷ DI ͰείʔϓΛ੾Δ & Rx Λ࢖͏ 86

Slide 87

Slide 87 text

Building my own debugging tool on overlay startService ͷ Intent ʹσʔλΛͭΊΔ ▸ Intent#putExtra() Λ׆༻ ▸ Service#onStartCommand() Ͱड͚औΔ ▸ pros & cons ▸ Android ϑϨʔϜϫʔΫͷ࢓૊ΈͰ׬݁͢Δ ▸ σʔλܕʹ Parcelable ͷ࣮૷͕ඞཁ ▸ View Λ؅ཧ͢Δந৅ϨΠϠʹ۩ମతͳॲཧ͕ೖΓࠐΉ 87

Slide 88

Slide 88 text

Building my own debugging tool on overlay startService ͷ Intent ʹσʔλΛͭΊΔ public class DebugOverlayService extends Service { public static final String EXTRA_DATA = // …… private OverlayViewManager mManager; @Override public int onStartCommand(Intent i, int flags, int startId) { // …… Data data = i.getParcelableExtra(EXTRA_DATA); mManager.onReceiveData(data); } } 88

Slide 89

Slide 89 text

Building my own debugging tool on overlay startService ͷ Intent ʹσʔλΛͭΊΔ public class DebugOverlayService extends Service { public static final String EXTRA_DATA = // …… private OverlayViewManager mManager; @Override public int onStartCommand(Intent i, int flags, int startId) { // …… Data data = i.getParcelableExtra(EXTRA_DATA); mManager.onReceiveData(data); } } 89

Slide 90

Slide 90 text

Building my own debugging tool on overlay startService ͷ Intent ʹσʔλΛͭΊΔ public class DebugOverlayService extends Service { public static final String EXTRA_DATA = // …… private OverlayViewManager mManager; @Override public int onStartCommand(Intent i, int flags, int startId) { // …… Data data = i.getParcelableExtra(EXTRA_DATA); mManager.onReceiveData(data); } } 90

Slide 91

Slide 91 text

Building my own debugging tool on overlay EventBus Λ׆༻ͯ͠σʔλΛΘͨ͢ ▸ greenrobot/EventBus, square/otto, reactivex/RxJava ͳͲ ▸ γϯϓϧͳ publisher/subscriber ύλʔϯ ▸ pros & cons ▸ ࢖͍ํΛ֮͑Ε͹؆୯ʹద༻Ͱ͖Δ ▸ Parcelable ͷ࣮૷͕͍Βͳ͍ ▸ ϥΠϒϥϦʹΑͬͯ͸ Deprecated ʹͳ͍ͬͯΔ 91

Slide 92

Slide 92 text

Building my own debugging tool on overlay EventBus Λ׆༻ͯ͠σʔλΛΘͨ͢ public class DebugOverlayView extends RelativeLayout { private EventBus; @Subscribe public void onDataReceived(Data data) { // draw something from data } } 92

Slide 93

Slide 93 text

Building my own debugging tool on overlay EventBus Λ׆༻ͯ͠σʔλΛΘͨ͢ public class DebugOverlayView extends RelativeLayout { private EventBus; @Subscribe public void onDataReceived(Data data) { // draw something from data } } 93

Slide 94

Slide 94 text

Building my own debugging tool on overlay Dagger ౳ͷ DI ͰείʔϓΛ੾Δ & Rx Λ࢖͏ ▸ είʔϓͷ੾Γํ ▸ Application ͷϥΠϑαΠΫϧʹ߹ΘͤΔείʔϓ ▸ Activity ͷϥΠϑαΠΫϧʹ߹ΘͤΔείʔϓ ▸ Service ͷϥΠϑαΠΫϧʹ߹ΘͤΔείʔϓ ▸ DroidKaigi ΞϓϦ ▸ Application ͷείʔϓʹ͍Δ΋ͷ͕ϧʔςΟϯάΛ୲౰ 94

Slide 95

Slide 95 text

ςΩετ Dagger ౳ͷ DI ͰείʔϓΛ੾Δ & Rx Λ࢖͏ 95 ApplicationScope LogEmitter ActivityScope ServiceScope listen send

Slide 96

Slide 96 text

Building my own debugging tool on overlay Dagger ౳ͷ DI ͰείʔϓΛ੾Δ & Rx Λ࢖͏ ▸ pros & cons ▸ ΦϒδΣΫτͷϥΠϑαΠΫϧ͕໌֬ʹͳΔ ▸ EventBus ʹྨࣅͷύλʔϯ͕ Rx Ͱ׬݁͢Δ ▸ ࣗ෼Ͱ EventBus ͷ࢓૊ΈΛ࡞Δඞཁ͕͋Δ 96

Slide 97

Slide 97 text

·ͱΊ

Slide 98

Slide 98 text

Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 98

Slide 99

Slide 99 text

Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 99

Slide 100

Slide 100 text

Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 100

Slide 101

Slide 101 text

Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 101

Slide 102

Slide 102 text

Building my own debugging tool on overlay Ͳ͏࣮ݱ͢Δͷ͔ ▸ ΍Δ͜ͱ ▸ ಛผͳϨΠϠʹ View Λදࣔ͢Δ ▸ ཪͰ View Λߋ৽͠ଓ͚Δ ▸ ߟྀ͢΂͖͜ͱ ▸ ϓϩηεΛಈ͔͠ଓ͚Δ ▸ Activity ͳͲͱͭͳ͗͜Ή 102

Slide 103

Slide 103 text

Building my own debugging tool on overlay ͍͞͝ʹ ▸ ͜ͷτʔΫʹ͸एׯͷࠇຐज़త಺༰ؚ͕·Ε͍ͯ·͢ ▸ Ԡ༻͢Δ৔߹ɺ༻๏༻ྔΛकָ͓ͬͯ͘͠࢖͍͍ͩ͘͞ 103

Slide 104

Slide 104 text

BUILDING MY OWN DEBUGGING TOOL ON OVERLAY Keishin Yokomaku / DroidKaigi 2017 Day 2 - Room 2

Slide 105

Slide 105 text

Building my own debugging tool on overlay Appendix ▸ ࢀߟࢿྉ ▸ WindowManager - Android Developers ▸ WindowManager.LayoutParams - Android Developers ▸ Whoa, Views can do that?
 WindowManager ideas and tricks! - @eric_cochran ▸ DroidKaigi/conference-app-2017 - GitHub 105

Slide 106

Slide 106 text

Drivemode We are hiring! 106

Slide 107

Slide 107 text

Drivemode What we do 107