droidcon 2013 automotive quality dunca_czol_garmin
TRANSCRIPT
Automotive quality for mobile products
Stefan Dunca, Ernest Czol
GARMIN, 06.03.2013
Outline
o NAVIGON Mobile Navigator
o Hybrid Android Application (Native & Java)
o Development Tools & Helpers
o Challenges
o Performance for low end devices
o Developing aids for such complex project
o Flexibility & scalability
o Android platform segmentation
Application coverage
Variaty of features
Support for
xxhdpi
Amazon shop
Glympse and
Foursquare
integration
Urban
Guidance
Hybrid approach: Java GUI & C++ core
Core Components (C++)
Router Name
Browser
Advisor Map
Drawer
Traffic
TMC …
JNI
GPS
Accelerometer
Tilt
Connected
Services
Mobile Navigator Starting Point
• Initially designed for
automotive
• Simple interfaces for
fast development
• Reduce client side
development effort
• Knowledge
sharing/reusing
between platforms
• Brought automotive
quality to mobile
Content Data
Core Library
Core API
Custom HMI
OS
Reality View
Tunnels &
Bridges
Performance gain by using native approach
• Complex algorithms
• Complex routing
support
• Hardware accelerated
drawing
• TTS House
number info
Sound data
POI
• Huge content size • Data compression and
optimization
• Efficiently pre-compiled
data format
Country info
3D Data
Terrain elevation
Street lines
Cross platform core
C++
Core release distribution
• Cmake
• Compiler independent
• Same build scripts
• Just different compiler paths
• Jenkins as build server
• Excellent platform independent build server system
• Support for OS independent nodes:
• Linux
• Windows
Native Core Integration
• JNI mapping
• Existing native API
• Core API hooks
• C++ classes to Objects
• Allows us to implement RPC protocol
Core Components (C++)
Router Name
Browser
Advisor Map
Drawer
Traffic
TMC …
JNI
RPC over Core API
• Remote calls to Core code via a custom RPC
over TCP/IP.
• Light binary protocol
• Application is in control
• Act as separation layer between C++ core and
Android native Java implementation
• Can record for issue replays
• Replay using desktop dev-tool
Java HMI – single process architecture
Java Proxy
Implementation
Core Server
Core Library
Core Server
Stream IO
JNI
API (Java)
Java HMI
API
Java Proxy
translates HMI
function calls into a
data stream which
is passed to a
single JNI function.
Core Server Library
decodes HMI function
calls.
Similar architecture also valid
with C# and COM on other
platforms
• C++ remote implementation of interfaces that acts as a proxy to the actual implementation
Core Library multi process architecture
Core Proxy Library
Server Application
Core Library &
actual
implementation
Core Server
Stream IO
Core Proxy
Stream IO TCP/IP
HMI
API
API
API
Core Proxy interacts between HMI and
Core to separate the HMI process from
main process.
Proxy encodes
HMI function calls.
Core Server decodes
HMI function calls.
Java HMI – multi process architecture
Java Proxy
(Package)
Native Core Library
Core Library
Core Server
Stream IO
JNI
Java HMI
Java Server
Application TCP/IP
Actual API
implementation
API (Java)
Java Proxy
translates HMI
function calls into a
data stream which
is passed to
JavaServer
Application via
TCP/IP.
Java Server
Application passes the
data stream to JNI.
Similar architecture also valid with C#
and COM on other platforms
Logging mode
Log Player
Application
Core Native
Library
Core Server
Stream IO
Log Player
Core API
File IO
Playback of HMI calls
binary log-file.
Application with
Core logging
enabled
Core Native
Library
Core Server
Stream IO
Core proxy
Core API
File IO
Recording of HMI calls
to binary log-file
considering relative
time-stamps.
HMI
API
3D City Models & Landmarks
Open Gl ES
• Replaced software rendering
• Better user experience
• Advantages:
• Increase drawing performance
• Already tested on other platforms
• Immersion into the city landscape
• Disadvantages:
• Opengl ES 2 for better texture filtering
• Small issues encountered on the way
Open GL integration challenges
• GlEs1.0 have limitations
• GlEs2.0 is available only from 2.2
• NativeActivity only from 2.3
• Native drawing thread
• Sync needed between Java side and native side
• Device specific issues
• Some have Open GL emulation
• Some have bad support
Software vs OpenGL
Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
Android Challenges
• Reduce APK size
• Requested by device manufacturers and operators
• Solutions:
• Download image resource set from content server
• Using LruCache for faster image loading
• (introduced in API 12, but added to Android Support library)
// Get max available VM memory
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
Sample code taken from http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
// Get max available VM memory
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/5th of the available memory for this memory cache.
final int cacheSize = maxMemory / 5;
Sample code taken from http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
// Get max available VM memory
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/5th of the available memory for this memory cache.
final int cacheSize = maxMemory / 5;
LruCache<String, Bitmap> mMemoryCache =
new LruCache<String,Bitmap>(cacheSize);
Sample code taken from http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
// Get max available VM memory
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/5th of the available memory for this memory cache.
final int cacheSize = maxMemory / 5;
LruCache<String, Bitmap> mMemoryCache =
new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount() / 1024;
}
}; Sample code taken from http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
Thank you!
Q?