├── .gitignore ├── .idea ├── assetWizardSettings.xml ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── dictionaries │ └── jensck.xml ├── encodings.xml ├── jarRepositories.xml ├── kotlinc.xml ├── misc.xml ├── modules.xml ├── navEditor.xml ├── render.experimental.xml ├── runConfigurations.xml └── vcs.xml ├── .travis.yml ├── CHANGELOG.md ├── FOR_MAINTAINERS.md ├── LICENSE ├── README.md ├── RELEASING.md ├── app ├── .gitignore ├── CHANGELOG.md ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── particle │ │ └── android │ │ └── sdk │ │ ├── ApplicationTest.java │ │ └── ReleaseBuildAppInitializer.kt │ ├── debug │ ├── java │ │ └── io │ │ │ └── particle │ │ │ └── android │ │ │ └── sdk │ │ │ └── ReleaseBuildAppInitializer.kt │ └── res │ │ └── values │ │ └── config.xml │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ ├── io │ │ │ └── particle │ │ │ │ └── android │ │ │ │ └── sdk │ │ │ │ ├── tinker │ │ │ │ ├── BgColorLinearLayout.java │ │ │ │ ├── DeviceUiState.kt │ │ │ │ ├── Models.kt │ │ │ │ ├── Pin.kt │ │ │ │ ├── PinLoader.kt │ │ │ │ ├── ReversedProgressBar.java │ │ │ │ ├── ReversedSeekBar.java │ │ │ │ ├── TinkerApplication.kt │ │ │ │ ├── TinkerFragment.kt │ │ │ │ ├── TinkerPrefs.kt │ │ │ │ └── pinreader │ │ │ │ │ └── PinInfoTool.kt │ │ │ │ ├── ui │ │ │ │ ├── EventsFragment.kt │ │ │ │ ├── FlashAppHelper.kt │ │ │ │ ├── FunctionsAndVariablesFragment.kt │ │ │ │ ├── InspectorActivity.kt │ │ │ │ ├── InspectorPager.kt │ │ │ │ ├── IntroActivity.java │ │ │ │ ├── SplashActivity.java │ │ │ │ ├── UnclaimHelper.java │ │ │ │ └── devicelist │ │ │ │ │ ├── DeviceFilterFragment.kt │ │ │ │ │ ├── DeviceFilterViewModel.kt │ │ │ │ │ ├── DeviceListActivity.kt │ │ │ │ │ ├── DeviceListFragment.kt │ │ │ │ │ ├── DeviceListTransformer.kt │ │ │ │ │ ├── DeviceTypeFilterButton.kt │ │ │ │ │ └── TextWatchers.kt │ │ │ │ └── utils │ │ │ │ ├── AnimationUtil.java │ │ │ │ ├── GDPR.kt │ │ │ │ ├── Prefs.java │ │ │ │ ├── Resources.kt │ │ │ │ ├── Snackbars.kt │ │ │ │ └── logging │ │ │ │ └── FileLogging.kt │ │ └── pl │ │ │ └── brightinventions │ │ │ └── slf4android │ │ │ ├── LogSharing.kt │ │ │ └── LogTask.kt │ └── res │ │ ├── animator │ │ ├── pin_background_end.xml │ │ ├── pin_background_go_dark.xml │ │ └── pin_background_start.xml │ │ ├── drawable-xhdpi │ │ └── scan_data_matrix_android.png │ │ ├── drawable-xxhdpi │ │ ├── ic_flashlight_off_white_24dp.png │ │ ├── ic_flashlight_white_24dp.png │ │ ├── ic_trianglify_background.png │ │ └── ic_triangy_toolbar_background.png │ │ ├── drawable │ │ ├── bg_adaptive_icon.xml │ │ ├── bg_app_bar_gradient.xml │ │ ├── bg_device_filter_active.xml │ │ ├── bg_tinker_device_shadow.xml │ │ ├── device_filter_button_background_selected.xml │ │ ├── device_filter_button_background_unselected.xml │ │ ├── device_flashing_dot.xml │ │ ├── fab_label_background.xml │ │ ├── ic_bluetooth_black_24dp.xml │ │ ├── ic_bluetooth_connected_black_24dp.xml │ │ ├── ic_clear_text_black_24dp.xml │ │ ├── ic_collapse.xml │ │ ├── ic_content_copy.xml │ │ ├── ic_delete.xml │ │ ├── ic_expand.xml │ │ ├── ic_f.xml │ │ ├── ic_filter.xml │ │ ├── ic_filter_list_gray_24dp.xml │ │ ├── ic_green_check.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_mode_edit_white_24dp.xml │ │ ├── ic_overflow.xml │ │ ├── ic_pause.xml │ │ ├── ic_play.xml │ │ ├── ic_publish.xml │ │ ├── ic_search.xml │ │ ├── ic_search_gray_24dp.xml │ │ ├── ic_settings_black_24dp.xml │ │ ├── ic_sub.xml │ │ ├── ic_v.xml │ │ ├── offline_dot.xml │ │ ├── online_dot.xml │ │ ├── p_ic_arrow_back_cyan_24dp.xml │ │ ├── progress_emerald.xml │ │ ├── progress_sunflower.xml │ │ ├── tinker_core_shadow_temp.png │ │ ├── tinker_logo_temp.png │ │ ├── tinker_pin.xml │ │ ├── tinker_pin_alizarin.xml │ │ ├── tinker_pin_cyan.xml │ │ ├── tinker_pin_emerald.xml │ │ ├── tinker_pin_muted.xml │ │ ├── tinker_pin_read_high.xml │ │ ├── tinker_pin_sunflower.xml │ │ ├── tinker_pin_write_high.xml │ │ └── white_circle.xml │ │ ├── layout │ │ ├── activity_device_list.xml │ │ ├── activity_inspector.xml │ │ ├── activity_intro.xml │ │ ├── activity_splash.xml │ │ ├── data_header_list.xml │ │ ├── device_list_footer.xml │ │ ├── fragment_data.xml │ │ ├── fragment_device_list2.xml │ │ ├── fragment_events.xml │ │ ├── fragment_filter_fragment.xml │ │ ├── fragment_info.xml │ │ ├── fragment_tinker.xml │ │ ├── publish_event.xml │ │ ├── row_device_list.xml │ │ ├── row_events_list.xml │ │ ├── row_function_list.xml │ │ ├── row_variable_list.xml │ │ ├── tinker_analog_read_left.xml │ │ ├── tinker_analog_read_right.xml │ │ ├── tinker_analog_write_left.xml │ │ ├── tinker_analog_write_right.xml │ │ ├── tinker_digital_read.xml │ │ ├── tinker_digital_write.xml │ │ ├── tinker_instructions.xml │ │ ├── tinker_select.xml │ │ └── view_device_type_filter_button.xml │ │ ├── menu │ │ ├── context_device_row.xml │ │ ├── device_list.xml │ │ ├── inspector.xml │ │ └── tinker.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── raw │ │ ├── b5som_tinker_1_4_5_b5som_2.bin │ │ ├── electron_setup_inject_iccid_js_template.js │ │ ├── electron_setup_variable_injection_js_template.js │ │ ├── tinker_firmware_080_rc27_argon.bin │ │ ├── tinker_firmware_080_rc27_boron.bin │ │ ├── tinker_firmware_080_rc27_xenon.bin │ │ ├── tinker_firmware_electron.bin │ │ ├── tinker_firmware_photon.bin │ │ └── tinker_pin_data.json │ │ ├── values-h700dp │ │ └── dimens_tinker.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── config.xml │ │ ├── customization.xml │ │ ├── dimens.xml │ │ ├── dimens_tinker.xml │ │ ├── fab_values.xml │ │ ├── ids.xml │ │ ├── shared_palette.xml │ │ ├── strings.xml │ │ ├── styles.xml │ │ ├── styles_tinker.xml │ │ ├── themes.xml │ │ ├── tinker_strings.xml │ │ └── uris.xml │ ├── release │ └── java │ │ └── io │ │ └── particle │ │ └── android │ │ └── sdk │ │ └── ReleaseBuildAppInitializer.kt │ └── test │ └── java │ └── io │ └── particle │ └── mesh │ ├── bluetooth │ └── PacketMTUSplitterTest.kt │ └── setup │ ├── FramingTest.kt │ ├── MessagesTest.kt │ ├── WiFiStrengthTest.kt │ └── ui │ └── BarcodeDataTest.kt ├── bintray_upload_v1.gradle ├── build.gradle ├── cloudsdk ├── .gitignore ├── CHANGELOG ├── README.md ├── build.gradle ├── consumer-proguard-rules.pro ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ ├── io │ │ │ └── particle │ │ │ │ └── android │ │ │ │ └── sdk │ │ │ │ ├── cloud │ │ │ │ ├── ApiDefs.kt │ │ │ │ ├── ApiFactory.java │ │ │ │ ├── BroadcastContract.java │ │ │ │ ├── DeviceState.kt │ │ │ │ ├── EventsDelegate.kt │ │ │ │ ├── FunctionArgs.java │ │ │ │ ├── ParticleAccessToken.java │ │ │ │ ├── ParticleCloud.kt │ │ │ │ ├── ParticleCloudSDK.java │ │ │ │ ├── ParticleDevice.kt │ │ │ │ ├── ParticleEvent.kt │ │ │ │ ├── ParticleEventHandler.java │ │ │ │ ├── ParticleEventVisibility.java │ │ │ │ ├── ParticleNetwork.kt │ │ │ │ ├── ParticleUser.java │ │ │ │ ├── Pricing.kt │ │ │ │ ├── Responses.kt │ │ │ │ ├── SDKGlobals.kt │ │ │ │ ├── SDKProvider.java │ │ │ │ ├── SimpleParticleEventHandler.java │ │ │ │ ├── exceptions │ │ │ │ │ ├── PartialDeviceListResultException.java │ │ │ │ │ ├── ParticleCloudException.java │ │ │ │ │ └── ParticleLoginException.java │ │ │ │ └── models │ │ │ │ │ ├── AccountInfo.java │ │ │ │ │ ├── DeviceIdentifiers.kt │ │ │ │ │ ├── DeviceStateChange.java │ │ │ │ │ ├── MeshNetworkChange.kt │ │ │ │ │ ├── MobileSecretResponse.kt │ │ │ │ │ ├── ModifyMeshNetworkAction.java │ │ │ │ │ ├── ParticleNetworkData.kt │ │ │ │ │ ├── ParticleSim.kt │ │ │ │ │ ├── ParticleSimStatus.kt │ │ │ │ │ └── SignUpInfo.java │ │ │ │ ├── persistance │ │ │ │ ├── AppDataStorage.kt │ │ │ │ └── SensitiveDataStorage.kt │ │ │ │ └── utils │ │ │ │ ├── Async.java │ │ │ │ ├── Broadcaster.kt │ │ │ │ ├── CoreNameGenerator.java │ │ │ │ ├── EZ.java │ │ │ │ ├── Enums.kt │ │ │ │ ├── Funcy.java │ │ │ │ ├── LangUtils.kt │ │ │ │ ├── Parcelables.java │ │ │ │ ├── ParticleInternalStringUtils.kt │ │ │ │ ├── Permissions.kt │ │ │ │ ├── Preconditions.java │ │ │ │ ├── Py.java │ │ │ │ ├── TLog.java │ │ │ │ └── Toaster.kt │ │ └── org │ │ │ └── kaazing │ │ │ ├── gateway │ │ │ ├── bridge │ │ │ │ └── ValidateOrigin.java │ │ │ └── client │ │ │ │ ├── impl │ │ │ │ ├── Channel.java │ │ │ │ ├── CommandMessage.java │ │ │ │ ├── DecoderInput.java │ │ │ │ ├── DecoderListener.java │ │ │ │ ├── EncoderOutput.java │ │ │ │ ├── Handler.java │ │ │ │ ├── WebSocketChannel.java │ │ │ │ ├── WebSocketHandler.java │ │ │ │ ├── WebSocketHandlerAdapter.java │ │ │ │ ├── WebSocketHandlerFactory.java │ │ │ │ ├── WebSocketHandlerListener.java │ │ │ │ ├── auth │ │ │ │ │ └── AuthenticationUtil.java │ │ │ │ ├── bridge │ │ │ │ │ ├── BridgeUtil.java │ │ │ │ │ ├── ClassLoaderFactory.java │ │ │ │ │ ├── HttpRequestBridgeHandler.java │ │ │ │ │ ├── Proxy.java │ │ │ │ │ ├── ProxyListener.java │ │ │ │ │ ├── WebSocketNativeBridgeHandler.java │ │ │ │ │ └── XoaEvent.java │ │ │ │ ├── http │ │ │ │ │ ├── HttpRequest.java │ │ │ │ │ ├── HttpRequestAuthenticationHandler.java │ │ │ │ │ ├── HttpRequestDelegateHandler.java │ │ │ │ │ ├── HttpRequestEvent.java │ │ │ │ │ ├── HttpRequestFactory.java │ │ │ │ │ ├── HttpRequestHandler.java │ │ │ │ │ ├── HttpRequestHandlerAdapter.java │ │ │ │ │ ├── HttpRequestHandlerFactory.java │ │ │ │ │ ├── HttpRequestListener.java │ │ │ │ │ ├── HttpRequestLoggingHandler.java │ │ │ │ │ ├── HttpRequestRedirectHandler.java │ │ │ │ │ ├── HttpRequestTransportHandler.java │ │ │ │ │ ├── HttpRequestUtil.java │ │ │ │ │ └── HttpResponse.java │ │ │ │ ├── util │ │ │ │ │ ├── WSCompositeURI.java │ │ │ │ │ ├── WSURI.java │ │ │ │ │ └── WebSocketUtil.java │ │ │ │ ├── ws │ │ │ │ │ ├── CloseCommandMessage.java │ │ │ │ │ ├── ReadyState.java │ │ │ │ │ ├── WebSocketCompositeChannel.java │ │ │ │ │ ├── WebSocketCompositeHandler.java │ │ │ │ │ ├── WebSocketHandshakeObject.java │ │ │ │ │ ├── WebSocketLoggingHandler.java │ │ │ │ │ ├── WebSocketReAuthenticateHandler.java │ │ │ │ │ ├── WebSocketSelectedChannel.java │ │ │ │ │ ├── WebSocketSelectedHandler.java │ │ │ │ │ ├── WebSocketSelectedHandlerImpl.java │ │ │ │ │ └── WebSocketTransportHandler.java │ │ │ │ ├── wseb │ │ │ │ │ ├── CreateChannel.java │ │ │ │ │ ├── CreateHandler.java │ │ │ │ │ ├── CreateHandlerFactory.java │ │ │ │ │ ├── CreateHandlerImpl.java │ │ │ │ │ ├── CreateHandlerListener.java │ │ │ │ │ ├── DownstreamChannel.java │ │ │ │ │ ├── DownstreamHandler.java │ │ │ │ │ ├── DownstreamHandlerFactory.java │ │ │ │ │ ├── DownstreamHandlerImpl.java │ │ │ │ │ ├── DownstreamHandlerListener.java │ │ │ │ │ ├── UpstreamChannel.java │ │ │ │ │ ├── UpstreamHandler.java │ │ │ │ │ ├── UpstreamHandlerFactory.java │ │ │ │ │ ├── UpstreamHandlerImpl.java │ │ │ │ │ ├── UpstreamHandlerListener.java │ │ │ │ │ ├── WebSocketEmulatedChannel.java │ │ │ │ │ ├── WebSocketEmulatedDecoder.java │ │ │ │ │ ├── WebSocketEmulatedDecoderImpl.java │ │ │ │ │ ├── WebSocketEmulatedDecoderListener.java │ │ │ │ │ ├── WebSocketEmulatedEncoder.java │ │ │ │ │ ├── WebSocketEmulatedEncoderImpl.java │ │ │ │ │ └── WebSocketEmulatedHandler.java │ │ │ │ └── wsn │ │ │ │ │ ├── WebSocketNativeAuthenticationHandler.java │ │ │ │ │ ├── WebSocketNativeBalancingHandler.java │ │ │ │ │ ├── WebSocketNativeChannel.java │ │ │ │ │ ├── WebSocketNativeCodec.java │ │ │ │ │ ├── WebSocketNativeDelegateHandler.java │ │ │ │ │ ├── WebSocketNativeEncoder.java │ │ │ │ │ ├── WebSocketNativeEncoderImpl.java │ │ │ │ │ ├── WebSocketNativeHandler.java │ │ │ │ │ └── WebSocketNativeHandshakeHandler.java │ │ │ │ ├── transport │ │ │ │ ├── AuthenticateEvent.java │ │ │ │ ├── BridgeDelegate.java │ │ │ │ ├── CloseEvent.java │ │ │ │ ├── ErrorEvent.java │ │ │ │ ├── Event.java │ │ │ │ ├── IoBufferUtil.java │ │ │ │ ├── LoadEvent.java │ │ │ │ ├── MessageEvent.java │ │ │ │ ├── OpenEvent.java │ │ │ │ ├── ProgressEvent.java │ │ │ │ ├── ReadyStateChangedEvent.java │ │ │ │ ├── RedirectEvent.java │ │ │ │ ├── http │ │ │ │ │ ├── HttpRequestDelegate.java │ │ │ │ │ ├── HttpRequestDelegateFactory.java │ │ │ │ │ ├── HttpRequestDelegateImpl.java │ │ │ │ │ ├── HttpRequestDelegateListener.java │ │ │ │ │ └── HttpRequestUtil.java │ │ │ │ └── ws │ │ │ │ │ ├── Base64Util.java │ │ │ │ │ ├── BridgeSocket.java │ │ │ │ │ ├── BridgeSocketFactory.java │ │ │ │ │ ├── BridgeSocketImpl.java │ │ │ │ │ ├── FrameProcessor.java │ │ │ │ │ ├── FrameProcessorListener.java │ │ │ │ │ ├── WebSocketDelegate.java │ │ │ │ │ ├── WebSocketDelegateFactory.java │ │ │ │ │ ├── WebSocketDelegateImpl.java │ │ │ │ │ ├── WebSocketDelegateListener.java │ │ │ │ │ ├── WsFrameEncodingSupport.java │ │ │ │ │ └── WsMessage.java │ │ │ │ └── util │ │ │ │ ├── Base64Util.java │ │ │ │ ├── GenericURI.java │ │ │ │ ├── HexUtil.java │ │ │ │ ├── HttpURI.java │ │ │ │ ├── StringUtils.java │ │ │ │ ├── URIUtils.java │ │ │ │ ├── WrappedByteBuffer.java │ │ │ │ └── auth │ │ │ │ └── LoginHandlerProvider.java │ │ │ └── net │ │ │ ├── URLFactory.java │ │ │ ├── URLStreamHandlerFactorySpi.java │ │ │ ├── auth │ │ │ ├── BasicChallengeHandler.java │ │ │ ├── ChallengeHandler.java │ │ │ ├── ChallengeRequest.java │ │ │ ├── ChallengeResponse.java │ │ │ ├── DispatchChallengeHandler.java │ │ │ ├── LoginHandler.java │ │ │ ├── NegotiableChallengeHandler.java │ │ │ └── NegotiateChallengeHandler.java │ │ │ ├── http │ │ │ └── HttpRedirectPolicy.java │ │ │ ├── impl │ │ │ ├── auth │ │ │ │ ├── BasicChallengeResponseFactory.java │ │ │ │ ├── DefaultBasicChallengeHandler.java │ │ │ │ ├── DefaultDispatchChallengeHandler.java │ │ │ │ └── RealmUtils.java │ │ │ └── util │ │ │ │ ├── BlockingQueueImpl.java │ │ │ │ └── ResumableTimer.java │ │ │ ├── sse │ │ │ ├── SseEventReader.java │ │ │ ├── SseEventSource.java │ │ │ ├── SseEventSourceFactory.java │ │ │ ├── SseEventType.java │ │ │ ├── SseException.java │ │ │ └── impl │ │ │ │ ├── AuthenticatedEventSourceFactory.java │ │ │ │ ├── AuthenticatedSseEventSourceImpl.java │ │ │ │ ├── AuthenticatedSseEventStream.java │ │ │ │ ├── DefaultEventSourceFactory.java │ │ │ │ ├── SseEventReaderImpl.java │ │ │ │ ├── SseEventSourceImpl.java │ │ │ │ ├── SseEventStream.java │ │ │ │ ├── SseEventStreamListener.java │ │ │ │ ├── SsePayload.java │ │ │ │ ├── SseURLConnection.java │ │ │ │ ├── SseURLConnectionImpl.java │ │ │ │ ├── legacy │ │ │ │ ├── EventSource.java │ │ │ │ ├── EventSourceAdapter.java │ │ │ │ ├── EventSourceEvent.java │ │ │ │ ├── EventSourceImpl.java │ │ │ │ └── EventSourceListener.java │ │ │ │ └── url │ │ │ │ ├── SseURLStreamHandlerFactorySpiImpl.java │ │ │ │ └── SseURLStreamHandlerImpl.java │ │ │ └── ws │ │ │ ├── WebSocket.java │ │ │ ├── WebSocketException.java │ │ │ ├── WebSocketExtension.java │ │ │ ├── WebSocketFactory.java │ │ │ ├── WebSocketMessageReader.java │ │ │ ├── WebSocketMessageType.java │ │ │ ├── WebSocketMessageWriter.java │ │ │ ├── WsURLConnection.java │ │ │ └── impl │ │ │ ├── DefaultWebSocketFactory.java │ │ │ ├── WebSocketImpl.java │ │ │ ├── WsExtensionParameterValuesSpiImpl.java │ │ │ ├── WsURLConnectionImpl.java │ │ │ ├── io │ │ │ ├── WsInputStreamImpl.java │ │ │ ├── WsMessagePullParser.java │ │ │ ├── WsMessageReaderAdapter.java │ │ │ ├── WsMessageReaderImpl.java │ │ │ ├── WsMessageWriterImpl.java │ │ │ ├── WsOutputStreamImpl.java │ │ │ ├── WsReaderImpl.java │ │ │ └── WsWriterImpl.java │ │ │ ├── spi │ │ │ ├── WebSocketExtensionFactorySpi.java │ │ │ ├── WebSocketExtensionHandlerSpi.java │ │ │ ├── WebSocketExtensionParameterValuesSpi.java │ │ │ └── WebSocketExtensionSpi.java │ │ │ └── url │ │ │ ├── WsURLStreamHandlerFactorySpiImpl.java │ │ │ ├── WsURLStreamHandlerImpl.java │ │ │ ├── WssURLStreamHandlerFactorySpiImpl.java │ │ │ └── WssURLStreamHandlerImpl.java │ ├── res │ │ └── values │ │ │ ├── config.xml │ │ │ └── oauth_client_creds.xml │ └── resources │ │ └── META-INF │ │ └── services │ │ ├── org.kaazing.net.URLStreamHandlerFactorySpi │ │ ├── org.kaazing.net.auth.BasicChallengeHandler │ │ ├── org.kaazing.net.auth.DispatchChallengeHandler │ │ ├── org.kaazing.net.sse.SseEventSourceFactory │ │ └── org.kaazing.net.ws.WebSocketFactory │ └── test │ └── java │ └── io │ └── particle │ └── android │ └── sdk │ ├── SingleWorkingUnitTest.kt │ ├── cloud │ ├── ParticleCloudTest.kt │ └── TestData.kt │ └── utils │ ├── CoreNameGeneratorTest.kt │ ├── LangUtilsTest.kt │ └── PyTest.kt ├── commonui ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── particle │ │ └── commonui │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── io │ │ │ └── particle │ │ │ └── commonui │ │ │ ├── DeviceDecorations.kt │ │ │ ├── DeviceInfoBottomSheetController.kt │ │ │ ├── DeviceNotesDelegate.kt │ │ │ ├── Devices.kt │ │ │ ├── RenameHelper.kt │ │ │ └── Views.kt │ └── res │ │ ├── anim │ │ └── fade_in_out.xml │ │ ├── drawable-xhdpi │ │ ├── inspector_border.xml │ │ ├── product_image_core.png │ │ └── product_image_electron.png │ │ ├── drawable-xxhdpi │ │ ├── product_image_argon.png │ │ ├── product_image_boron.png │ │ ├── product_image_photon.png │ │ └── product_image_xenon.png │ │ ├── drawable │ │ ├── bg_colored_circled_device_letter.xml │ │ ├── device_status_dot_flashing.xml │ │ ├── device_status_dot_offline.xml │ │ ├── device_status_dot_online_non_tinker.xml │ │ ├── device_status_dot_online_tinker.xml │ │ ├── ic_arrow_down_gray_24dp.xml │ │ ├── ic_edit_light_gray_24dp.xml │ │ ├── ic_expand_less_black_24dp.xml │ │ ├── p_mesh_progress_spinner.xml │ │ ├── p_particle_logo.png │ │ ├── product_image_p1.png │ │ ├── product_image_pi.png │ │ ├── product_image_red_bear_duo.png │ │ └── product_image_unknown.png │ │ ├── layout │ │ └── view_device_info.xml │ │ ├── values-w400dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── io │ └── particle │ └── commonui │ └── ExampleUnitTest.kt ├── devicesetup ├── .gitignore ├── CHANGELOG ├── README.md ├── add_to_app_manifest.xml ├── build.gradle ├── lint.xml ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── particle │ │ └── sdk │ │ └── library │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── fonts │ │ ├── avenirnext_demibold.ttf │ │ ├── avenirnext_italic.ttf │ │ ├── avenirnext_regular.ttf │ │ ├── avenirnext_ultralight.ttf │ │ ├── roboto_light.ttf │ │ ├── roboto_medium.ttf │ │ ├── roboto_regular.ttf │ │ └── roboto_thin_italic.ttf │ ├── java │ └── io │ │ └── particle │ │ └── android │ │ └── sdk │ │ ├── accountsetup │ │ ├── CreateAccountActivity.java │ │ ├── LoginActivity.java │ │ ├── PasswordResetActivity.java │ │ └── TwoFactorActivity.java │ │ ├── devicesetup │ │ ├── ParticleDeviceSetupLibrary.java │ │ ├── SetupCompleteIntentBuilder.java │ │ ├── SetupProcessException.java │ │ ├── SetupResult.java │ │ ├── SimpleReceiver.java │ │ ├── apconnector │ │ │ ├── ApConnector.kt │ │ │ ├── ApConnectorApi21.kt │ │ │ └── ApConnectorApi29.kt │ │ ├── commands │ │ │ ├── Command.java │ │ │ ├── CommandClient.java │ │ │ ├── CommandClientFactory.java │ │ │ ├── CommandClientUtils.java │ │ │ ├── ConfigureApCommand.java │ │ │ ├── ConnectAPCommand.java │ │ │ ├── DeviceIdCommand.java │ │ │ ├── NetworkBindingSocketFactory.java │ │ │ ├── NoArgsCommand.java │ │ │ ├── PublicKeyCommand.java │ │ │ ├── ScanApCommand.java │ │ │ ├── SetCommand.java │ │ │ ├── VersionCommand.java │ │ │ └── data │ │ │ │ └── WifiSecurity.java │ │ ├── loaders │ │ │ ├── ScanApCommandLoader.java │ │ │ └── WifiScanResultLoader.java │ │ ├── model │ │ │ ├── ScanAPCommandResult.java │ │ │ ├── ScanResultNetwork.java │ │ │ └── WifiNetwork.java │ │ ├── setupsteps │ │ │ ├── CheckIfDeviceClaimedStep.java │ │ │ ├── ConfigureAPStep.java │ │ │ ├── ConnectDeviceToNetworkStep.java │ │ │ ├── EnsureSoftApNotVisible.java │ │ │ ├── SetupStep.java │ │ │ ├── SetupStepApReconnector.java │ │ │ ├── SetupStepException.java │ │ │ ├── SetupStepsFactory.java │ │ │ ├── SetupStepsRunnerTask.java │ │ │ ├── StepConfig.java │ │ │ ├── StepProgress.java │ │ │ ├── WaitForCloudConnectivityStep.java │ │ │ └── WaitForDisconnectionFromDeviceStep.java │ │ └── ui │ │ │ ├── ConnectToApFragment.java │ │ │ ├── ConnectingActivity.java │ │ │ ├── ConnectingProcessWorkerTask.java │ │ │ ├── DeviceSetupState.java │ │ │ ├── DiscoverDeviceActivity.java │ │ │ ├── DiscoverProcessWorker.java │ │ │ ├── GetReadyActivity.java │ │ │ ├── ManualNetworkEntryActivity.java │ │ │ ├── PasswordEntryActivity.java │ │ │ ├── PermissionsFragment.java │ │ │ ├── RequiresWifiScansActivity.java │ │ │ ├── SelectNetworkActivity.java │ │ │ ├── SuccessActivity.java │ │ │ └── WifiListFragment.java │ │ ├── di │ │ ├── ActivityInjectorComponent.java │ │ ├── ApModule.java │ │ ├── ApplicationComponent.java │ │ ├── ApplicationModule.java │ │ ├── CloudModule.java │ │ └── PerActivity.java │ │ ├── ui │ │ ├── BaseActivity.java │ │ └── NextActivitySelector.java │ │ └── utils │ │ ├── BetterAsyncTaskLoader.java │ │ ├── Crypto.java │ │ ├── ParticleDeviceSetupInternalStringUtils.java │ │ ├── SEGAnalytics.java │ │ ├── SSID.java │ │ ├── SoftAPConfigRemover.java │ │ ├── WifiFacade.java │ │ ├── WorkerFragment.java │ │ └── ui │ │ ├── Fragments.java │ │ ├── ParticleUi.java │ │ ├── SoftKeyboardVisibilityDetectingLinearLayout.java │ │ ├── Toaster.java │ │ ├── Ui.java │ │ └── WebViewActivity.java │ └── res │ ├── drawable-xhdpi │ └── checkmark.png │ ├── drawable-xxhdpi │ ├── fail.png │ ├── ic_clear_black_24dp.png │ ├── particle_vertical_blue.png │ ├── photon_vector.png │ ├── product_img_photon.png │ ├── spinner.png │ ├── success.png │ ├── the_wifi.png │ └── trianglifybackground.png │ ├── drawable-xxxhdpi │ ├── honeycomb_bg.webp │ ├── lock.png │ ├── particle_horizontal_blue.png │ └── particle_horizontal_head.png │ ├── drawable │ ├── button_text_color_selector.xml │ ├── link_text_selector.xml │ └── progress_spinner.xml │ ├── layout-xlarge │ └── activity_connecting.xml │ ├── layout │ ├── activity_connecting.xml │ ├── activity_create_account.xml │ ├── activity_discover_device.xml │ ├── activity_get_ready.xml │ ├── activity_manual_network_entry.xml │ ├── activity_password_entry.xml │ ├── activity_password_reset.xml │ ├── activity_select_network.xml │ ├── activity_success.xml │ ├── activity_two_factor.xml │ ├── activity_web_view.xml │ ├── brand_image_header.xml │ ├── particle_activity_login.xml │ └── row_wifi_scan_result.xml │ ├── values-sw820dp │ └── dimens.xml │ ├── values-v19 │ └── dimens.xml │ ├── values-v21 │ └── themes.xml │ ├── values-xlarge │ └── dimens_font_size.xml │ └── values │ ├── colors.xml │ ├── customization.xml │ ├── devicesetup_styles.xml │ ├── dimens.xml │ ├── dimens_font_size.xml │ ├── ids.xml │ ├── particle_setup_strings.xml │ ├── strings.xml │ ├── strings_activity_login.xml │ ├── styles.xml │ ├── success_failure_messages.xml │ └── themes.xml ├── ecjpake4j ├── .gitignore ├── CMakeLists.txt ├── README ├── build.gradle ├── build_mbedtls.sh ├── distribution │ ├── arm64-v8a │ │ ├── libmbedcrypto.a │ │ ├── libmbedtls.a │ │ └── libmbedx509.a │ └── armeabi-v7a │ │ ├── libmbedcrypto.a │ │ ├── libmbedtls.a │ │ └── libmbedx509.a ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── particle │ │ └── ecjpake4j │ │ └── JPAKEInstrumentedTest.kt │ └── main │ ├── AndroidManifest.xml │ ├── cpp │ ├── config.h │ ├── ecjpake-jni-wrapper.c │ ├── ecjpake-jni-wrapper.h │ └── mbedtls │ │ ├── aes.h │ │ ├── aesni.h │ │ ├── arc4.h │ │ ├── aria.h │ │ ├── asn1.h │ │ ├── asn1write.h │ │ ├── base64.h │ │ ├── bignum.h │ │ ├── blowfish.h │ │ ├── bn_mul.h │ │ ├── camellia.h │ │ ├── ccm.h │ │ ├── certs.h │ │ ├── check_config.h │ │ ├── cipher.h │ │ ├── cipher_internal.h │ │ ├── cmac.h │ │ ├── compat-1.3.h │ │ ├── config.h │ │ ├── ctr_drbg.h │ │ ├── debug.h │ │ ├── des.h │ │ ├── dhm.h │ │ ├── ecdh.h │ │ ├── ecdsa.h │ │ ├── ecjpake.h │ │ ├── ecp.h │ │ ├── ecp_internal.h │ │ ├── entropy.h │ │ ├── entropy_poll.h │ │ ├── error.h │ │ ├── gcm.h │ │ ├── havege.h │ │ ├── hkdf.h │ │ ├── hmac_drbg.h │ │ ├── mbedtls │ │ ├── config.h │ │ └── platform_time.h │ │ ├── md.h │ │ ├── md2.h │ │ ├── md4.h │ │ ├── md5.h │ │ ├── md_internal.h │ │ ├── memory_buffer_alloc.h │ │ ├── net.h │ │ ├── net_sockets.h │ │ ├── oid.h │ │ ├── padlock.h │ │ ├── pem.h │ │ ├── pk.h │ │ ├── pk_internal.h │ │ ├── pkcs11.h │ │ ├── pkcs12.h │ │ ├── pkcs5.h │ │ ├── platform.h │ │ ├── platform_time.h │ │ ├── platform_util.h │ │ ├── ripemd160.h │ │ ├── rsa.h │ │ ├── rsa_internal.h │ │ ├── sha1.h │ │ ├── sha256.h │ │ ├── sha512.h │ │ ├── ssl.h │ │ ├── ssl_cache.h │ │ ├── ssl_ciphersuites.h │ │ ├── ssl_cookie.h │ │ ├── ssl_internal.h │ │ ├── ssl_ticket.h │ │ ├── threading.h │ │ ├── timing.h │ │ ├── version.h │ │ ├── x509.h │ │ ├── x509_crl.h │ │ ├── x509_crt.h │ │ ├── x509_csr.h │ │ └── xtea.h │ └── java │ └── io │ └── particle │ └── ecjpake4j │ ├── ECJPake.kt │ └── ECJPakeImpl.kt ├── firmwareprotos ├── .gitignore ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ ├── fi │ └── kapsi │ │ └── koti │ │ └── jpa │ │ └── nanopb │ │ └── Nanopb.java │ └── io │ └── particle │ └── firmwareprotos │ └── ctrl │ ├── Common.java │ ├── Config.java │ ├── Extensions.java │ ├── Network.java │ ├── Storage.java │ ├── cellular │ └── Cellular.java │ ├── cloud │ └── Cloud.java │ ├── mesh │ └── Mesh.java │ └── wifi │ └── WifiNew.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── mesh ├── .gitignore ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── particle │ │ └── mesh │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── io │ │ │ └── particle │ │ │ ├── android │ │ │ └── common │ │ │ │ └── Resources.kt │ │ │ └── mesh │ │ │ ├── bluetooth │ │ │ ├── BLELiveDataCallbacks.kt │ │ │ ├── BTCharacteristicWriter.kt │ │ │ ├── BTCoroutines.kt │ │ │ ├── BluetoothAdapterStateLD.kt │ │ │ ├── Extensions.kt │ │ │ ├── GATTStatusCode.kt │ │ │ ├── PacketMTUSplitter.kt │ │ │ ├── connecting │ │ │ │ ├── BluetoothConnectionManager.kt │ │ │ │ ├── BondingState.kt │ │ │ │ ├── CharacteristicSubscriber.kt │ │ │ │ ├── ConnectionState.kt │ │ │ │ ├── GattConnector.kt │ │ │ │ └── ServiceDiscoverer.kt │ │ │ └── scanning │ │ │ │ ├── BLEScannerLD.kt │ │ │ │ └── SimpleScanCallback.kt │ │ │ ├── common │ │ │ ├── ActionDebouncer.kt │ │ │ ├── AsyncWorkSuspender.kt │ │ │ ├── ByteArrays.kt │ │ │ ├── Delegates.kt │ │ │ ├── Functions.kt │ │ │ ├── QATool.kt │ │ │ ├── Result.kt │ │ │ ├── Truthiness.kt │ │ │ └── android │ │ │ │ ├── Extensions.kt │ │ │ │ ├── SimpleAsync.kt │ │ │ │ ├── SimpleLifecycleOwner.kt │ │ │ │ └── livedata │ │ │ │ ├── AbsentLiveData.kt │ │ │ │ ├── BroadcastReceiverLD.kt │ │ │ │ ├── ClearValueOnInactiveLiveData.kt │ │ │ │ ├── LiveDataSuspender.kt │ │ │ │ └── LiveDatas.kt │ │ │ ├── ota │ │ │ ├── FirmwareUpdateManager.kt │ │ │ └── FirmwareUpdater.kt │ │ │ └── setup │ │ │ ├── BarcodeData.kt │ │ │ ├── SerialNumbers.kt │ │ │ ├── WiFiStrength.kt │ │ │ ├── connection │ │ │ ├── Config.kt │ │ │ ├── Constants.kt │ │ │ ├── Framing.kt │ │ │ ├── ProtocolTransceiver.kt │ │ │ ├── ProtocolTransceiverFactory.kt │ │ │ ├── Requests.kt │ │ │ └── security │ │ │ │ ├── JpakeExchangeManager.kt │ │ │ │ ├── Nonces.java │ │ │ │ └── SecurityManager.kt │ │ │ ├── flow │ │ │ ├── Clearable.kt │ │ │ ├── DeviceConnector.kt │ │ │ ├── DialogTool.kt │ │ │ ├── Errors.kt │ │ │ ├── Flow.kt │ │ │ ├── FlowConfig.kt │ │ │ ├── FlowRunnerSystemInterface.kt │ │ │ ├── FlowRunnerUiListener.kt │ │ │ ├── FlowUiDelegate.kt │ │ │ ├── FlowUtils.kt │ │ │ ├── MeshFlowExecutor.kt │ │ │ ├── MeshFlowRunner.kt │ │ │ ├── MeshSetupStep.kt │ │ │ ├── Scopes.kt │ │ │ ├── SimStatusChangeMode.kt │ │ │ ├── WifiNetworksScannerLD.kt │ │ │ ├── context │ │ │ │ ├── BLEContext.kt │ │ │ │ ├── CellularContext.kt │ │ │ │ ├── CloudConnectionContext.kt │ │ │ │ ├── DeviceContext.kt │ │ │ │ ├── MeshContext.kt │ │ │ │ ├── SetupContexts.kt │ │ │ │ ├── SetupDevice.kt │ │ │ │ └── WifiContext.kt │ │ │ ├── meshsetup │ │ │ │ ├── MeshNetworkToJoin.kt │ │ │ │ └── TargetDeviceMeshNetworksScanner.kt │ │ │ └── setupsteps │ │ │ │ ├── StepAwaitSetupStandAloneOrWithNetwork.kt │ │ │ │ ├── StepCheckDeviceGotClaimed.kt │ │ │ │ ├── StepCheckIfTargetDeviceShouldBeClaimed.kt │ │ │ │ ├── StepCheckShouldSwitchToControlPanel.kt │ │ │ │ ├── StepCheckTargetDeviceHasThreadInterface.kt │ │ │ │ ├── StepCollectCommissionerDeviceInfo.kt │ │ │ │ ├── StepCollectMeshNetworkToJoinPassword.kt │ │ │ │ ├── StepCollectMeshNetworkToJoinSelection.kt │ │ │ │ ├── StepCollectSelectedWifiNetworkPassword.kt │ │ │ │ ├── StepCollectUserWifiNetworkSelection.kt │ │ │ │ ├── StepConnectToTargetDevice.kt │ │ │ │ ├── StepControlPanelDetermineFlowAfterPreflow.kt │ │ │ │ ├── StepCreateNewMeshNetworkOnCloud.kt │ │ │ │ ├── StepCreateNewMeshNetworkOnLocalDevice.kt │ │ │ │ ├── StepDeactivateSim.kt │ │ │ │ ├── StepDetermineFlowAfterPreflow.kt │ │ │ │ ├── StepEnsureCardOnFile.kt │ │ │ │ ├── StepEnsureCommissionerConnected.kt │ │ │ │ ├── StepEnsureCommissionerNetworkMatches.kt │ │ │ │ ├── StepEnsureConnectionToCloud.kt │ │ │ │ ├── StepEnsureCorrectEthernetFeatureStatus.kt │ │ │ │ ├── StepEnsureEthernetHasIpAddress.kt │ │ │ │ ├── StepEnsureLatestFirmware.kt │ │ │ │ ├── StepEnsureListeningStoppedForBothDevices.kt │ │ │ │ ├── StepEnsureSelectedWifiNetworkJoined.kt │ │ │ │ ├── StepEnsureSimActivated.kt │ │ │ │ ├── StepEnsureSimActivationStatusUpdated.kt │ │ │ │ ├── StepEnsureTargetDeviceIsNotOnMeshNetwork.kt │ │ │ │ ├── StepFetchCurrentMeshNetwork.kt │ │ │ │ ├── StepFetchDeviceId.kt │ │ │ │ ├── StepFetchFullSimData.kt │ │ │ │ ├── StepFetchIccid.kt │ │ │ │ ├── StepFetchIccidFromCloud.kt │ │ │ │ ├── StepGetAPINetworks.kt │ │ │ │ ├── StepGetEthernetPinStatus.kt │ │ │ │ ├── StepGetNewMeshNetworkName.kt │ │ │ │ ├── StepGetNewMeshNetworkPassword.kt │ │ │ │ ├── StepGetTargetDeviceInfo.kt │ │ │ │ ├── StepInspectCurrentWifiNetwork.kt │ │ │ │ ├── StepJoinSelectedNetwork.kt │ │ │ │ ├── StepLeaveMeshNetwork.kt │ │ │ │ ├── StepPopBackStack.kt │ │ │ │ ├── StepPublishDeviceSetupDoneEvent.kt │ │ │ │ ├── StepReactivateSim.kt │ │ │ │ ├── StepRemoveDeviceFromAnyMeshNetwork.kt │ │ │ │ ├── StepRetrieveWifiNetworks.kt │ │ │ │ ├── StepSetClaimCode.kt │ │ │ │ ├── StepSetDataLimit.kt │ │ │ │ ├── StepSetEthernetPinStatus.kt │ │ │ │ ├── StepSetNewDeviceName.kt │ │ │ │ ├── StepSetSetupDone.kt │ │ │ │ ├── StepShowCellularConnectingToDeviceCloudUi.kt │ │ │ │ ├── StepShowCellularOptionsUi.kt │ │ │ │ ├── StepShowConnectedToCloudSuccessUi.kt │ │ │ │ ├── StepShowConnectingToDeviceCloudUi.kt │ │ │ │ ├── StepShowCreateNetworkFinished.kt │ │ │ │ ├── StepShowCreateNewMeshNetworkUi.kt │ │ │ │ ├── StepShowDeviceWifiNetworks.kt │ │ │ │ ├── StepShowEthernetOptionsUi.kt │ │ │ │ ├── StepShowGetReadyForSetup.kt │ │ │ │ ├── StepShowJoinerSetupFinishedUi.kt │ │ │ │ ├── StepShowJoiningMeshNetworkUi.kt │ │ │ │ ├── StepShowLetsGetBuildingUi.kt │ │ │ │ ├── StepShowMeshInspectNetworkUi.kt │ │ │ │ ├── StepShowPricingImpact.kt │ │ │ │ ├── StepShowSetDataLimitUi.kt │ │ │ │ ├── StepShowShouldConnectToDeviceCloudConfirmation.kt │ │ │ │ ├── StepShowSimDeactivateUi.kt │ │ │ │ ├── StepShowSimReactivateUi.kt │ │ │ │ ├── StepShowSimUnpauseUi.kt │ │ │ │ ├── StepShowSingleTaskCongratsScreen.kt │ │ │ │ ├── StepShowSnackbar.kt │ │ │ │ ├── StepShowTargetPairingSuccessful.kt │ │ │ │ ├── StepShowWifiConnectingToDeviceCloudUi.kt │ │ │ │ ├── StepStartListeningModeForTarget.kt │ │ │ │ ├── StepStopSignal.kt │ │ │ │ ├── StepUnpauseSim.kt │ │ │ │ └── StepUnsetFullSimData.kt │ │ │ ├── ui │ │ │ ├── ProgressHack.kt │ │ │ └── utils │ │ │ │ ├── BLEScanning.kt │ │ │ │ └── Networks.kt │ │ │ └── utils │ │ │ ├── Buffers.kt │ │ │ ├── ByteBuffers.kt │ │ │ ├── ByteMath.java │ │ │ ├── MainThreadUtils.kt │ │ │ └── Toasts.kt │ └── res │ │ └── values │ │ ├── mesh_strings.xml │ │ └── strings_mesh.xml │ └── test │ └── java │ └── io │ └── particle │ └── mesh │ └── ExampleUnitTest.java ├── meshui ├── .gitignore ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── particle │ │ └── mesh │ │ └── ui │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── io │ │ │ └── particle │ │ │ ├── android │ │ │ └── common │ │ │ │ ├── Adapters.kt │ │ │ │ └── Location.kt │ │ │ └── mesh │ │ │ └── ui │ │ │ ├── BaseFlowActivity.kt │ │ │ ├── BaseFlowFragment.kt │ │ │ ├── BaseFlowUiDelegate.kt │ │ │ ├── BaseNavigationToolImpl.kt │ │ │ ├── Views.kt │ │ │ ├── controlpanel │ │ │ ├── BaseControlPanelFragment.kt │ │ │ ├── ControlPanelActivity.kt │ │ │ ├── ControlPanelCellularDataLimitFragment.kt │ │ │ ├── ControlPanelCellularOptionsFragment.kt │ │ │ ├── ControlPanelCongratsFragment.kt │ │ │ ├── ControlPanelEnterWifiNetworkPasswordFragment.kt │ │ │ ├── ControlPanelEthernetOptionsFragment.kt │ │ │ ├── ControlPanelFlowUiDelegate.kt │ │ │ ├── ControlPanelLandingFragment.kt │ │ │ ├── ControlPanelMeshInspectNetworkFragment.kt │ │ │ ├── ControlPanelMeshOptionsFragment.kt │ │ │ ├── ControlPanelNetworkIdFragment.kt │ │ │ ├── ControlPanelScanForWifiNetworksFragment.kt │ │ │ ├── ControlPanelSimStatusChangeFragment.kt │ │ │ ├── ControlPanelUnclaimDeviceFragment.kt │ │ │ ├── ControlPanelWifiInspectNetworkFragment.kt │ │ │ ├── ControlPanelWifiManageNetworksFragment.kt │ │ │ ├── ControlPanelWifiOptionsFragment.kt │ │ │ └── PrepareForPairingFragment.kt │ │ │ ├── setup │ │ │ ├── ArgonConnectingStatusFragment.kt │ │ │ ├── AssistingDevicePairingProgressFragment.kt │ │ │ ├── BLEPairingProgressFragment.kt │ │ │ ├── BoronConnectingStatusFragment.kt │ │ │ ├── ConnectToDeviceCloudIntroFragment.kt │ │ │ ├── CreatingMeshNetworkFragment.kt │ │ │ ├── EnterNetworkPasswordFragment.kt │ │ │ ├── EnterWifiNetworkPasswordFragment.kt │ │ │ ├── EthernetConnectingToDeviceCloudFragment.kt │ │ │ ├── GetReadyForSetupFragment.kt │ │ │ ├── HashtagWinningFragment.kt │ │ │ ├── JoinerSetupFinishedFragment.kt │ │ │ ├── JoiningMeshNetworkProgressFragment.kt │ │ │ ├── LetsGetBuildingFragment.kt │ │ │ ├── ManualCommissioningAddToNetworkFragment.kt │ │ │ ├── MeshSetupActivity.kt │ │ │ ├── NameYourDeviceFragment.kt │ │ │ ├── NewMeshNetworkFinishedFragment.kt │ │ │ ├── NewMeshNetworkNameFragment.kt │ │ │ ├── NewMeshNetworkPasswordFragment.kt │ │ │ ├── PermissionsFragment.kt │ │ │ ├── PricingImpactFragment.kt │ │ │ ├── ScanCodeFragment.kt │ │ │ ├── ScanCommissionerCodeFragment.kt │ │ │ ├── ScanForMeshNetworksFragment.kt │ │ │ ├── ScanForWiFiNetworksFragment.kt │ │ │ ├── ScanIntroBaseFragment.kt │ │ │ ├── ScanSetupTargetCodeIntroFragment.kt │ │ │ ├── SelectDeviceFragment.kt │ │ │ ├── SetupFlowUiDelegate.kt │ │ │ ├── UseStandaloneOrInMeshFragment.kt │ │ │ ├── barcodescanning │ │ │ │ ├── CameraSource.java │ │ │ │ ├── CameraSourcePreview.java │ │ │ │ ├── FrameMetadata.kt │ │ │ │ ├── GraphicOverlay.java │ │ │ │ ├── LivePreviewActivity.kt │ │ │ │ ├── VisionImageProcessor.java │ │ │ │ ├── VisionProcessorBase.java │ │ │ │ └── barcode │ │ │ │ │ ├── BarcodeGraphic.java │ │ │ │ │ └── BarcodeScanningProcessor.kt │ │ │ └── ota │ │ │ │ ├── BleOtaFragment.kt │ │ │ │ └── BleOtaIntroFragment.kt │ │ │ ├── utils │ │ │ ├── Resources.kt │ │ │ ├── UserFeedback.kt │ │ │ └── ViewModels.kt │ │ │ └── views │ │ │ └── OverlayWithHoleView.kt │ └── res │ │ ├── drawable-xxhdpi │ │ ├── sim_activate_header_image.png │ │ ├── sim_deactivate_header_image.png │ │ └── unclaim_device_header_image.png │ │ ├── drawable │ │ ├── background_top_bottom_gray_borders.xml │ │ ├── ic_check_cyan_24dp.xml │ │ ├── ic_check_gray_24dp.xml │ │ ├── ic_chevron_right_gray_24dp.xml │ │ ├── p_bleotaintro_hero_graphic.xml │ │ ├── p_ic_close_cyan_24dp.xml │ │ ├── p_mesh_hintbox_background.xml │ │ ├── p_mesh_ic_camera_24dp.xml │ │ ├── p_mesh_ic_capability_cellular.xml │ │ ├── p_mesh_ic_capability_ethernet.xml │ │ ├── p_mesh_ic_capability_mesh.xml │ │ ├── p_mesh_ic_capability_wifi.xml │ │ ├── p_mesh_ic_lock_black_14dp.xml │ │ ├── p_mesh_ic_lock_black_24dp.xml │ │ ├── p_mesh_ic_wifi_strength_high.png │ │ ├── p_mesh_ic_wifi_strength_low.png │ │ ├── p_mesh_ic_wifi_strength_medium.png │ │ └── p_mesh_rosie.xml │ │ ├── layout │ │ ├── activity_control_panel.xml │ │ ├── activity_main.xml │ │ ├── controlpanel_row_data_limit.xml │ │ ├── fragment_argon_connecting_status.xml │ │ ├── fragment_assisting_device_pairing_progress.xml │ │ ├── fragment_ble_ota.xml │ │ ├── fragment_ble_ota_intro.xml │ │ ├── fragment_ble_pairing_progress.xml │ │ ├── fragment_boron_connecting_status.xml │ │ ├── fragment_connect_to_device_cloud_intro.xml │ │ ├── fragment_control_panel_cellular_data_limit.xml │ │ ├── fragment_control_panel_ethernet_options.xml │ │ ├── fragment_control_panel_landing.xml │ │ ├── fragment_control_panel_network_id.xml │ │ ├── fragment_control_panel_sim_status_change.xml │ │ ├── fragment_control_panel_unclaim_device.xml │ │ ├── fragment_control_panel_wifi_inspect_network.xml │ │ ├── fragment_control_panel_wifi_manage_networks.xml │ │ ├── fragment_control_panel_wifi_options.xml │ │ ├── fragment_controlpanel_cellular_options.xml │ │ ├── fragment_controlpanel_mesh_network_info.xml │ │ ├── fragment_controlpanel_mesh_network_options.xml │ │ ├── fragment_cp_congrats.xml │ │ ├── fragment_cp_enter_wifi_password.xml │ │ ├── fragment_cp_prepare_for_pairing.xml │ │ ├── fragment_cp_scan_for_wifi_networks.xml │ │ ├── fragment_creating_mesh_network.xml │ │ ├── fragment_enter_network_password.xml │ │ ├── fragment_enter_wifi_network_password.xml │ │ ├── fragment_ethernet_connecting_to_device_cloud.xml │ │ ├── fragment_first_demo.xml │ │ ├── fragment_get_ready_for_setup.xml │ │ ├── fragment_hashtag_winning.xml │ │ ├── fragment_joiner_setup_finished.xml │ │ ├── fragment_joining_mesh_network_progress.xml │ │ ├── fragment_lets_get_building.xml │ │ ├── fragment_manual_commissioning_add_to_network.xml │ │ ├── fragment_manual_commissioning_select_device.xml │ │ ├── fragment_name_your_device.xml │ │ ├── fragment_new_mesh_network_finished.xml │ │ ├── fragment_new_mesh_network_name.xml │ │ ├── fragment_new_mesh_network_password.xml │ │ ├── fragment_pricing_impact.xml │ │ ├── fragment_scan_code.xml │ │ ├── fragment_scan_code_intro.xml │ │ ├── fragment_scan_commissioner_code.xml │ │ ├── fragment_scan_for_mesh_networks.xml │ │ ├── fragment_scan_for_wi_fi_networks.xml │ │ ├── fragment_select_device.xml │ │ ├── fragment_use_standalone_or_in_mesh.xml │ │ ├── p_controlpanel_row_wifi_scan.xml │ │ ├── p_mesh_row_wifi_scan.xml │ │ ├── p_scanformeshnetwork_row_select_mesh_network.xml │ │ ├── row_mesh_networks.xml │ │ ├── row_select_comissioner.xml │ │ └── row_select_device.xml │ │ ├── navigation │ │ ├── mesh_setup.xml │ │ └── navgraph_control_panel.xml │ │ ├── raw │ │ ├── commissioner_to_listening_mode.mov │ │ ├── cp_device_in_listening_mode.mov │ │ ├── power_on_argon.mov │ │ ├── power_on_boron_battery.mov │ │ ├── power_on_bsom.mov │ │ ├── power_on_featherwing.mp4 │ │ ├── power_on_som_ethernet.mov │ │ └── power_on_xenon.mov │ │ ├── values-h700dp │ │ └── dimens_mesh.xml │ │ └── values │ │ ├── colors_mesh.xml │ │ ├── dimens_mesh.xml │ │ ├── ids_mesh.xml │ │ ├── strings.xml │ │ └── styles_mesh.xml │ └── test │ └── java │ └── io │ └── particle │ └── mesh │ └── ui │ └── ExampleUnitTest.java ├── particle-mark.png ├── play_store_512px_icon.png ├── pom_generator_v1.gradle ├── sdk_example_app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── io │ │ └── particle │ │ └── cloudsdk │ │ └── example_app │ │ ├── DeviceInfoActivity.java │ │ ├── LoginActivity.java │ │ ├── SplashActivity.java │ │ └── ValueActivity.java │ └── res │ ├── layout │ ├── activity_device_info.xml │ ├── activity_login.xml │ ├── activity_splash.xml │ └── activity_value.xml │ ├── menu │ ├── menu_splash.xml │ └── menu_value.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── settings.gradle ├── setup_exampleapp ├── .gitignore ├── build.gradle ├── lint.xml ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── io │ │ └── particle │ │ └── devicesetup │ │ └── exampleapp │ │ ├── ExampleSetupCompleteIntentBuilder.java │ │ └── MainActivity.java │ └── res │ ├── layout │ └── activity_main.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml └── setup_testapp ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src ├── androidTest └── java │ └── io │ └── particle │ └── devicesetup │ └── testapp │ ├── ApplicationTest.java │ ├── CustomAndroidTestRunner.java │ ├── CustomApplication.java │ ├── EspressoDaggerMockRule.java │ └── accountsetup │ └── SetupFlowTest.java ├── main ├── AndroidManifest.xml ├── java │ └── io │ │ └── particle │ │ └── devicesetup │ │ └── testapp │ │ └── MainActivity.java └── res │ ├── layout │ └── activity_main.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml └── test └── java └── io └── particle └── devicesetup └── testapp └── ExampleUnitTest.java /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/dictionaries/jensck.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | barcodes 5 | bcode 6 | clearables 7 | crashlytics 8 | ctxs 9 | iccid 10 | jpake 11 | unpause 12 | xceiver 13 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/render.experimental.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Intentionally empty! 2 | 3 | See the CHANGELOG.md files in each module's for their respective changelogs. 4 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/jknutson/Library/ADT/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/io/particle/android/sdk/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/io/particle/android/sdk/ReleaseBuildAppInitializer.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk 2 | 3 | import android.app.Application 4 | import io.particle.android.sdk.utils.pass 5 | 6 | 7 | fun onApplicationCreated(app: Application) { 8 | // NO-OP 9 | } 10 | 11 | fun updateUsernameWithCrashlytics(username: String?) { 12 | pass 13 | } 14 | -------------------------------------------------------------------------------- /app/src/debug/java/io/particle/android/sdk/ReleaseBuildAppInitializer.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk 2 | 3 | 4 | import android.app.Application 5 | import io.particle.android.sdk.utils.pass 6 | 7 | 8 | fun onApplicationCreated(app: Application) { 9 | // set debugging properties for Kotlin coroutines here in debug builds 10 | System.setProperty("DEBUG_PROPERTY_NAME", "BANANA") 11 | System.setProperty("kotlinx.coroutines.stacktrace.recovery", "true") 12 | } 13 | 14 | fun updateUsernameWithCrashlytics(username: String?) { 15 | pass 16 | } 17 | -------------------------------------------------------------------------------- /app/src/debug/res/values/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | FULL 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/java/io/particle/android/sdk/tinker/Models.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.tinker 2 | 3 | 4 | enum class PinAction { 5 | DIGITAL_READ, 6 | DIGITAL_WRITE, 7 | ANALOG_READ, 8 | ANALOG_WRITE, 9 | ANALOG_WRITE_DAC, 10 | NONE 11 | } 12 | 13 | 14 | enum class PinType { 15 | A, 16 | D 17 | } 18 | 19 | 20 | enum class DigitalValue constructor(val intValue: Int) { 21 | 22 | HIGH(1), 23 | LOW(0), 24 | NONE(-1); 25 | 26 | companion object { 27 | 28 | @JvmStatic 29 | fun fromInt(value: Int): DigitalValue { 30 | return when (value) { 31 | 1 -> HIGH 32 | 0 -> LOW 33 | else -> NONE 34 | } 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/io/particle/android/sdk/tinker/ReversedProgressBar.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.tinker; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.util.AttributeSet; 6 | import android.widget.ProgressBar; 7 | 8 | 9 | public class ReversedProgressBar extends ProgressBar { 10 | 11 | public ReversedProgressBar(Context context, AttributeSet attrs) { 12 | super(context, attrs); 13 | } 14 | 15 | protected void onDraw(Canvas c) { 16 | float px = this.getWidth() / 2.0f; 17 | float py = this.getHeight() / 2.0f; 18 | 19 | c.scale(-1, 1, px, py); 20 | 21 | super.onDraw(c); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/io/particle/android/sdk/tinker/ReversedSeekBar.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.tinker; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.util.AttributeSet; 6 | import android.view.MotionEvent; 7 | 8 | 9 | public class ReversedSeekBar extends androidx.appcompat.widget.AppCompatSeekBar { 10 | 11 | public ReversedSeekBar(Context context, AttributeSet attrs) { 12 | super(context, attrs); 13 | } 14 | 15 | protected void onDraw(Canvas c) { 16 | float px = this.getWidth() / 2.0f; 17 | float py = this.getHeight() / 2.0f; 18 | 19 | c.scale(-1, 1, px, py); 20 | 21 | super.onDraw(c); 22 | } 23 | 24 | public boolean onTouchEvent(MotionEvent event) { 25 | event.setLocation(this.getWidth() - event.getX(), event.getY()); 26 | return super.onTouchEvent(event); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/io/particle/android/sdk/ui/devicelist/TextWatchers.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.ui.devicelist 2 | 3 | import android.text.Editable 4 | import android.text.TextWatcher 5 | import android.widget.EditText 6 | 7 | 8 | fun afterTextChangedListener(afterTextChange: (Editable?) -> Unit): TextWatcher { 9 | return object : TextWatcher { 10 | 11 | override fun afterTextChanged(editable: Editable?) { 12 | afterTextChange(editable) 13 | } 14 | 15 | override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} 16 | override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/io/particle/android/sdk/utils/Resources.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.utils 2 | 3 | import android.content.Context 4 | import androidx.annotation.RawRes 5 | import okio.buffer 6 | import okio.source 7 | 8 | 9 | fun Context.readRawResourceBytes(@RawRes resId: Int): ByteArray { 10 | val stream = this.resources.openRawResource(resId) 11 | return stream.source().buffer().use { 12 | it.readByteArray() 13 | } 14 | } -------------------------------------------------------------------------------- /app/src/main/res/animator/pin_background_end.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/animator/pin_background_go_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/animator/pin_background_start.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/scan_data_matrix_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/drawable-xhdpi/scan_data_matrix_android.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_flashlight_off_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/drawable-xxhdpi/ic_flashlight_off_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_flashlight_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/drawable-xxhdpi/ic_flashlight_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_trianglify_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/drawable-xxhdpi/ic_trianglify_background.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_triangy_toolbar_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/drawable-xxhdpi/ic_triangy_toolbar_background.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_adaptive_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_app_bar_gradient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_device_filter_active.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_tinker_device_shadow.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/device_filter_button_background_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/device_filter_button_background_unselected.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/device_flashing_dot.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/fab_label_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_bluetooth_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_bluetooth_connected_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_clear_text_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_collapse.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_content_copy.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_expand.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_list_gray_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_green_check.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_mode_edit_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pause.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_play.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_publish.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search_gray_24dp.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_sub.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_v.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/offline_dot.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/online_dot.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/p_ic_arrow_back_cyan_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_emerald.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_sunflower.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tinker_core_shadow_temp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/drawable/tinker_core_shadow_temp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/tinker_logo_temp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/drawable/tinker_logo_temp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/tinker_pin.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tinker_pin_alizarin.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tinker_pin_cyan.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tinker_pin_emerald.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tinker_pin_muted.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tinker_pin_read_high.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tinker_pin_sunflower.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tinker_pin_write_high.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/white_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_device_list.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 14 | 15 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/device_list_footer.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/tinker_digital_read.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/tinker_digital_write.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/menu/device_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/menu/inspector.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/menu/tinker.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-hdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-mdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/raw/b5som_tinker_1_4_5_b5som_2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/raw/b5som_tinker_1_4_5_b5som_2.bin -------------------------------------------------------------------------------- /app/src/main/res/raw/electron_setup_inject_iccid_js_template.js: -------------------------------------------------------------------------------- 1 | var inputElement = document.getElementById('iccid'); 2 | inputElement.value = '%s'; 3 | var e = new Event('change'); 4 | e.target = inputElement; 5 | inputElement.dispatchEvent(e); 6 | -------------------------------------------------------------------------------- /app/src/main/res/raw/electron_setup_variable_injection_js_template.js: -------------------------------------------------------------------------------- 1 | console.log('init web view to allow setting vars on window object'); 2 | window.mobileClient = 'android'; 3 | window.particleUsername = '%s'; 4 | window.particleAccessToken = '%s'; 5 | console.log('init web view to allow setting vars on window object'); 6 | -------------------------------------------------------------------------------- /app/src/main/res/raw/tinker_firmware_080_rc27_argon.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/raw/tinker_firmware_080_rc27_argon.bin -------------------------------------------------------------------------------- /app/src/main/res/raw/tinker_firmware_080_rc27_boron.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/raw/tinker_firmware_080_rc27_boron.bin -------------------------------------------------------------------------------- /app/src/main/res/raw/tinker_firmware_080_rc27_xenon.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/raw/tinker_firmware_080_rc27_xenon.bin -------------------------------------------------------------------------------- /app/src/main/res/raw/tinker_firmware_electron.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/raw/tinker_firmware_electron.bin -------------------------------------------------------------------------------- /app/src/main/res/raw/tinker_firmware_photon.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/app/src/main/res/raw/tinker_firmware_photon.bin -------------------------------------------------------------------------------- /app/src/main/res/values-h700dp/dimens_tinker.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 41dp 4 | 14sp 5 | 8dp 6 | 150dp 7 | 320dp 8 | 12dp 9 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Setup button 5 | https://setup.particle.io 6 | @drawable/ic_trianglify_background 7 | 8 | #FFFFFF 9 | @color/teal 10 | #0C2D4D 11 | @color/teal 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/values/customization.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fonts/avenirnext_regular.ttf 5 | fonts/avenirnext_demibold.ttf 6 | fonts/avenirnext_italic.ttf 7 | fonts/avenirnext_ultralight.ttf 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 205dip 4 | 19sp 5 | 6 | 16dp 7 | 16dp 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens_tinker.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 32dp 4 | 12sp 5 | 4dp 6 | 150dp 7 | 300dp 8 | 4dp 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/fab_values.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #B2000000 4 | #e5e5e5 5 | #808080 6 | #fafafa 7 | #ddd 8 | #e91e63 9 | #ec407a 10 | #805677fc 11 | #80738ffe 12 | 13 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/uris.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://docs.particle.io/photon/tinker/#tinkering-with-tinker 4 | https://docs.particle.io/photon/connect/#connecting-your-device 5 | https://docs.particle.io/photon/ios/#ios-cloud-sdk 6 | https://community.particle.io/ 7 | https://support.particle.io/hc/en-us 8 | -------------------------------------------------------------------------------- /app/src/test/java/io/particle/mesh/bluetooth/PacketMTUSplitterTest.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.bluetooth 2 | 3 | import org.junit.Assert.assertEquals 4 | import org.junit.Test 5 | 6 | 7 | class PacketMTUSplitterTest { 8 | 9 | @Test 10 | fun doTheThing() { 11 | val hexBytes = "word1word2word3word4word5".toByteArray() 12 | val outputTarget = mutableListOf() 13 | val testee = PacketMTUSplitter( { outputTarget.add(it) } , mtuSize = 10) 14 | 15 | testee.splitIntoPackets(hexBytes) 16 | 17 | assertEquals(3, outputTarget.size) 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /app/src/test/java/io/particle/mesh/setup/MessagesTest.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup 2 | 3 | import io.particle.firmwareprotos.ctrl.mesh.Mesh 4 | import io.particle.mesh.setup.connection.asRequest 5 | import org.junit.Assert.assertArrayEquals 6 | import org.junit.Assert.assertEquals 7 | import org.junit.Test 8 | 9 | 10 | class MessagesTest { 11 | 12 | @Test 13 | fun asRequestDoesTheThing() { 14 | val msg = Mesh.AuthRequest.newBuilder() 15 | .setPassword("LOLWUT") 16 | .build() 17 | val expectedPayload = msg.toByteArray() 18 | 19 | val request = msg.asRequest() 20 | 21 | assertEquals(1001.toShort(), request.messageType) 22 | assertArrayEquals(expectedPayload, request.payloadData) 23 | assertEquals(expectedPayload.size, request.payloadData.size) 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /cloudsdk/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /cloudsdk/consumer-proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -dontwarn okio.** 2 | -------------------------------------------------------------------------------- /cloudsdk/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/jensck/Library/android-sdk-linux/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /cloudsdk/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/BroadcastContract.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud; 2 | 3 | 4 | public interface BroadcastContract { 5 | 6 | String BROADCAST_DEVICES_UPDATED = "BROADCAST_DEVICES_UPDATED"; 7 | String BROADCAST_SYSTEM_EVENT = "BROADCAST_SYSTEM_EVENT"; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/FunctionArgs.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | public class FunctionArgs { 6 | 7 | @SerializedName("params") 8 | public final String params; 9 | 10 | public FunctionArgs(String params) { 11 | this.params = params; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/ParticleEvent.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud 2 | 3 | import com.google.gson.annotations.SerializedName 4 | import java.util.* 5 | import javax.annotation.ParametersAreNonnullByDefault 6 | 7 | // Normally it's bad form to use network data models as API data models, but considering that 8 | // for the moment, they'd be a 1:1 mapping, we'll just reuse this data model class. If the 9 | // network API changes, then we can write new classes for the network API models, without 10 | // impacting the public API of the SDK. 11 | @ParametersAreNonnullByDefault 12 | class ParticleEvent( 13 | @SerializedName("coreid") val deviceId: String, 14 | @SerializedName("data") val dataPayload: String?, 15 | @SerializedName("published_at") val publishedAt: Date, 16 | @SerializedName("ttl") val timeToLive: Int? 17 | ) -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/ParticleEventHandler.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud; 2 | 3 | 4 | public interface ParticleEventHandler extends SimpleParticleEventHandler { 5 | 6 | // FIXME: ugh, use a more specific exception here 7 | void onEventError(Exception e); 8 | } 9 | -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/ParticleEventVisibility.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud; 2 | 3 | 4 | import androidx.annotation.IntDef; 5 | 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | 9 | 10 | @IntDef({ParticleEventVisibility.PRIVATE, 11 | ParticleEventVisibility.PUBLIC}) 12 | @Retention(RetentionPolicy.SOURCE) 13 | public @interface ParticleEventVisibility { 14 | int PRIVATE = 1; 15 | int PUBLIC = 2; 16 | } 17 | -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/SimpleParticleEventHandler.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud; 2 | 3 | /** 4 | * Created by Julius. 5 | */ 6 | 7 | public interface SimpleParticleEventHandler { 8 | void onEvent(String eventName, ParticleEvent particleEvent); 9 | } 10 | -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/exceptions/PartialDeviceListResultException.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud.exceptions; 2 | 3 | import java.util.List; 4 | 5 | import io.particle.android.sdk.cloud.ParticleDevice; 6 | import retrofit.RetrofitError; 7 | 8 | public class PartialDeviceListResultException extends Exception { 9 | 10 | public final List devices; 11 | 12 | public PartialDeviceListResultException(List devices, Exception cause) { 13 | super(cause); 14 | this.devices = devices; 15 | } 16 | 17 | public PartialDeviceListResultException(List devices, RetrofitError error) { 18 | super(error); 19 | this.devices = devices; 20 | } 21 | 22 | public PartialDeviceListResultException(List devices) { 23 | super("Undefined error while fetching devices"); 24 | this.devices = devices; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/models/DeviceIdentifiers.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud.models 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | 6 | data class DeviceIdentifiers( 7 | @SerializedName("device_id") 8 | val deviceId: String, 9 | 10 | @SerializedName("iccid") 11 | val iccid: String?, 12 | 13 | @SerializedName("platform_id") 14 | val platformId: Int 15 | ) 16 | -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/models/MeshNetworkChange.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud.models 2 | 3 | data class MeshNetworkChange( 4 | val action: String, 5 | val deviceID: String 6 | ) -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/models/MobileSecretResponse.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud.models 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | 6 | data class MobileSecretResponse( 7 | @SerializedName("mobile_secret") 8 | val fullMobileSecret: String?, 9 | val deviceId: String? 10 | ) -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/models/ModifyMeshNetworkAction.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud.models; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | 6 | public enum ModifyMeshNetworkAction { 7 | @SerializedName("add-device") 8 | ADD_DEVICE, 9 | @SerializedName("remove-device") 10 | REMOVE_DEVICE, 11 | @SerializedName("gateway-enable") 12 | GATEWAY_ENABLE, 13 | @SerializedName("gateway-disable") 14 | GATEWAY_DISABLE 15 | } 16 | -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/cloud/models/ParticleNetworkData.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.cloud.models 2 | 3 | import com.google.gson.annotations.SerializedName 4 | import io.particle.android.sdk.cloud.* 5 | import java.util.* 6 | 7 | 8 | internal data class ParticleNetworkData( 9 | val id: NetworkID, 10 | val name: String, 11 | val type: ParticleNetworkType, 12 | val state: ParticleNetworkState, 13 | @SerializedName("device_count") val deviceCount: Int, 14 | @SerializedName("gateway_count") val gatewayCount: Int, 15 | @SerializedName("last_heard") val lastHeard: Date?, 16 | @SerializedName("pan_id") val panId: PanID?, 17 | @SerializedName("xpan_id") val xpanId: XPanID?, 18 | val channel: Int?, 19 | val notes: String? 20 | ) 21 | -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/utils/Broadcaster.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.utils 2 | 3 | import android.content.Intent 4 | import androidx.localbroadcastmanager.content.LocalBroadcastManager 5 | 6 | 7 | interface Broadcaster { 8 | fun sendBroadcast(intent: Intent) 9 | } 10 | 11 | 12 | class BroadcastImpl(private val localBroadcaster: LocalBroadcastManager) : Broadcaster { 13 | 14 | override fun sendBroadcast(intent: Intent) { 15 | localBroadcaster.sendBroadcast(intent) 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/utils/LangUtils.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.utils 2 | 3 | // A "no-op" value, for use with, e.g.: intentionally non-exhaustive when() statements, 4 | // inspired by Python's "pass" statement 5 | val pass = Unit 6 | -------------------------------------------------------------------------------- /cloudsdk/src/main/java/io/particle/android/sdk/utils/Permissions.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.utils 2 | 3 | import android.content.Context 4 | import android.content.pm.PackageManager 5 | import androidx.core.content.ContextCompat 6 | 7 | 8 | fun Context.appHasPermission(permission: String): Boolean { 9 | val result = ContextCompat.checkSelfPermission(this, permission) 10 | return result == PackageManager.PERMISSION_GRANTED 11 | } 12 | -------------------------------------------------------------------------------- /cloudsdk/src/main/res/values/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://api.particle.io 5 | 6 | 12 | NONE 13 | 14 | 15 | -------------------------------------------------------------------------------- /cloudsdk/src/main/res/values/oauth_client_creds.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | spark-android-app-1234 7 | d34db33f164e458fdb8daffe48b4ffe9d34db33f 8 | 9 | -------------------------------------------------------------------------------- /cloudsdk/src/main/resources/META-INF/services/org.kaazing.net.URLStreamHandlerFactorySpi: -------------------------------------------------------------------------------- 1 | org.kaazing.net.ws.impl.url.WsURLStreamHandlerFactorySpiImpl 2 | org.kaazing.net.ws.impl.url.WssURLStreamHandlerFactorySpiImpl 3 | -------------------------------------------------------------------------------- /cloudsdk/src/main/resources/META-INF/services/org.kaazing.net.auth.BasicChallengeHandler: -------------------------------------------------------------------------------- 1 | org.kaazing.net.impl.auth.DefaultBasicChallengeHandler 2 | -------------------------------------------------------------------------------- /cloudsdk/src/main/resources/META-INF/services/org.kaazing.net.auth.DispatchChallengeHandler: -------------------------------------------------------------------------------- 1 | org.kaazing.net.impl.auth.DefaultDispatchChallengeHandler 2 | -------------------------------------------------------------------------------- /cloudsdk/src/main/resources/META-INF/services/org.kaazing.net.sse.SseEventSourceFactory: -------------------------------------------------------------------------------- 1 | org.kaazing.net.sse.impl.DefaultEventSourceFactory -------------------------------------------------------------------------------- /cloudsdk/src/main/resources/META-INF/services/org.kaazing.net.ws.WebSocketFactory: -------------------------------------------------------------------------------- 1 | org.kaazing.net.ws.impl.DefaultWebSocketFactory -------------------------------------------------------------------------------- /cloudsdk/src/test/java/io/particle/android/sdk/SingleWorkingUnitTest.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk 2 | 3 | import io.particle.android.sdk.utils.UnknownEnumIntValueException 4 | import org.junit.Test 5 | 6 | import org.junit.Assert.* 7 | 8 | /** 9 | * Example local unit test, which will execute on the development machine (host). 10 | * 11 | * See [testing documentation](http://d.android.com/tools/testing). 12 | */ 13 | class ExampleUnitTest { 14 | 15 | @Test 16 | fun messageIsAsExpected() { 17 | val ex = UnknownEnumIntValueException(8) 18 | assertEquals("Unknown enum value for 8", ex.message) 19 | } 20 | 21 | @Test 22 | fun addition_isCorrect() { 23 | assertEquals(4, 2 + 2) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /cloudsdk/src/test/java/io/particle/android/sdk/utils/CoreNameGeneratorTest.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.utils 2 | 3 | import org.junit.Test 4 | import org.junit.Assert.* 5 | 6 | 7 | class CoreNameGeneratorTest { 8 | 9 | @Test 10 | fun nameNotNull() { 11 | val name = CoreNameGenerator.generateUniqueName(setOf()) 12 | assertNotNull(name) 13 | } 14 | 15 | @Test 16 | fun nameContainsUnderscore() { 17 | val name = CoreNameGenerator.generateUniqueName(setOf()) 18 | assertTrue(name.contains("_")) 19 | } 20 | 21 | @Test 22 | fun nameSegmentsNotRepeated() { 23 | val name = CoreNameGenerator.generateUniqueName(setOf()) 24 | val (first ,second) = name.split("_") 25 | assertNotEquals(first, second) 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /cloudsdk/src/test/java/io/particle/android/sdk/utils/LangUtilsTest.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.utils 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | 8 | class LangUtilsTest { 9 | 10 | @Test 11 | fun passDoesNothing() { 12 | // ensure that we actually hit the "pass" line but that it does nothing 13 | var foo = false 14 | pass 15 | foo = true 16 | assertTrue(foo) 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /cloudsdk/src/test/java/io/particle/android/sdk/utils/PyTest.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.utils 2 | 3 | import org.junit.Assert.assertTrue 4 | import org.junit.Test 5 | 6 | 7 | class PyTest { 8 | 9 | @Test 10 | fun emptyListReturnsEmptyList() { 11 | val emptyList = Py.list() 12 | assertTrue(emptyList.isEmpty()) 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /commonui/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /commonui/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/consumer-rules.pro -------------------------------------------------------------------------------- /commonui/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /commonui/src/androidTest/java/io/particle/commonui/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package io.particle.commonui 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("io.particle.commonui.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /commonui/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /commonui/src/main/java/io/particle/commonui/Views.kt: -------------------------------------------------------------------------------- 1 | package io.particle.commonui 2 | 3 | import android.content.Context 4 | import android.util.DisplayMetrics 5 | import kotlin.math.ceil 6 | import kotlin.math.floor 7 | 8 | 9 | fun dpToPx(dpValue: Float, displayMetrics: DisplayMetrics): Int { 10 | return (dpValue * displayMetrics.density).round() 11 | } 12 | 13 | 14 | fun dpToPx(dpValue: Float, context: Context): Int { 15 | return dpToPx(dpValue, context.resources.displayMetrics) 16 | } 17 | 18 | 19 | fun dpToPx(dpValue: Int, context: Context): Int { 20 | return dpToPx(dpValue.toFloat(), context) 21 | } 22 | 23 | 24 | private fun Float.round(): Int { 25 | val rounded = if (this < 0) ceil(this - 0.5f) else floor(this + 0.5f) 26 | return rounded.toInt() 27 | } 28 | -------------------------------------------------------------------------------- /commonui/src/main/res/anim/fade_in_out.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /commonui/src/main/res/drawable-xhdpi/inspector_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /commonui/src/main/res/drawable-xhdpi/product_image_core.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/src/main/res/drawable-xhdpi/product_image_core.png -------------------------------------------------------------------------------- /commonui/src/main/res/drawable-xhdpi/product_image_electron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/src/main/res/drawable-xhdpi/product_image_electron.png -------------------------------------------------------------------------------- /commonui/src/main/res/drawable-xxhdpi/product_image_argon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/src/main/res/drawable-xxhdpi/product_image_argon.png -------------------------------------------------------------------------------- /commonui/src/main/res/drawable-xxhdpi/product_image_boron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/src/main/res/drawable-xxhdpi/product_image_boron.png -------------------------------------------------------------------------------- /commonui/src/main/res/drawable-xxhdpi/product_image_photon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/src/main/res/drawable-xxhdpi/product_image_photon.png -------------------------------------------------------------------------------- /commonui/src/main/res/drawable-xxhdpi/product_image_xenon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/src/main/res/drawable-xxhdpi/product_image_xenon.png -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/bg_colored_circled_device_letter.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/device_status_dot_flashing.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/device_status_dot_offline.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/device_status_dot_online_non_tinker.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/device_status_dot_online_tinker.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/ic_arrow_down_gray_24dp.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/ic_edit_light_gray_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/ic_expand_less_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/p_mesh_progress_spinner.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/p_particle_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/src/main/res/drawable/p_particle_logo.png -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/product_image_p1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/src/main/res/drawable/product_image_p1.png -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/product_image_pi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/src/main/res/drawable/product_image_pi.png -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/product_image_red_bear_duo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/src/main/res/drawable/product_image_red_bear_duo.png -------------------------------------------------------------------------------- /commonui/src/main/res/drawable/product_image_unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/commonui/src/main/res/drawable/product_image_unknown.png -------------------------------------------------------------------------------- /commonui/src/main/res/values-w400dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 270dp 4 | -------------------------------------------------------------------------------- /commonui/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 6 | 18sp 7 | 13sp 8 | 22sp 9 | @dimen/p_setup_text_size_small 10 | 11 | 15sp 12 | 13 | 16dp 14 | 82dp 15 | 220dp 16 | 17 | -------------------------------------------------------------------------------- /commonui/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Core 4 | Electron 5 | Photon 6 | Unknown 7 | Raspberry Pi 8 | Red Bear Duo 9 | P1 10 | 11 | Tap to add some notes for this device. 12 | 13 | 14 | -------------------------------------------------------------------------------- /commonui/src/test/java/io/particle/commonui/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package io.particle.commonui 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /devicesetup/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /devicesetup/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /devicesetup/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/jensck/Android/Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /devicesetup/src/androidTest/java/io/particle/sdk/library/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package io.particle.sdk.library; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /devicesetup/src/main/assets/fonts/avenirnext_demibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/assets/fonts/avenirnext_demibold.ttf -------------------------------------------------------------------------------- /devicesetup/src/main/assets/fonts/avenirnext_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/assets/fonts/avenirnext_italic.ttf -------------------------------------------------------------------------------- /devicesetup/src/main/assets/fonts/avenirnext_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/assets/fonts/avenirnext_regular.ttf -------------------------------------------------------------------------------- /devicesetup/src/main/assets/fonts/avenirnext_ultralight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/assets/fonts/avenirnext_ultralight.ttf -------------------------------------------------------------------------------- /devicesetup/src/main/assets/fonts/roboto_light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/assets/fonts/roboto_light.ttf -------------------------------------------------------------------------------- /devicesetup/src/main/assets/fonts/roboto_medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/assets/fonts/roboto_medium.ttf -------------------------------------------------------------------------------- /devicesetup/src/main/assets/fonts/roboto_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/assets/fonts/roboto_regular.ttf -------------------------------------------------------------------------------- /devicesetup/src/main/assets/fonts/roboto_thin_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/assets/fonts/roboto_thin_italic.ttf -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/devicesetup/SetupCompleteIntentBuilder.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.devicesetup; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import androidx.annotation.Nullable; 6 | 7 | public interface SetupCompleteIntentBuilder { 8 | Intent buildIntent(Context ctx, @Nullable SetupResult result); 9 | } 10 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/devicesetup/SetupProcessException.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.devicesetup; 2 | 3 | 4 | import io.particle.android.sdk.devicesetup.setupsteps.SetupStep; 5 | 6 | public class SetupProcessException extends Exception { 7 | 8 | public final SetupStep failedStep; 9 | 10 | public SetupProcessException(String msg, SetupStep failedStep) { 11 | super(msg); 12 | this.failedStep = failedStep; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/devicesetup/commands/Command.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.devicesetup.commands; 2 | 3 | import com.google.gson.Gson; 4 | 5 | 6 | public abstract class Command { 7 | 8 | public abstract String getCommandName(); 9 | 10 | // override if you want a different implementation 11 | public String argsAsJsonString(Gson gson) { 12 | return gson.toJson(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/devicesetup/commands/CommandClientFactory.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.devicesetup.commands; 2 | 3 | import io.particle.android.sdk.utils.SSID; 4 | import io.particle.android.sdk.utils.WifiFacade; 5 | 6 | import static io.particle.android.sdk.devicesetup.commands.CommandClient.DEFAULT_TIMEOUT_SECONDS; 7 | 8 | public class CommandClientFactory { 9 | 10 | public CommandClient newClient(WifiFacade wifiFacade, SSID softApSSID, String ipAddress, int port) { 11 | return new CommandClient(ipAddress, port, 12 | new NetworkBindingSocketFactory(wifiFacade, softApSSID, DEFAULT_TIMEOUT_SECONDS * 1000)); 13 | } 14 | 15 | public CommandClient newClientUsingDefaultsForDevices(WifiFacade wifiFacade, SSID softApSSID) { 16 | return newClient(wifiFacade, softApSSID, "192.168.0.1", 5609); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/devicesetup/commands/NoArgsCommand.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.devicesetup.commands; 2 | 3 | import com.google.gson.Gson; 4 | 5 | /** 6 | * Convenience class for commands with no argument data 7 | */ 8 | public abstract class NoArgsCommand extends Command { 9 | 10 | @Override 11 | public String argsAsJsonString(Gson gson) { 12 | // this command has no argument data 13 | return null; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/devicesetup/commands/PublicKeyCommand.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.devicesetup.commands; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | public class PublicKeyCommand extends NoArgsCommand { 6 | 7 | @Override 8 | public String getCommandName() { 9 | return "public-key"; 10 | } 11 | 12 | 13 | public static class Response { 14 | 15 | @SerializedName("r") 16 | public final int responseCode; 17 | 18 | // Hex-encoded public key, in DER format 19 | @SerializedName("b") 20 | public final String publicKey; 21 | 22 | public Response(int responseCode, String publicKey) { 23 | this.responseCode = responseCode; 24 | this.publicKey = publicKey; 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/devicesetup/commands/VersionCommand.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.devicesetup.commands; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | 6 | public class VersionCommand extends NoArgsCommand { 7 | 8 | @Override 9 | public String getCommandName() { 10 | return "version"; 11 | } 12 | 13 | 14 | public static class Response { 15 | 16 | @SerializedName("v") 17 | public final int version; 18 | 19 | public Response(int version) { 20 | this.version = version; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return "Response{" + 26 | "version=" + version + 27 | '}'; 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/devicesetup/model/WifiNetwork.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.devicesetup.model; 2 | 3 | import io.particle.android.sdk.utils.SSID; 4 | 5 | 6 | public interface WifiNetwork { 7 | 8 | SSID getSsid(); 9 | 10 | boolean isSecured(); 11 | } 12 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/devicesetup/setupsteps/SetupStepException.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.devicesetup.setupsteps; 2 | 3 | 4 | public class SetupStepException extends Exception { 5 | 6 | public SetupStepException(String msg, Throwable throwable) { 7 | super(msg, throwable); 8 | } 9 | 10 | public SetupStepException(String msg) { 11 | super(msg); 12 | } 13 | 14 | public SetupStepException(Throwable throwable) { 15 | super(throwable); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/devicesetup/setupsteps/StepProgress.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.devicesetup.setupsteps; 2 | 3 | 4 | public class StepProgress { 5 | 6 | public static final int STARTING = 1; 7 | static final int SUCCEEDED = 2; 8 | 9 | public final int stepId; 10 | public final int status; 11 | 12 | StepProgress(int stepId, int status) { 13 | this.status = status; 14 | this.stepId = stepId; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/devicesetup/ui/RequiresWifiScansActivity.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.devicesetup.ui; 2 | 3 | import android.Manifest.permission; 4 | import android.annotation.SuppressLint; 5 | import android.util.Log; 6 | 7 | import io.particle.android.sdk.ui.BaseActivity; 8 | 9 | @SuppressLint("Registered") 10 | public class RequiresWifiScansActivity extends BaseActivity { 11 | 12 | @Override 13 | protected void onStart() { 14 | super.onStart(); 15 | if (!PermissionsFragment.hasPermission(this, permission.ACCESS_FINE_LOCATION)) { 16 | Log.d("RequiresWifiScans", "Location permission appears to have been revoked, finishing activity..."); 17 | finish(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/di/ApplicationComponent.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.di; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import androidx.annotation.RestrictTo; 6 | 7 | import com.google.gson.Gson; 8 | 9 | import javax.inject.Singleton; 10 | 11 | import dagger.Component; 12 | import io.particle.android.sdk.cloud.ParticleCloud; 13 | 14 | @Singleton 15 | @Component(modules = {ApplicationModule.class, CloudModule.class}) 16 | @RestrictTo({RestrictTo.Scope.LIBRARY}) 17 | public interface ApplicationComponent { 18 | ActivityInjectorComponent.Builder activityComponentBuilder(); 19 | 20 | Application getApplication(); 21 | 22 | Context getContext(); 23 | 24 | ParticleCloud getParticleCloud(); 25 | 26 | Gson getGson(); 27 | } 28 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/di/ApplicationModule.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.di; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import androidx.annotation.RestrictTo; 6 | 7 | import javax.inject.Singleton; 8 | 9 | import dagger.Module; 10 | import dagger.Provides; 11 | 12 | @Module 13 | @RestrictTo({RestrictTo.Scope.LIBRARY}) 14 | public class ApplicationModule { 15 | private Application application; 16 | 17 | @RestrictTo(RestrictTo.Scope.LIBRARY) 18 | public ApplicationModule(Application application) { 19 | this.application = application; 20 | } 21 | 22 | @Singleton 23 | @Provides 24 | protected Application providesApplication() { 25 | return application; 26 | } 27 | 28 | @Singleton 29 | @Provides 30 | protected Context providesContext() { 31 | return application; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/di/CloudModule.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.di; 2 | 3 | import androidx.annotation.RestrictTo; 4 | 5 | import com.google.gson.Gson; 6 | 7 | import javax.inject.Singleton; 8 | 9 | import dagger.Module; 10 | import dagger.Provides; 11 | import io.particle.android.sdk.cloud.ParticleCloud; 12 | import io.particle.android.sdk.cloud.ParticleCloudSDK; 13 | 14 | @Module 15 | @RestrictTo({RestrictTo.Scope.LIBRARY}) 16 | public class CloudModule { 17 | 18 | @Singleton 19 | @Provides 20 | protected ParticleCloud providesParticleCloud() { 21 | return ParticleCloudSDK.getCloud(); 22 | } 23 | 24 | @Singleton 25 | @Provides 26 | protected Gson providesGson() { 27 | return new Gson(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/di/PerActivity.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.di; 2 | 3 | import androidx.annotation.RestrictTo; 4 | 5 | import java.lang.annotation.Documented; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | 9 | import javax.inject.Scope; 10 | 11 | @Scope 12 | @Documented 13 | @Retention(value = RetentionPolicy.RUNTIME) 14 | @RestrictTo({RestrictTo.Scope.LIBRARY}) 15 | public @interface PerActivity { 16 | } -------------------------------------------------------------------------------- /devicesetup/src/main/java/io/particle/android/sdk/utils/BetterAsyncTaskLoader.java: -------------------------------------------------------------------------------- 1 | package io.particle.android.sdk.utils; 2 | 3 | import android.content.Context; 4 | import androidx.loader.content.AsyncTaskLoader; 5 | 6 | 7 | public abstract class BetterAsyncTaskLoader extends AsyncTaskLoader { 8 | 9 | 10 | public abstract boolean hasContent(); 11 | 12 | public abstract T getLoadedContent(); 13 | 14 | 15 | public BetterAsyncTaskLoader(Context context) { 16 | super(context); 17 | } 18 | 19 | @Override 20 | protected void onStartLoading() { 21 | // How is this not on AsyncTaskLoader already? 22 | if (hasContent()) { 23 | deliverResult(getLoadedContent()); 24 | } 25 | if (takeContentChanged() || !hasContent()) { 26 | forceLoad(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xhdpi/checkmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xhdpi/checkmark.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxhdpi/fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxhdpi/fail.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxhdpi/ic_clear_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxhdpi/ic_clear_black_24dp.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxhdpi/particle_vertical_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxhdpi/particle_vertical_blue.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxhdpi/photon_vector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxhdpi/photon_vector.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxhdpi/product_img_photon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxhdpi/product_img_photon.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxhdpi/spinner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxhdpi/spinner.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxhdpi/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxhdpi/success.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxhdpi/the_wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxhdpi/the_wifi.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxhdpi/trianglifybackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxhdpi/trianglifybackground.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxxhdpi/honeycomb_bg.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxxhdpi/honeycomb_bg.webp -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxxhdpi/lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxxhdpi/lock.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxxhdpi/particle_horizontal_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxxhdpi/particle_horizontal_blue.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable-xxxhdpi/particle_horizontal_head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/devicesetup/src/main/res/drawable-xxxhdpi/particle_horizontal_head.png -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable/button_text_color_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable/link_text_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/drawable/progress_spinner.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/layout/activity_web_view.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/layout/brand_image_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/values-sw820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/values-v19/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12dp 4 | 24dp 5 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/values-v21/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/values-xlarge/dimens_font_size.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14sp 5 | 16sp 6 | 18sp 7 | 18sp 8 | 26sp 9 | 10 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #5222 4 | #E5FFFFFF 5 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 144dp 4 | 5 | 6 | 24dp 7 | 24dp 8 | 0dp 9 | 0dp 10 | 11 | 320dip 12 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/values/dimens_font_size.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10sp 5 | 12sp 6 | 14sp 7 | 18sp 8 | 22sp 9 | 10 | 112sp 11 | 56sp 12 | 45sp 13 | 34sp 14 | 24sp 15 | 20sp 16 | 16sp 17 | 14sp 18 | 12sp 19 | 20 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /devicesetup/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /ecjpake4j/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /mbedtls 3 | /mbedtls_build 4 | /.cxx 5 | 6 | -------------------------------------------------------------------------------- /ecjpake4j/README: -------------------------------------------------------------------------------- 1 | This module is a thin JNI wrapper around a portion of the EC-JPAKE interface of mbedtls. 2 | 3 | If you ever need to rebuild the version of mbedtls in the distribution folder, 4 | just 'cd' to the ecjpake4j dir, and run build_mbedtls.sh 5 | 6 | (Note that you will probably have to edit that script to specify the location 7 | of your Android NDK install) 8 | 9 | -------------------------------------------------------------------------------- /ecjpake4j/distribution/arm64-v8a/libmbedcrypto.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/ecjpake4j/distribution/arm64-v8a/libmbedcrypto.a -------------------------------------------------------------------------------- /ecjpake4j/distribution/arm64-v8a/libmbedtls.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/ecjpake4j/distribution/arm64-v8a/libmbedtls.a -------------------------------------------------------------------------------- /ecjpake4j/distribution/arm64-v8a/libmbedx509.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/ecjpake4j/distribution/arm64-v8a/libmbedx509.a -------------------------------------------------------------------------------- /ecjpake4j/distribution/armeabi-v7a/libmbedcrypto.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/ecjpake4j/distribution/armeabi-v7a/libmbedcrypto.a -------------------------------------------------------------------------------- /ecjpake4j/distribution/armeabi-v7a/libmbedtls.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/ecjpake4j/distribution/armeabi-v7a/libmbedtls.a -------------------------------------------------------------------------------- /ecjpake4j/distribution/armeabi-v7a/libmbedx509.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/ecjpake4j/distribution/armeabi-v7a/libmbedx509.a -------------------------------------------------------------------------------- /ecjpake4j/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /ecjpake4j/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /firmwareprotos/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /firmwareprotos/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 30 5 | 6 | 7 | 8 | defaultConfig { 9 | minSdkVersion 21 10 | targetSdkVersion 30 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | 22 | } 23 | 24 | dependencies { 25 | api 'com.google.protobuf:protobuf-java:3.5.1' 26 | } 27 | -------------------------------------------------------------------------------- /firmwareprotos/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /firmwareprotos/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Jan 17 15:17:16 PST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 7 | -------------------------------------------------------------------------------- /mesh/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /mesh/README.md: -------------------------------------------------------------------------------- 1 | # Mesh module 2 | 3 | ## Introduction 4 | 5 | This module contains the mesh setup flow code, but no UI. All UI-related code is in the `meshui` module. 6 | 7 | -------------------------------------------------------------------------------- /mesh/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /mesh/src/androidTest/java/io/particle/mesh/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package io.particle.mesh; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("io.particle.mesh.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /mesh/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/android/common/Resources.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.common 2 | 3 | import android.content.Context 4 | import android.net.Uri 5 | import androidx.annotation.RawRes 6 | 7 | 8 | fun Context.buildRawResourceUri(@RawRes rawRes: Int): Uri { 9 | return Uri.parse("android.resource://${this.packageName}/$rawRes") 10 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/bluetooth/BTCoroutines.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.bluetooth 2 | 3 | import kotlinx.coroutines.newSingleThreadContext 4 | 5 | 6 | /** 7 | * Single-threaded coroutine context to 100% ensure proper ordering for rx and tx of packets 8 | */ 9 | internal val packetTxRxContext = newSingleThreadContext("PACKET_TX_RX_CONTEXT") 10 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/bluetooth/Extensions.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.bluetooth 2 | 3 | import android.bluetooth.BluetoothAdapter 4 | import android.bluetooth.BluetoothManager 5 | import android.content.Context 6 | 7 | 8 | val Context.btAdapter: BluetoothAdapter 9 | get() { 10 | val btMgr = applicationContext.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager 11 | return btMgr.adapter 12 | } 13 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/bluetooth/PacketMTUSplitter.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.bluetooth 2 | 3 | import io.particle.mesh.setup.utils.readByteArray 4 | import java.nio.ByteBuffer 5 | 6 | 7 | class PacketMTUSplitter( 8 | private val outputTarget: (ByteArray) -> Unit, 9 | private val mtuSize: Int = 20, 10 | bufferSize: Int = 10240 11 | ) { 12 | 13 | private val buffer = ByteBuffer.allocate(bufferSize) 14 | 15 | @Synchronized 16 | fun splitIntoPackets(bytes: ByteArray) { 17 | buffer.clear() 18 | buffer.put(bytes) 19 | buffer.flip() 20 | 21 | while (buffer.hasRemaining()) { 22 | val packet = if (buffer.remaining() >= mtuSize) { 23 | buffer.readByteArray(mtuSize) 24 | } else { 25 | buffer.readByteArray() 26 | } 27 | outputTarget(packet) 28 | } 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/bluetooth/connecting/BondingState.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.bluetooth.connecting 2 | 3 | import android.bluetooth.BluetoothDevice 4 | import io.particle.android.sdk.utils.buildIntValueMap 5 | 6 | enum class BondingState(val intValue: Int) { 7 | 8 | BOND_NONE(BluetoothDevice.BOND_NONE), 9 | BOND_BONDING(BluetoothDevice.BOND_BONDING), 10 | BOND_BONDED(BluetoothDevice.BOND_BONDED); 11 | 12 | companion object { 13 | 14 | private val intValueMap = buildIntValueMap(values()) { state -> state.intValue } 15 | 16 | fun fromIntValue(intValue: Int): BondingState { 17 | val state = intValueMap.get(intValue) 18 | return requireNotNull(state) 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/bluetooth/connecting/ConnectionState.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.bluetooth.connecting 2 | 3 | import android.bluetooth.BluetoothProfile 4 | import io.particle.android.sdk.utils.buildIntValueMap 5 | 6 | 7 | enum class ConnectionState(val intValue: Int) { 8 | 9 | DISCONNECTED(BluetoothProfile.STATE_DISCONNECTED), 10 | CONNECTING(BluetoothProfile.STATE_CONNECTING), 11 | CONNECTED(BluetoothProfile.STATE_CONNECTED), 12 | DISCONNECTING(BluetoothProfile.STATE_DISCONNECTING), 13 | UNKNOWN(0x10101); // made up value that doesn't conflict with/overload any others 14 | 15 | 16 | companion object { 17 | 18 | private val intValueMap = buildIntValueMap(values()) { state -> state.intValue } 19 | 20 | fun fromIntValue(intValue: Int): ConnectionState { 21 | return intValueMap.get(intValue, UNKNOWN) 22 | } 23 | } 24 | 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/common/ByteArrays.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.common 2 | 3 | private const val ALL_HEX_CHARS = "0123456789ABCDEF" 4 | @Suppress("PrivatePropertyName") 5 | private val HEX_CHARARRAY = ALL_HEX_CHARS.toCharArray() 6 | 7 | 8 | fun ByteArray?.toHex(): String { 9 | if (this == null) { 10 | return "[null]" 11 | } 12 | 13 | val hexChars = CharArray(this.size * 2) 14 | 15 | for (i in this.indices) { 16 | val asInt = this[i].toInt() 17 | val v = asInt and 0xFF 18 | hexChars[i * 2] = HEX_CHARARRAY[v ushr 4] 19 | hexChars[i * 2 + 1] = HEX_CHARARRAY[v and 0x0F] 20 | } 21 | 22 | return String(hexChars) 23 | } 24 | 25 | 26 | fun Byte.toHex(): String { 27 | return byteArrayOf(this).toHex() 28 | } 29 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/common/Functions.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.common 2 | 3 | /** 4 | * Some simple functional tools and aliases 5 | */ 6 | 7 | 8 | typealias Predicate = (T) -> Boolean 9 | typealias Procedure = (T) -> Unit 10 | 11 | 12 | fun nonNull(): Predicate = { x -> x != null } 13 | 14 | 15 | inline infix fun Predicate.and(crossinline other: Predicate): Predicate { 16 | return { this(it) && other(it) } 17 | } 18 | 19 | 20 | inline infix fun Predicate.not(crossinline other: Predicate): Predicate { 21 | return negate(other) 22 | } 23 | 24 | 25 | inline fun negate(crossinline toNegate: Predicate): Predicate { 26 | return { !toNegate(it) } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/common/Result.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.common 2 | 3 | 4 | sealed class Result { 5 | 6 | abstract val value: V? 7 | abstract val error: E? 8 | 9 | data class Present( 10 | override val value: V 11 | ) : Result() { 12 | 13 | override val error: E? = null 14 | } 15 | 16 | data class Error( 17 | override val error: E 18 | ) : Result() { 19 | 20 | override val value: V? = null 21 | } 22 | 23 | data class Absent( 24 | // data classes *require* that they have at least one unique param, so 25 | // this fulfills that contract 26 | private val _ignore_do_not_use_: Int = 0 27 | ) : Result() { 28 | 29 | override val value: V? = null 30 | override val error: E? = null 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/common/android/Extensions.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.common.android 2 | 3 | import android.content.BroadcastReceiver 4 | import android.content.IntentFilter 5 | 6 | 7 | fun BroadcastReceiver.filterFromAction(bcastAction: String): IntentFilter = IntentFilter(bcastAction) 8 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/common/android/SimpleLifecycleOwner.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.common.android 2 | 3 | import androidx.lifecycle.Lifecycle 4 | import androidx.lifecycle.LifecycleOwner 5 | import androidx.lifecycle.LifecycleRegistry 6 | import io.particle.mesh.setup.flow.Scopes 7 | import io.particle.mesh.setup.utils.runOnMainThread 8 | 9 | 10 | class SimpleLifecycleOwner : LifecycleOwner { 11 | 12 | private val registry = LifecycleRegistry(this) 13 | private val scopes = Scopes() 14 | 15 | override fun getLifecycle(): Lifecycle = registry 16 | 17 | fun setNewState(newState: Lifecycle.State) { 18 | scopes.onMain { registry.markState(newState) } 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/common/android/livedata/AbsentLiveData.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.common.android.livedata 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.Transformations 5 | 6 | /** 7 | * A LiveData which has no data yet, for use with things like [Transformations.switchMap]. 8 | */ 9 | class AbsentLiveData : LiveData() { 10 | 11 | init { 12 | postValue(null) 13 | } 14 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/common/android/livedata/ClearValueOnInactiveLiveData.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.common.android.livedata 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import mu.KotlinLogging 5 | 6 | class ClearValueOnInactiveLiveData : MutableLiveData() { 7 | 8 | private val log = KotlinLogging.logger {} 9 | 10 | override fun onInactive() { 11 | super.onInactive() 12 | log.info { "LD deactivated, clearing value" } 13 | this.value = null 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/common/android/livedata/LiveDatas.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.common.android.livedata 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import io.particle.mesh.setup.utils.isThisTheMainThread 6 | 7 | 8 | 9 | 10 | fun MutableLiveData.setOnMainThread(newValue: T) { 11 | if (isThisTheMainThread()) { 12 | this.value = newValue 13 | } else { 14 | this.postValue(newValue) 15 | } 16 | } 17 | 18 | 19 | fun LiveData.castAndSetOnMainThread(newValue: T) { 20 | (this as MutableLiveData).setOnMainThread(newValue) 21 | } 22 | 23 | 24 | fun LiveData.castAndPost(value: T?) { 25 | (this as MutableLiveData).postValue(value) 26 | } 27 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/SerialNumbers.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup 2 | 3 | import androidx.annotation.WorkerThread 4 | import io.particle.android.sdk.cloud.ParticleCloud 5 | import io.particle.android.sdk.cloud.ParticleDevice.ParticleDeviceType 6 | import mu.KotlinLogging 7 | 8 | 9 | private val log = KotlinLogging.logger {} 10 | 11 | 12 | inline class SerialNumber(val value: String) 13 | 14 | 15 | 16 | @WorkerThread 17 | fun SerialNumber.toDeviceType(cloud: ParticleCloud): ParticleDeviceType { 18 | return cloud.getPlatformId(this.value) 19 | } 20 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/WiFiStrength.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup 2 | 3 | 4 | enum class WiFiStrength(val sortValue: Int) { 5 | 6 | STRONG(3), 7 | MEDIUM(2), 8 | WEAK(1); 9 | 10 | companion object { 11 | fun fromInt(value: Int): WiFiStrength { 12 | return when { 13 | (value > 0) -> throw IllegalArgumentException("Invalid RSSI value: $value") 14 | (value > -56) -> STRONG 15 | (value >= -71) -> MEDIUM 16 | else -> WEAK 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/connection/Config.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.connection 2 | 3 | import java.util.concurrent.TimeUnit 4 | 5 | 6 | // FIXME: set this to something smaller, or rely on DeviceOS's timeouts? 7 | // this has to be LONG for some of the messages to be processed (like AuthRequest) 8 | val BLE_PROTO_REQUEST_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(15) 9 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/connection/Constants.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.connection 2 | 3 | import java.util.* 4 | 5 | 6 | val BT_SETUP_SERVICE_ID = UUID.fromString("6FA90001-5C4E-48A8-94F4-8030546F36FC") 7 | val BT_PROTOCOL_VERSION_ID = UUID.fromString("6FA90002-5C4E-48A8-94F4-8030546F36FC") 8 | // this is "TX" from the Device OS perspective, labelled as such to match docs elsewhere. 9 | // from the mobile device perspective, this is the characteristic we will subscribe to 10 | // (i.e.: read from) 11 | val BT_SETUP_TX_CHARACTERISTIC_ID = UUID.fromString("6FA90003-5C4E-48A8-94F4-8030546F36FC") 12 | // this is "RX" from the Device OS perspective 13 | // from the mobile device perspective, this is the characteristic to write to for sending data 14 | // to the device 15 | val BT_SETUP_RX_CHARACTERISTIC_ID = UUID.fromString("6FA90004-5C4E-48A8-94F4-8030546F36FC") 16 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/Clearable.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow 2 | 3 | 4 | interface Clearable { 5 | 6 | fun clearState() 7 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/Flow.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow 2 | 3 | import io.particle.mesh.common.Result 4 | import mu.KotlinLogging 5 | 6 | 7 | // FIXME: put these somewhere better 8 | 9 | 10 | enum class Gen3ConnectivityType { 11 | WIFI, 12 | CELLULAR, 13 | MESH_ONLY 14 | } 15 | 16 | 17 | inline fun Result.throwOnErrorOrAbsent(): V { 18 | return when (this) { 19 | is Result.Error, 20 | is Result.Absent -> { 21 | val log = KotlinLogging.logger {} 22 | val msg = if (this is Result.Error) { 23 | "Error getting result: ${this.error}" 24 | } else { 25 | "Absent result returned! value type=${V::class}, error type=${E::class}" 26 | } 27 | log.error { msg } 28 | throw MeshSetupFlowException(null, msg) 29 | } 30 | is Result.Present -> this.value 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/FlowConfig.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow 2 | 3 | 4 | internal const val SIM_ACTION_MAX_RETRY_COUNT = 4 -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/SimStatusChangeMode.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow 2 | 3 | 4 | enum class SimStatusChangeMode { 5 | DEACTIVATE, 6 | UNPAUSE, 7 | REACTIVATE 8 | } 9 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/context/BLEContext.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.context 2 | 3 | import io.particle.mesh.common.logged 4 | import io.particle.mesh.setup.flow.Clearable 5 | import mu.KotlinLogging 6 | 7 | 8 | class BLEContext : Clearable { 9 | 10 | private val log = KotlinLogging.logger {} 11 | 12 | var connectingToTargetUiShown by log.logged(false) 13 | var showingConnectingToTargetUi by log.logged(false) 14 | 15 | var connectingToAssistingDeviceUiShown by log.logged(false) 16 | var shownAssistingDeviceInitialIsConnectedScreen by log.logged(false) 17 | 18 | 19 | override fun clearState() { 20 | log.info { "clearState()" } 21 | connectingToAssistingDeviceUiShown = false 22 | shownAssistingDeviceInitialIsConnectedScreen = false 23 | connectingToTargetUiShown = false 24 | showingConnectingToTargetUi = false 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/meshsetup/MeshNetworkToJoin.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.meshsetup 2 | 3 | import io.particle.firmwareprotos.ctrl.mesh.Mesh.NetworkInfo 4 | 5 | 6 | // FIXME: figure out a way to make this "internal" 7 | sealed class MeshNetworkToJoin { 8 | 9 | data class SelectedNetwork( 10 | val networkToJoin: NetworkInfo 11 | ) : MeshNetworkToJoin() 12 | 13 | class CreateNewNetwork : MeshNetworkToJoin() { 14 | override fun equals(other: Any?): Boolean = this === other 15 | override fun hashCode(): Int = System.identityHashCode(this) 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepEnsureListeningStoppedForBothDevices.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | 7 | 8 | class StepEnsureListeningStoppedForBothDevices : MeshSetupStep() { 9 | 10 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 11 | ctxs.targetDevice.transceiverLD.value?.sendStopListeningMode() 12 | ctxs.commissioner.transceiverLD.value?.sendStopListeningMode() 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepFetchCurrentMeshNetwork.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.FlowUiDelegate 4 | import io.particle.mesh.setup.flow.MeshSetupStep 5 | import io.particle.mesh.setup.flow.Scopes 6 | import io.particle.mesh.setup.flow.context.SetupContexts 7 | import io.particle.mesh.setup.flow.throwOnErrorOrAbsent 8 | 9 | 10 | class StepFetchCurrentMeshNetwork(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 11 | 12 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 13 | flowUi.showGlobalProgressSpinner(true) 14 | 15 | try { 16 | val reply = ctxs.requireTargetXceiver().sendGetNetworkInfo().throwOnErrorOrAbsent() 17 | ctxs.mesh.currentlyJoinedNetwork = reply.network 18 | 19 | } catch (ex: Exception) { 20 | ctxs.mesh.currentlyJoinedNetwork = null 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepFetchDeviceId.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import androidx.annotation.WorkerThread 4 | import io.particle.mesh.setup.flow.MeshSetupStep 5 | import io.particle.mesh.setup.flow.Scopes 6 | import io.particle.mesh.setup.flow.context.SetupContexts 7 | import io.particle.mesh.setup.flow.throwOnErrorOrAbsent 8 | 9 | 10 | class StepFetchDeviceId : MeshSetupStep() { 11 | 12 | @WorkerThread 13 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 14 | if (ctxs.targetDevice.deviceId != null) { 15 | return 16 | } 17 | 18 | val deviceIdReply = ctxs.requireTargetXceiver().sendGetDeviceId().throwOnErrorOrAbsent() 19 | ctxs.targetDevice.deviceId = deviceIdReply.id 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepFetchIccidFromCloud.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.android.sdk.cloud.ParticleCloud 4 | import io.particle.mesh.setup.flow.FlowUiDelegate 5 | import io.particle.mesh.setup.flow.MeshSetupStep 6 | import io.particle.mesh.setup.flow.Scopes 7 | import io.particle.mesh.setup.flow.context.SetupContexts 8 | 9 | 10 | class StepFetchIccidFromCloud( 11 | private val cloud: ParticleCloud, 12 | private val flowUi: FlowUiDelegate 13 | ) : MeshSetupStep() { 14 | 15 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 16 | if (ctxs.targetDevice.iccid != null) { 17 | return 18 | } 19 | 20 | flowUi.showGlobalProgressSpinner(true) 21 | val device = cloud.getDevice(ctxs.targetDevice.deviceId!!) 22 | ctxs.targetDevice.iccid = device.iccid 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepGetNewMeshNetworkPassword.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.common.android.livedata.nonNull 4 | import io.particle.mesh.common.android.livedata.runBlockOnUiThreadAndAwaitUpdate 5 | import io.particle.mesh.setup.flow.MeshSetupStep 6 | import io.particle.mesh.setup.flow.Scopes 7 | import io.particle.mesh.setup.flow.context.SetupContexts 8 | import io.particle.mesh.setup.flow.FlowUiDelegate 9 | 10 | 11 | class StepGetNewMeshNetworkPassword(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 12 | 13 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 14 | if (ctxs.mesh.newNetworkPasswordLD.value != null) { 15 | return 16 | } 17 | 18 | ctxs.mesh.newNetworkPasswordLD.nonNull(scopes).runBlockOnUiThreadAndAwaitUpdate(scopes) { 19 | flowUi.getNewMeshNetworkPassword() 20 | } 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepPopBackStack.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.FlowUiDelegate 4 | import io.particle.mesh.setup.flow.MeshSetupStep 5 | import io.particle.mesh.setup.flow.Scopes 6 | import io.particle.mesh.setup.flow.context.SetupContexts 7 | 8 | class StepPopBackStack( 9 | private val flowUi: FlowUiDelegate, 10 | private val popToRoot: Boolean = false 11 | ) : MeshSetupStep() { 12 | 13 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 14 | if (!popToRoot) { 15 | flowUi.popBackStack() 16 | flowUi.showGlobalProgressSpinner(false) 17 | return 18 | } 19 | 20 | var popped = true 21 | while (popped) { 22 | popped = flowUi.popBackStack() 23 | } 24 | flowUi.showGlobalProgressSpinner(false) 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepSetClaimCode.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | import io.particle.mesh.setup.flow.throwOnErrorOrAbsent 7 | 8 | 9 | class StepSetClaimCode : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | // if claim code is null, we don't intend to claim 13 | if (ctxs.targetDevice.isClaimedLD.value == true || ctxs.cloud.shouldBeClaimed == false) { 14 | return 15 | } 16 | 17 | val targetXceiver = ctxs.targetDevice.transceiverLD.value!! 18 | targetXceiver.sendSetClaimCode(ctxs.cloud.claimCode!!).throwOnErrorOrAbsent() 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepSetSetupDone.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | import io.particle.mesh.setup.flow.throwOnErrorOrAbsent 7 | 8 | class StepSetSetupDone : MeshSetupStep() { 9 | 10 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 11 | val xceiver = ctxs.requireTargetXceiver() 12 | xceiver.sendSetDeviceSetupDone(true).throwOnErrorOrAbsent() 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowCellularConnectingToDeviceCloudUi.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | import io.particle.mesh.setup.flow.FlowUiDelegate 7 | 8 | class StepShowCellularConnectingToDeviceCloudUi( 9 | private val flowUi: FlowUiDelegate 10 | ) : MeshSetupStep() { 11 | 12 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 13 | if (ctxs.cellular.connectingToCloudUiShown) { 14 | return 15 | } 16 | ctxs.cellular.connectingToCloudUiShown = true 17 | flowUi.showConnectingToDeviceCloudCellularUi() 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowCellularOptionsUi.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.FlowUiDelegate 4 | import io.particle.mesh.setup.flow.MeshSetupStep 5 | import io.particle.mesh.setup.flow.Scopes 6 | import io.particle.mesh.setup.flow.context.SetupContexts 7 | 8 | 9 | class StepShowCellularOptionsUi(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | flowUi.showControlPanelCellularOptionsUi() 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowConnectingToDeviceCloudUi.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | import io.particle.mesh.setup.flow.FlowUiDelegate 7 | 8 | 9 | class StepShowConnectingToDeviceCloudUi(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | flowUi.showConnectingToDeviceCloudUi() 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowCreateNetworkFinished.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | import io.particle.mesh.setup.flow.FlowUiDelegate 7 | 8 | 9 | class StepShowCreateNetworkFinished(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | flowUi.showCreateNetworkFinishedUi() 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowCreateNewMeshNetworkUi.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | import io.particle.mesh.setup.flow.FlowUiDelegate 7 | 8 | 9 | class StepShowCreateNewMeshNetworkUi(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | if (ctxs.mesh.newNetworkCreatedSuccessfully) { 13 | return 14 | } 15 | 16 | flowUi.showCreatingMeshNetworkUi() 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowDeviceWifiNetworks.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.FlowUiDelegate 4 | import io.particle.mesh.setup.flow.MeshSetupStep 5 | import io.particle.mesh.setup.flow.Scopes 6 | import io.particle.mesh.setup.flow.context.SetupContexts 7 | 8 | 9 | class StepShowDeviceWifiNetworks(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | flowUi.showControlPanelWifiManageList() 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowEthernetOptionsUi.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.FlowUiDelegate 4 | import io.particle.mesh.setup.flow.MeshSetupStep 5 | import io.particle.mesh.setup.flow.Scopes 6 | import io.particle.mesh.setup.flow.context.SetupContexts 7 | 8 | 9 | class StepShowEthernetOptionsUi(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | flowUi.showEthernetOptionsUi(ctxs.ble.connectingToTargetUiShown) 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowJoinerSetupFinishedUi.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | import io.particle.mesh.setup.flow.FlowUiDelegate 7 | 8 | 9 | class StepShowJoinerSetupFinishedUi(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | flowUi.showJoinerSetupFinishedUi() 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowJoiningMeshNetworkUi.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | import io.particle.mesh.setup.flow.FlowUiDelegate 7 | 8 | 9 | class StepShowJoiningMeshNetworkUi(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | flowUi.showJoiningMeshNetworkUi() 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowLetsGetBuildingUi.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.FlowUiDelegate 4 | import io.particle.mesh.setup.flow.MeshSetupStep 5 | import io.particle.mesh.setup.flow.Scopes 6 | import io.particle.mesh.setup.flow.context.SetupContexts 7 | 8 | 9 | class StepShowLetsGetBuildingUi(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | flowUi.showSetupFinishedUi() 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowMeshInspectNetworkUi.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.FlowUiDelegate 4 | import io.particle.mesh.setup.flow.MeshSetupStep 5 | import io.particle.mesh.setup.flow.Scopes 6 | import io.particle.mesh.setup.flow.context.SetupContexts 7 | import kotlinx.coroutines.flow.flow 8 | import mu.KotlinLogging 9 | 10 | 11 | class StepShowMeshInspectNetworkUi(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 12 | 13 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 14 | if (ctxs.mesh.currentlyJoinedNetwork == null) { 15 | flowUi.showMeshOptionsUi(ctxs.ble.connectingToTargetUiShown) 16 | } else { 17 | flowUi.showMeshInspectNetworkUi(ctxs.ble.connectingToTargetUiShown) 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowSingleTaskCongratsScreen.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | import io.particle.mesh.setup.flow.FlowUiDelegate 7 | import io.particle.mesh.setup.flow.PostCongratsAction 8 | 9 | 10 | class StepShowSingleTaskCongratsScreen( 11 | private val flowUi: FlowUiDelegate, 12 | private val message: String? = null 13 | ) : MeshSetupStep() { 14 | 15 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 16 | if (message != null) { 17 | ctxs.singleStepCongratsMessage = message 18 | } 19 | flowUi.showCongratsScreen(ctxs.singleStepCongratsMessage, PostCongratsAction.RESET_TO_START) 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowSnackbar.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.FlowUiDelegate 4 | import io.particle.mesh.setup.flow.MeshSetupStep 5 | import io.particle.mesh.setup.flow.Scopes 6 | import io.particle.mesh.setup.flow.context.SetupContexts 7 | 8 | 9 | class StepShowSnackbar(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | flowUi.showSnackbarWithMessage(ctxs.snackbarMessage) 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepShowWifiConnectingToDeviceCloudUi.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | import io.particle.mesh.setup.flow.FlowUiDelegate 7 | 8 | 9 | class StepShowWifiConnectingToDeviceCloudUi(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 10 | 11 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 12 | if (ctxs.wifi.connectingToCloudUiShown) { 13 | return 14 | } 15 | ctxs.wifi.connectingToCloudUiShown = true 16 | flowUi.showConnectingToDeviceCloudWiFiUi() 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepStartListeningModeForTarget.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.FlowUiDelegate 4 | import io.particle.mesh.setup.flow.MeshSetupStep 5 | import io.particle.mesh.setup.flow.Scopes 6 | import io.particle.mesh.setup.flow.context.SetupContexts 7 | import kotlinx.coroutines.delay 8 | 9 | 10 | class StepStartListeningModeForTarget(private val flowUi: FlowUiDelegate) : MeshSetupStep() { 11 | 12 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 13 | flowUi.showGlobalProgressSpinner(true) 14 | ctxs.requireTargetXceiver().sendStartListeningMode() 15 | delay(500) 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/flow/setupsteps/StepUnsetFullSimData.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.flow.setupsteps 2 | 3 | import io.particle.mesh.setup.flow.MeshSetupStep 4 | import io.particle.mesh.setup.flow.Scopes 5 | import io.particle.mesh.setup.flow.context.SetupContexts 6 | 7 | class StepUnsetFullSimData : MeshSetupStep() { 8 | 9 | override suspend fun doRunStep(ctxs: SetupContexts, scopes: Scopes) { 10 | ctxs.targetDevice.sim = null 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/ui/ProgressHack.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.ui 2 | 3 | import androidx.annotation.AnyThread 4 | 5 | 6 | interface ProgressHack { 7 | @AnyThread 8 | fun showGlobalProgressSpinner(show: Boolean) 9 | } 10 | -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/ui/utils/Networks.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.ui.utils 2 | 3 | import android.content.Context 4 | import android.net.ConnectivityManager 5 | import android.net.NetworkInfo 6 | 7 | 8 | fun Context.localDeviceHasInternetConnection(): Boolean { 9 | val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager 10 | val activeNetwork: NetworkInfo? = cm.activeNetworkInfo 11 | return activeNetwork?.isConnectedOrConnecting == true 12 | } -------------------------------------------------------------------------------- /mesh/src/main/java/io/particle/mesh/setup/utils/Buffers.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.setup.utils 2 | 3 | import okio.Buffer 4 | 5 | 6 | fun Buffer.readUint16LE(): Int { 7 | return ByteMath.readUint16LE(this) 8 | } 9 | 10 | fun Buffer.writeUint16LE(value: Int): Buffer { 11 | ByteMath.writeUint16LE(this, value) 12 | return this 13 | } 14 | 15 | -------------------------------------------------------------------------------- /mesh/src/test/java/io/particle/mesh/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package io.particle.mesh; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /meshui/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /meshui/README.md: -------------------------------------------------------------------------------- 1 | # Mesh module 2 | 3 | ## Introduction 4 | 5 | This module contains the UI for mesh setup flow, but no flow logic. All logic should live in the `mesh` module. 6 | 7 | -------------------------------------------------------------------------------- /meshui/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /meshui/src/androidTest/java/io/particle/mesh/ui/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.ui; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("io.particle.mesh.ui", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /meshui/src/main/java/io/particle/android/common/Adapters.kt: -------------------------------------------------------------------------------- 1 | package io.particle.android.common 2 | 3 | import android.annotation.SuppressLint 4 | import androidx.recyclerview.widget.DiffUtil 5 | 6 | 7 | fun easyDiffUtilCallback(idFieldGetter: (T) -> I): DiffUtil.ItemCallback { 8 | 9 | return object: DiffUtil.ItemCallback() { 10 | 11 | @SuppressLint("DiffUtilEquals") 12 | override fun areContentsTheSame(oldItem: T, newItem: T): Boolean { 13 | return oldItem == newItem 14 | } 15 | 16 | override fun areItemsTheSame(oldItem: T, newItem: T): Boolean { 17 | return idFieldGetter(oldItem) == idFieldGetter(newItem) 18 | } 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /meshui/src/main/java/io/particle/mesh/ui/setup/AssistingDevicePairingProgressFragment.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.ui.setup 2 | 3 | 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import io.particle.mesh.ui.BaseFlowFragment 9 | import io.particle.mesh.ui.R 10 | 11 | 12 | class AssistingDevicePairingProgressFragment : BaseFlowFragment() { 13 | 14 | override fun onCreateView( 15 | inflater: LayoutInflater, container: ViewGroup?, 16 | savedInstanceState: Bundle? 17 | ): View? { 18 | return inflater.inflate( 19 | R.layout.fragment_assisting_device_pairing_progress, 20 | container, 21 | false 22 | ) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /meshui/src/main/java/io/particle/mesh/ui/utils/Resources.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.ui.utils 2 | 3 | import androidx.annotation.StringRes 4 | import androidx.fragment.app.Fragment 5 | 6 | 7 | fun Fragment.getResOrEmptyString(@StringRes resId: Int?): String { 8 | return if (resId == null) "" else getString(resId) 9 | } -------------------------------------------------------------------------------- /meshui/src/main/java/io/particle/mesh/ui/utils/ViewModels.kt: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.ui.utils 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.fragment.app.FragmentActivity 5 | import androidx.lifecycle.ViewModel 6 | import androidx.lifecycle.ViewModelProviders 7 | 8 | 9 | inline fun FragmentActivity.getViewModel(): T { 10 | return ViewModelProviders.of(this).get(T::class.java) 11 | } 12 | 13 | 14 | inline fun Fragment.getViewModel(): T { 15 | val activity = requireActivity() 16 | return activity.getViewModel() 17 | } 18 | -------------------------------------------------------------------------------- /meshui/src/main/res/drawable-xxhdpi/sim_activate_header_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/drawable-xxhdpi/sim_activate_header_image.png -------------------------------------------------------------------------------- /meshui/src/main/res/drawable-xxhdpi/sim_deactivate_header_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/drawable-xxhdpi/sim_deactivate_header_image.png -------------------------------------------------------------------------------- /meshui/src/main/res/drawable-xxhdpi/unclaim_device_header_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/drawable-xxhdpi/unclaim_device_header_image.png -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/background_top_bottom_gray_borders.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/ic_check_cyan_24dp.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/ic_check_gray_24dp.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/ic_chevron_right_gray_24dp.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/p_ic_close_cyan_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/p_mesh_hintbox_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/p_mesh_ic_camera_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/p_mesh_ic_lock_black_14dp.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/p_mesh_ic_lock_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/p_mesh_ic_wifi_strength_high.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/drawable/p_mesh_ic_wifi_strength_high.png -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/p_mesh_ic_wifi_strength_low.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/drawable/p_mesh_ic_wifi_strength_low.png -------------------------------------------------------------------------------- /meshui/src/main/res/drawable/p_mesh_ic_wifi_strength_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/drawable/p_mesh_ic_wifi_strength_medium.png -------------------------------------------------------------------------------- /meshui/src/main/res/layout/p_scanformeshnetwork_row_select_mesh_network.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | -------------------------------------------------------------------------------- /meshui/src/main/res/layout/row_select_comissioner.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | -------------------------------------------------------------------------------- /meshui/src/main/res/raw/commissioner_to_listening_mode.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/raw/commissioner_to_listening_mode.mov -------------------------------------------------------------------------------- /meshui/src/main/res/raw/cp_device_in_listening_mode.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/raw/cp_device_in_listening_mode.mov -------------------------------------------------------------------------------- /meshui/src/main/res/raw/power_on_argon.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/raw/power_on_argon.mov -------------------------------------------------------------------------------- /meshui/src/main/res/raw/power_on_boron_battery.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/raw/power_on_boron_battery.mov -------------------------------------------------------------------------------- /meshui/src/main/res/raw/power_on_bsom.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/raw/power_on_bsom.mov -------------------------------------------------------------------------------- /meshui/src/main/res/raw/power_on_featherwing.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/raw/power_on_featherwing.mp4 -------------------------------------------------------------------------------- /meshui/src/main/res/raw/power_on_som_ethernet.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/raw/power_on_som_ethernet.mov -------------------------------------------------------------------------------- /meshui/src/main/res/raw/power_on_xenon.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/meshui/src/main/res/raw/power_on_xenon.mov -------------------------------------------------------------------------------- /meshui/src/main/res/values-h700dp/dimens_mesh.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 300dp 6 | 7 | -------------------------------------------------------------------------------- /meshui/src/main/res/values/colors_mesh.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /meshui/src/main/res/values/dimens_mesh.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4dp 5 | 215dp 6 | 7 | -------------------------------------------------------------------------------- /meshui/src/main/res/values/ids_mesh.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /meshui/src/main/res/values/styles_mesh.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /meshui/src/test/java/io/particle/mesh/ui/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package io.particle.mesh.ui; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /particle-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/particle-mark.png -------------------------------------------------------------------------------- /play_store_512px_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/play_store_512px_icon.png -------------------------------------------------------------------------------- /sdk_example_app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /sdk_example_app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/ido/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /sdk_example_app/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /sdk_example_app/src/main/res/menu/menu_splash.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /sdk_example_app/src/main/res/menu/menu_value.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /sdk_example_app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/sdk_example_app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sdk_example_app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/sdk_example_app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sdk_example_app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/sdk_example_app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sdk_example_app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/sdk_example_app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sdk_example_app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /sdk_example_app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /sdk_example_app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | SparkSDK_android_first_try 3 | 4 | Splash! 5 | Settings 6 | LoginActivity 7 | Login 8 | Device Info 9 | ValueActivity 10 | DeviceInfoActivity 11 | 12 | FULL 13 | 14 | 15 | -------------------------------------------------------------------------------- /sdk_example_app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', 2 | ':commonui', 3 | ':meshui', 4 | ':mesh', 5 | ':firmwareprotos', 6 | ':cloudsdk', 7 | ':devicesetup', 8 | ':sdk_example_app', 9 | ':setup_testapp', 10 | ':setup_exampleapp', 11 | ':ecjpake4j' 12 | -------------------------------------------------------------------------------- /setup_exampleapp/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /setup_exampleapp/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /setup_exampleapp/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/ido/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /setup_exampleapp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /setup_exampleapp/src/main/java/io/particle/devicesetup/exampleapp/ExampleSetupCompleteIntentBuilder.java: -------------------------------------------------------------------------------- 1 | package io.particle.devicesetup.exampleapp; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import io.particle.android.sdk.devicesetup.SetupCompleteIntentBuilder; 7 | import io.particle.android.sdk.devicesetup.SetupResult; 8 | 9 | public class ExampleSetupCompleteIntentBuilder implements SetupCompleteIntentBuilder { 10 | private final String setupLaunchedTime; 11 | 12 | ExampleSetupCompleteIntentBuilder(String setupLaunchedTime) { 13 | this.setupLaunchedTime = setupLaunchedTime; 14 | } 15 | 16 | @Override 17 | public Intent buildIntent(Context ctx, SetupResult result) { 18 | Intent intent = new Intent(ctx, MainActivity.class); 19 | intent.putExtra(MainActivity.EXTRA_SETUP_LAUNCHED_TIME, setupLaunchedTime); 20 | 21 | return intent; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /setup_exampleapp/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /setup_exampleapp/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_exampleapp/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /setup_exampleapp/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_exampleapp/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /setup_exampleapp/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_exampleapp/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /setup_exampleapp/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_exampleapp/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /setup_exampleapp/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /setup_exampleapp/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /setup_exampleapp/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Example app 3 | 4 | Hello world! 5 | Welcome back! You\'ve returned from setup, which started at %s. 6 | 7 | Settings 8 | 9 | 10 | FULL 11 | 12 | -------------------------------------------------------------------------------- /setup_exampleapp/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /setup_testapp/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /setup_testapp/src/androidTest/java/io/particle/devicesetup/testapp/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package io.particle.devicesetup.testapp; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /setup_testapp/src/androidTest/java/io/particle/devicesetup/testapp/CustomAndroidTestRunner.java: -------------------------------------------------------------------------------- 1 | package io.particle.devicesetup.testapp; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.support.test.runner.AndroidJUnitRunner; 6 | 7 | public class CustomAndroidTestRunner extends AndroidJUnitRunner { 8 | 9 | @Override 10 | public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { 11 | return super.newApplication(cl, CustomApplication.class.getName(), context); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /setup_testapp/src/androidTest/java/io/particle/devicesetup/testapp/CustomApplication.java: -------------------------------------------------------------------------------- 1 | package io.particle.devicesetup.testapp; 2 | 3 | import android.app.Application; 4 | 5 | import io.particle.android.sdk.cloud.ParticleCloudSDK; 6 | 7 | public class CustomApplication extends Application { 8 | 9 | @Override 10 | public void onCreate() { 11 | super.onCreate(); 12 | ParticleCloudSDK.init(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /setup_testapp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /setup_testapp/src/main/java/io/particle/devicesetup/testapp/MainActivity.java: -------------------------------------------------------------------------------- 1 | package io.particle.devicesetup.testapp; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.appcompat.app.AppCompatActivity; 6 | 7 | 8 | public class MainActivity extends AppCompatActivity { 9 | 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | setContentView(R.layout.activity_main); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /setup_testapp/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /setup_testapp/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_testapp/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /setup_testapp/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_testapp/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /setup_testapp/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_testapp/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /setup_testapp/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_testapp/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /setup_testapp/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_testapp/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /setup_testapp/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_testapp/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /setup_testapp/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_testapp/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /setup_testapp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_testapp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /setup_testapp/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_testapp/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /setup_testapp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/particle-iot/particle-android/996d4dcbf085e6e13c438eaa4ebee546a5659ef0/setup_testapp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /setup_testapp/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /setup_testapp/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Testapp 3 | 4 | -------------------------------------------------------------------------------- /setup_testapp/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /setup_testapp/src/test/java/io/particle/devicesetup/testapp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package io.particle.devicesetup.testapp; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } --------------------------------------------------------------------------------