67
solid foundations Paul Blundell Xavi Rigau

Android Things - Solid Foundations

Embed Size (px)

Citation preview

Page 1: Android Things - Solid Foundations

solid foundationsPaul BlundellXavi Rigau

Page 2: Android Things - Solid Foundations
Page 3: Android Things - Solid Foundations

CamerasGatewaysHVAC ControlSmart Meters

Point of SaleInventory ControlInteractive AdsVending Machines

Security SystemsSmart DoorbellsRoutersEnergy Monitors

Asset TrackingFleet ManagementDriver AssistPredictive Service

Ideal for powerful, intelligent devices on the edge that need to be secure.

Page 4: Android Things - Solid Foundations

IoT Developer Console

Automatic Security Updates

Signed Images Verified Boot

Page 5: Android Things - Solid Foundations

SoMArchitecture

Google Managed BSP

Page 6: Android Things - Solid Foundations
Page 7: Android Things - Solid Foundations
Page 8: Android Things - Solid Foundations

Displays are Optional

Consider Alternate UI

Page 9: Android Things - Solid Foundations

Supported protocols

Page 10: Android Things - Solid Foundations

Peripheral I/O

Communicate your Android Things device with external hardware components (usually called peripherals)

Various protocols can be used (depends on hardware)

General-Purpose Input/Output

GPIOPulse Width Modulation

PWM

Inter-Integrated Circuit

I2C

Universal Asynchronous

Receiver-Transmitter

UART

Serial Peripheral Interface

SPI

Page 11: Android Things - Solid Foundations

Peripheral I/O

Communicate your Android Things device with external hardware components (usually called peripherals)

Various protocols can be used (depends on hardware)

General-Purpose Input/Output

GPIOPulse Width Modulation

PWM

Inter-Integrated Circuit

I2C

Universal Asynchronous

Receiver-Transmitter

UART

Serial Peripheral Interface

SPI

Native Peripheral Input/Output

NPIO

Page 12: Android Things - Solid Foundations

General-Purpose Input/Output

GPIO

Page 13: Android Things - Solid Foundations
Page 14: Android Things - Solid Foundations

Pulse Width ModulationPWM

Xavi Rigau
TODO: These protocol diagrams, can they be replaced with anything better?
Page 15: Android Things - Solid Foundations
Page 16: Android Things - Solid Foundations

Serial Peripheral Interface

SPI

Page 17: Android Things - Solid Foundations
Page 18: Android Things - Solid Foundations

Inter-Integrated Circuit

I2C

Page 19: Android Things - Solid Foundations
Page 20: Android Things - Solid Foundations

Universal Asynchronous

Receiver-Transmitter

UART

Page 21: Android Things - Solid Foundations
Page 22: Android Things - Solid Foundations

Code example: use SPI for an LED strip

Page 23: Android Things - Solid Foundations

public class MainActivity extends Activity {

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }

}

Page 24: Android Things - Solid Foundations

public class MainActivity extends Activity {

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

PeripheralManagerService service = new PeripheralManagerService(); }

}

Page 25: Android Things - Solid Foundations

public class MainActivity extends Activity {

private static final String SPI_PORT = "SPI1"; private SpiDevice device;

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

PeripheralManagerService service = new PeripheralManagerService();

try { device = service.openSpiDevice(SPI_PORT); } catch (IOException e) { throw new IllegalStateException(SPI_PORT + " bus cannot be opened.", e); } }

}

Page 26: Android Things - Solid Foundations

public class MainActivity extends Activity { ... @Override protected void onDestroy() { super.onDestroy(); try { device.close(); } catch (IOException e) { Log.e("TUT", SPI_PORT + " bus cannot be closed, you may experience errors on next launch.", e); } }

}

Page 27: Android Things - Solid Foundations

public class MainActivity extends Activity { ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

...

try { device.setMode(SpiDevice.MODE0); device.setFrequency(1_000_000); device.setBitsPerWord(8); } catch (IOException e) { throw new IllegalStateException(SPI_PORT + " bus cannot be configured.", e); } }

}

Page 28: Android Things - Solid Foundations

public class MainActivity extends Activity { ... private Handler ledToggleHandler;

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

...

ledToggleHandler = new Handler(Looper.getMainLooper()); }

}

Page 29: Android Things - Solid Foundations

public class MainActivity extends Activity { ... private Handler ledToggleHandler;

@Override protected void onStart() { super.onStart(); ledToggleHandler.post(toggleLed); }

@Override protected void onStop() { ledToggleHandler.removeCallbacks(toggleLed); super.onStop(); }

}

Page 30: Android Things - Solid Foundations

public class MainActivity extends Activity { ... private int colourValue; ... private final Runnable toggleLed = new Runnable() { @Override public void run() { try { colourValue = (colourValue == 0 ? 123 : 0); device.write(new byte[]{colourValue, colourValue, colourValue}, 3); } catch (IOException e) { throw new IllegalStateException(LED_PIN + " cannot be read/written.", e); } ledToggleHandler.postDelayed(this, TimeUnit.SECONDS.toMillis(1)); } };

}

Page 31: Android Things - Solid Foundations

Drivers

Page 32: Android Things - Solid Foundations

Driver Libraries Input Drivers

User Drivers

Page 33: Android Things - Solid Foundations

Read or write

from/to a peripheral

Reusable components

Abstract protocol details

Driver Libraries

Page 34: Android Things - Solid Foundations

Ws2801 ledstrip = Ws2801.create("SPI1", Ws2801.Mode.RGB);

ledstrip.write(new int[]{Color.rgb(123, 123, 123)});

Page 35: Android Things - Solid Foundations

Input Drivers

Framework redirects events to

theAndroid

event queue

Register an input driver

Use Services instead of Activities

Page 36: Android Things - Solid Foundations

BarActivityFooService

Page 37: Android Things - Solid Foundations

InputDriver inputDriver = InputDriver.builder(InputDevice.SOURCE_CLASS_BUTTON)

.setName("HelloInputDriver")

.setVersion(1)

.setKeys(new int[]{

KeyEvent.KEYCODE_T, KeyEvent.KEYCODE_H, KeyEvent.KEYCODE_I,

KeyEvent.KEYCODE_N, KeyEvent.KEYCODE_G, KeyEvent.KEYCODE_S

}).build();

UserDriverManager driverManager = UserDriverManager.getManager();

driverManager.registerInputDriver(inputDriver);

KeyEvent[] events = new KeyEvent[]{new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_T)};

inputDriver.emit(events);

Page 38: Android Things - Solid Foundations

Peripherals naming convention

Page 39: Android Things - Solid Foundations

Active peripherals

Passive peripherals

Page 40: Android Things - Solid Foundations

Output peripherals

Input peripherals

Page 41: Android Things - Solid Foundations

Input peripherals / Sensors

“A sensor detects or measures a physical property and responds to it.”

Page 42: Android Things - Solid Foundations

Output peripherals / Actuators

“An actuator is responsible for moving or controlling

a mechanism or system, or presenting data to the outside world.”

Page 43: Android Things - Solid Foundations

/*** HC-SR501*/class PirMotionSensor implements MotionSensor { …

/*** PS-1240*/class PiezoSoundActuator implements SoundActuator { ...

Page 44: Android Things - Solid Foundations

Clarity when searching classes

Clarity when reading code

Page 45: Android Things - Solid Foundations

Better team

discussions

Page 46: Android Things - Solid Foundations

Package structure convention

Page 47: Android Things - Solid Foundations

Grouping by

type

- activities- MainActivity- BasketActivity- CheckoutActivity

- services- LoginService- MoneyService

- utils- LoginUtils- HttpUtils

- peripherals- BarcodeScanningSensor- PriceInputSensor- HelpAlertSensor- FingerprintSensor- PriceDisplayActuator- MoneyDrawActuator

- models- Money- Username- Basket- Receipt- Barcode- Price

Page 48: Android Things - Solid Foundations

Grouping by

protocol

- activities- MainActivity- BasketActivity- CheckoutActivity

- services- LoginService- MoneyService

- utils- LoginUtils- HttpUtils

- gpio- BarcodeScanningSensor- PriceInputSensor- HelpAlertSensor

- i2c- FingerprintSensor

- pwm- PriceDisplayActuator- MoneyDrawActuator

- models- Money- Username- Basket- Receipt- Barcode- Price

Page 49: Android Things - Solid Foundations

Increased package

tackle index

Tidy, everything in its place and a place

for everything

Don’t always

remember the protocol

Context switching between packages

Page 50: Android Things - Solid Foundations

Grouping by domain

concepts

- login- MainActivity- LoginUtils- FingerprintSensor- LoginService- Username

- shopping- basket

- BasketActivity- PriceInputSensor- Basket

- checkout- CheckoutActivity- MoneyService- BarcodeScanningSensor- HelpAlertSensor- MoneyDrawActuator- Barcode

- receipt- PriceDisplayActuator- Receipt

- Money- Price- HttpUtils

Page 51: Android Things - Solid Foundations

Needs to be taught (DDD)

Easier to remember where to

look

All code in the same

place

Less chance of

conflicting changes

Page 52: Android Things - Solid Foundations

Peripherals MVP convention

Page 53: Android Things - Solid Foundations

Model

business logic

Presenter

co-ordination

View

user interface

Page 54: Android Things - Solid Foundations

Sensor

“A sensor detects or measures a physical property and responds to

it.”Model

business logic

Page 55: Android Things - Solid Foundations

Actuator

“An actuator is responsible for moving or controlling a mechanism or system,

or presenting data to the outside world.”

View

user interface

Page 56: Android Things - Solid Foundations

Faster debugging

and problem analysis

Clean code, more

maintainable

A clear separation of

concerns

Faster development

through agreed

standards

Clarity in discussions around class responsibiliti

es

Page 57: Android Things - Solid Foundations

Driver testing

Page 58: Android Things - Solid Foundations

Mock framework

classesTest driver behaviour

Extract collaborator

classes

Page 59: Android Things - Solid Foundations

Test driver behaviour

public class LightStripActuatorTest { @Mock Ws2801 driver;

private LightStripActuator actuator;

@Test

public void driverGoesRedWhenError() throws Exception { actuator.showError();

verify(driver).write({Color.RED});

}

}

Page 60: Android Things - Solid Foundations

Rely on mockspublic class Ws2801Test { @Mock SpiDevice device;

private Ws2801 driver; @Test

public void configures1MHzClockFrequencyWhenCreated() throws Exception {

driver = new Ws2801(device, Direction.NORMAL); verify(device).setFrequency(1_000_000);

}

@Test

public void writesToSpiDeviceWhenWriting() throws Exception { int[] anyColors = {Color.RED, Color.DKGRAY, Color.GREEN, Color.WHITE, Color.YELLOW};

driver.write(anyColors);

verify(device).write(any(byte[].class), anyInt()); }

}

Page 61: Android Things - Solid Foundations

Test collaborators easilypublic class ColorUnpackerTest { @Test public void orderedBytesWhenModeIsRBG() { Ws2801.Mode mode = Ws2801.Mode.RBG;

byte[] result = ColorUnpacker.getOrderedRgbBytes(mode, R, G, B);

assertBytesOrder(result, R, B, G); }

@Test public void orderedBytesWhenModeIsBGR() { Ws2801.Mode mode = Ws2801.Mode.BGR;

byte[] result = ColorUnpacker.getOrderedRgbBytes(mode, R, G, B);

assertBytesOrder(result, B, G, R); }}

Page 62: Android Things - Solid Foundations

Tips & Tricks

Page 63: Android Things - Solid Foundations

Always match .openSomething()

with .close()

Set a static IP addressor

use Android.local

Page 64: Android Things - Solid Foundations

On app crash need to redeploy

or adb shell am start

Only 1 app active at a time https://goo.gl/kLtvM7

Page 65: Android Things - Solid Foundations

Each board has different pin/bus address names

Threading, 3 choices

Page 66: Android Things - Solid Foundations

Thanks!Paul Blundell

Xavi Rigau@blundell_apps@xrigau

Page 67: Android Things - Solid Foundations

Questions?user drivers PWM

UARTGPIO

I2C

SPIinput

output

sensorsactuators

MVP

DDDPaul Blundell

Xavi Rigau@blundell_apps@xrigau