diff --git a/app/build.gradle b/app/build.gradle index 9913477a..1b449b49 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,8 +17,8 @@ android { applicationId "info.dvkr.screenstream" minSdkVersion 21 targetSdkVersion 26 - versionCode 202 - versionName "2.0.2" + versionCode 203 + versionName "2.0.3" resConfigs "en", "ru"//, "es" // multiDexEnabled = true } diff --git a/app/src/main/java/info/dvkr/screenstream/model/httpserver/HttpServerImpl.kt b/app/src/main/java/info/dvkr/screenstream/model/httpserver/HttpServerImpl.kt index 3f4bbdb0..9baa7c69 100644 --- a/app/src/main/java/info/dvkr/screenstream/model/httpserver/HttpServerImpl.kt +++ b/app/src/main/java/info/dvkr/screenstream/model/httpserver/HttpServerImpl.kt @@ -65,8 +65,8 @@ class HttpServerImpl constructor(serverAddress: InetSocketAddress, // Clients @Keep class LocalClient(clientAddress: InetSocketAddress, - var sendBytes: Long = 0, - var disconnectedTime: Long = 0) : HttpServer.Client(clientAddress) + var sendBytes: Long = 0, + var disconnectedTime: Long = 0) : HttpServer.Client(clientAddress) @Keep sealed class LocalEvent { @Keep data class ClientConnected(val address: InetSocketAddress) : LocalEvent() diff --git a/app/src/main/java/info/dvkr/screenstream/model/image/ImageGeneratorImpl.kt b/app/src/main/java/info/dvkr/screenstream/model/image/ImageGeneratorImpl.kt index d4ae8936..dac68ab7 100644 --- a/app/src/main/java/info/dvkr/screenstream/model/image/ImageGeneratorImpl.kt +++ b/app/src/main/java/info/dvkr/screenstream/model/image/ImageGeneratorImpl.kt @@ -102,32 +102,32 @@ class ImageGeneratorImpl(context: Context, imageReader = ImageReader.newInstance(screenSize.x, screenSize.y, PixelFormat.RGBA_8888, 2) imageReader.setOnImageAvailableListener(listener, imageThreadHandler) - try { - virtualDisplay = mediaProjection.createVirtualDisplay("ScreenStreamVirtualDisplay", - screenSize.x, screenSize.y, displayMetrics.densityDpi, - DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, imageReader.surface, null, null) - - subscriptions.add(Observable.interval(250, TimeUnit.MILLISECONDS) - .map { _ -> windowManager.defaultDisplay.rotation } - .map { rotation -> rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 } - .distinctUntilChanged() - .skip(1) - .filter { _ -> STATE_STARTED == imageReaderState } - .subscribe { _ -> restart() } - ) - - imageReaderState = STATE_STARTED - globalStatus.isStreamRunning.set(true) - eventBus.sendEvent(EventBus.GlobalEvent.StreamStatus()) - if (BuildConfig.DEBUG_MODE) Log.w(TAG, "Thread [${Thread.currentThread().name}] Constructor: End") - } catch (ex: SecurityException) { - virtualDisplay = null - imageReaderState = STATE_ERROR - globalStatus.isStreamRunning.set(true) - eventBus.sendEvent(EventBus.GlobalEvent.StreamStatus()) - eventBus.sendEvent(EventBus.GlobalEvent.Error(ex)) - if (BuildConfig.DEBUG_MODE) Log.e(TAG, "Thread [${Thread.currentThread().name}] $ex") - } +// try { + virtualDisplay = mediaProjection.createVirtualDisplay("ScreenStreamVirtualDisplay", + screenSize.x, screenSize.y, displayMetrics.densityDpi, + DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, imageReader.surface, null, null) + + subscriptions.add(Observable.interval(250, TimeUnit.MILLISECONDS) + .map { _ -> windowManager.defaultDisplay.rotation } + .map { rotation -> rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 } + .distinctUntilChanged() + .skip(1) + .filter { _ -> STATE_STARTED == imageReaderState } + .subscribe { _ -> restart() } + ) + + imageReaderState = STATE_STARTED + globalStatus.isStreamRunning.set(true) + eventBus.sendEvent(EventBus.GlobalEvent.StreamStatus()) + if (BuildConfig.DEBUG_MODE) Log.w(TAG, "Thread [${Thread.currentThread().name}] Constructor: End") +// } catch (ex: SecurityException) { +// virtualDisplay = null +// imageReaderState = STATE_ERROR +// globalStatus.isStreamRunning.set(true) +// eventBus.sendEvent(EventBus.GlobalEvent.StreamStatus()) +// eventBus.sendEvent(EventBus.GlobalEvent.Error(ex)) +// if (BuildConfig.DEBUG_MODE) Log.e(TAG, "Thread [${Thread.currentThread().name}] $ex") +// } } override fun stop() { @@ -175,18 +175,18 @@ class ImageGeneratorImpl(context: Context, imageReader = ImageReader.newInstance(screenSize.x, screenSize.y, PixelFormat.RGBA_8888, 2) imageReader.setOnImageAvailableListener(listener, imageThreadHandler) - try { - virtualDisplay = mediaProjection.createVirtualDisplay("SSVirtualDisplay", - screenSize.x, screenSize.y, displayMetrics.densityDpi, - DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, imageReader.surface, null, null) - - if (BuildConfig.DEBUG_MODE) Log.w(TAG, "Thread [${Thread.currentThread().name}] Restart: End") - } catch (ex: SecurityException) { - imageReaderState = STATE_ERROR - eventBus.sendEvent(EventBus.GlobalEvent.Error(ex)) - virtualDisplay = null - if (BuildConfig.DEBUG_MODE) Log.e(TAG, "Thread [${Thread.currentThread().name}] $ex") - } +// try { + virtualDisplay = mediaProjection.createVirtualDisplay("SSVirtualDisplay", + screenSize.x, screenSize.y, displayMetrics.densityDpi, + DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, imageReader.surface, null, null) + + if (BuildConfig.DEBUG_MODE) Log.w(TAG, "Thread [${Thread.currentThread().name}] Restart: End") +// } catch (ex: SecurityException) { +// imageReaderState = STATE_ERROR +// eventBus.sendEvent(EventBus.GlobalEvent.Error(ex)) +// virtualDisplay = null +// if (BuildConfig.DEBUG_MODE) Log.e(TAG, "Thread [${Thread.currentThread().name}] $ex") +// } } } diff --git a/app/src/main/java/info/dvkr/screenstream/presenter/StartActivityPresenter.kt b/app/src/main/java/info/dvkr/screenstream/presenter/StartActivityPresenter.kt index ce7400a6..2ce2cfd9 100644 --- a/app/src/main/java/info/dvkr/screenstream/presenter/StartActivityPresenter.kt +++ b/app/src/main/java/info/dvkr/screenstream/presenter/StartActivityPresenter.kt @@ -39,14 +39,14 @@ class StartActivityPresenter @Inject internal constructor(private val eventSched // Sending message to StartActivity is StartActivityView.FromEvent.TryStartStream -> { + if (globalStatus.isStreamRunning.get()) return@subscribe globalStatus.error.set(null) - if (globalStatus.isStreamRunning.get()) throw IllegalStateException("Stream already running") startActivity?.toEvent(StartActivityView.ToEvent.TryToStart()) } // Relaying message to ForegroundServicePresenter is StartActivityView.FromEvent.StopStream -> { - if (!globalStatus.isStreamRunning.get()) throw IllegalStateException("Stream not running") + if (!globalStatus.isStreamRunning.get()) return@subscribe eventBus.sendEvent(EventBus.GlobalEvent.StopStream()) } diff --git a/app/src/main/java/info/dvkr/screenstream/service/ForegroundService.kt b/app/src/main/java/info/dvkr/screenstream/service/ForegroundService.kt index 84b78b57..070d1c8d 100644 --- a/app/src/main/java/info/dvkr/screenstream/service/ForegroundService.kt +++ b/app/src/main/java/info/dvkr/screenstream/service/ForegroundService.kt @@ -293,11 +293,10 @@ class ForegroundService : Service(), ForegroundServiceView { if (BuildConfig.DEBUG_MODE) Log.w(TAG, "Thread [${Thread.currentThread().name}] stopMediaProjection") mediaProjection?.apply { projectionCallback?.let { unregisterCallback(it) } - stop() } + imageGenerator?.stop() projectionCallback = null mediaProjection = null - imageGenerator?.stop() imageGenerator = null } diff --git a/app/src/main/java/info/dvkr/screenstream/ui/ClientsActivity.kt b/app/src/main/java/info/dvkr/screenstream/ui/ClientsActivity.kt index 31cd1dff..6e659a40 100644 --- a/app/src/main/java/info/dvkr/screenstream/ui/ClientsActivity.kt +++ b/app/src/main/java/info/dvkr/screenstream/ui/ClientsActivity.kt @@ -35,7 +35,7 @@ class ClientsActivity : BaseActivity(), ClientsActivityView { @Inject internal lateinit var presenter: ClientsActivityPresenter private val fromEvents = PublishSubject.create() - private lateinit var lineGraphSeries: LineGraphSeries + private var lineGraphSeries: LineGraphSeries? = null override fun fromEvent(): Observable = fromEvents.asObservable() @@ -66,11 +66,13 @@ class ClientsActivity : BaseActivity(), ClientsActivityView { textViewCurrentTraffic.text = getString(R.string.clients_activity_current_traffic).format(toMbit(event.trafficHistory.last().bytes)) val arrayOfDataPoints = event.trafficHistory.map { DataPoint(it.time.toDouble(), toMbit(it.bytes)) }.toTypedArray() - lineGraphSeries = LineGraphSeries(arrayOfDataPoints) - lineGraphSeries.color = ContextCompat.getColor(this, R.color.colorAccent) - lineGraphSeries.thickness = 6 lineChartTraffic.removeAllSeries() - lineChartTraffic.addSeries(lineGraphSeries) + lineGraphSeries = LineGraphSeries(arrayOfDataPoints) + lineGraphSeries?.apply { + color = ContextCompat.getColor(this@ClientsActivity, R.color.colorAccent) + thickness = 6 + lineChartTraffic.addSeries(lineGraphSeries) + } lineChartTraffic.viewport.isXAxisBoundsManual = true lineChartTraffic.viewport.setMinX(arrayOfDataPoints[0].x) lineChartTraffic.viewport.setMaxX(arrayOfDataPoints[arrayOfDataPoints.size - 1].x) @@ -90,12 +92,14 @@ class ClientsActivity : BaseActivity(), ClientsActivityView { } is ClientsActivityView.ToEvent.TrafficPoint -> { - val mbit = toMbit(event.trafficPoint.bytes) - textViewCurrentTraffic.text = getString(R.string.start_activity_current_traffic).format(mbit) - lineGraphSeries.appendData(DataPoint(event.trafficPoint.time.toDouble(), mbit), true, 60) - val maxY = Math.max(toMbit(event.maxY) * 1.2, 1.1) - lineChartTraffic.viewport.setMinY(maxY * -0.1) - lineChartTraffic.viewport.setMaxY(maxY) + lineGraphSeries?.let { + val mbit = toMbit(event.trafficPoint.bytes) + textViewCurrentTraffic.text = getString(R.string.start_activity_current_traffic).format(mbit) + it.appendData(DataPoint(event.trafficPoint.time.toDouble(), mbit), true, 60) + val maxY = Math.max(toMbit(event.maxY) * 1.2, 1.1) + lineChartTraffic.viewport.setMinY(maxY * -0.1) + lineChartTraffic.viewport.setMaxY(maxY) + } } } } diff --git a/app/src/main/java/info/dvkr/screenstream/ui/StartActivity.kt b/app/src/main/java/info/dvkr/screenstream/ui/StartActivity.kt index 5c31dd88..529ad6e2 100644 --- a/app/src/main/java/info/dvkr/screenstream/ui/StartActivity.kt +++ b/app/src/main/java/info/dvkr/screenstream/ui/StartActivity.kt @@ -64,7 +64,6 @@ class StartActivity : BaseActivity(), StartActivityView { private val fromEvents = PublishSubject.create() private lateinit var drawer: Drawer private var canStart: Boolean = true - private var isRunning: Boolean = false override fun fromEvent(): Observable = fromEvents.asObservable() @@ -80,7 +79,6 @@ class StartActivity : BaseActivity(), StartActivityView { is StartActivityView.ToEvent.OnStreamStartStop -> { setStreamRunning(event.running) - Crashlytics.log(1, "StartActivityView.ToEvent.OnStreamStartStop", "isRunning=$isRunning") if (event.running && settings.minimizeOnStream) startActivity(Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) } @@ -88,10 +86,7 @@ class StartActivity : BaseActivity(), StartActivityView { is StartActivityView.ToEvent.ResizeFactor -> showResizeFactor(event.value) is StartActivityView.ToEvent.EnablePin -> showEnablePin(event.value) is StartActivityView.ToEvent.SetPin -> textViewPinValue.text = event.value - is StartActivityView.ToEvent.StreamRunning -> { - setStreamRunning(event.running) - Crashlytics.log(1, "StartActivityView.ToEvent.StreamRunning", "isRunning=$isRunning") - } + is StartActivityView.ToEvent.StreamRunning -> setStreamRunning(event.running) is StartActivityView.ToEvent.Error -> { canStart = true @@ -156,20 +151,20 @@ class StartActivity : BaseActivity(), StartActivityView { supportActionBar?.setTitle(R.string.start_activity_name) startService(ForegroundService.getIntent(applicationContext, ForegroundService.ACTION_INIT)) - + toggleButtonStartStop.isEnabled = false + textViewConnectedClients.text = getString(R.string.start_activity_connected_clients).format(0) + textViewCurrentTraffic.text = getString(R.string.start_activity_current_traffic).format(0f) presenter.attach(this) toggleButtonStartStop.setOnClickListener { _ -> if (toggleButtonStartStop.isChecked) { - toggleButtonStartStop.isChecked = isRunning + toggleButtonStartStop.isChecked = false if (!canStart) return@setOnClickListener toggleButtonStartStop.isEnabled = false - Crashlytics.log(1, "StartActivityView.FromEvent.TryStartStreamm", "setOnClickListener;isRunning=$isRunning") fromEvents.onNext(StartActivityView.FromEvent.TryStartStream()) } else { - toggleButtonStartStop.isChecked = isRunning + toggleButtonStartStop.isChecked = true toggleButtonStartStop.isEnabled = false - Crashlytics.log(1, "StartActivityView.FromEvent.StopStream", "setOnClickListener;isRunning=$isRunning") fromEvents.onNext(StartActivityView.FromEvent.StopStream()) } } @@ -242,19 +237,18 @@ class StartActivity : BaseActivity(), StartActivityView { if (BuildConfig.DEBUG_MODE) Log.w(TAG, "Thread [${Thread.currentThread().name}] onNewIntent: action = $action") if (null == action) return + intent.removeExtra(EXTRA_DATA) + this.intent = intent + when (action) { ACTION_START_STREAM -> { if (!canStart) return - toggleButtonStartStop.isChecked = isRunning toggleButtonStartStop.isEnabled = false - Crashlytics.log(1, "StartActivityView.FromEvent.TryStartStreamm", "ACTION_START_STREAM;isRunning=$isRunning") fromEvents.onNext(StartActivityView.FromEvent.TryStartStream()) } ACTION_STOP_STREAM -> { - toggleButtonStartStop.isChecked = isRunning toggleButtonStartStop.isEnabled = false - Crashlytics.log(1, "StartActivityView.FromEvent.StopStream", "ACTION_STOP_STREAM;isRunning=$isRunning") fromEvents.onNext(StartActivityView.FromEvent.StopStream()) } @@ -318,11 +312,10 @@ class StartActivity : BaseActivity(), StartActivityView { // Private methods private fun setStreamRunning(running: Boolean) { - isRunning = running - toggleButtonStartStop.isChecked = isRunning + toggleButtonStartStop.isChecked = running toggleButtonStartStop.isEnabled = true if (settings.enablePin) { - if (isRunning && settings.hidePinOnStart) textViewPinValue.setText(R.string.start_activity_pin_asterisks) + if (running && settings.hidePinOnStart) textViewPinValue.setText(R.string.start_activity_pin_asterisks) else textViewPinValue.text = settings.currentPin } }