Skip to content

Commit

Permalink
Workflow optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
dkrivoruchko committed Aug 29, 2016
1 parent c83f3e3 commit 19d75ac
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 197 deletions.
38 changes: 12 additions & 26 deletions app/src/main/java/info/dvkr/screenstream/AppContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Locale;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentLinkedQueue;

import static info.dvkr.screenstream.ForegroundService.SERVICE_MESSAGE;
import static info.dvkr.screenstream.ForegroundService.SERVICE_MESSAGE_PREPARE_STREAMING;
Expand All @@ -25,6 +23,7 @@
public class AppContext extends Application {
private static AppContext instance;

private final AppViewState appViewState = new AppViewState();
private final AppState appState = new AppState();
private AppSettings appSettings;
private WindowManager windowManager;
Expand All @@ -33,11 +32,6 @@ public class AppContext extends Application {
private String pinRequestHTMLPage;
private byte[] iconBytes;

private final ConcurrentLinkedDeque<byte[]> JPEGQueue = new ConcurrentLinkedDeque<>();
private final ConcurrentLinkedQueue<Client> clientQueue = new ConcurrentLinkedQueue<>();

private volatile boolean isStreamRunning;

@Override
public void onCreate() {
super.onCreate();
Expand All @@ -48,11 +42,11 @@ public void onCreate() {
appSettings.generateAndSaveNewPin();
}

appState.serverAddress.set(getServerAddress());
appState.pinEnabled.set(appSettings.isEnablePin());
appState.pinAutoHide.set(appSettings.isPinAutoHide());
appState.streamPin.set(appSettings.getUserPin());
appState.wifiConnected.set(isWiFiConnected());
appViewState.serverAddress.set(getServerAddress());
appViewState.pinEnabled.set(appSettings.isEnablePin());
appViewState.pinAutoHide.set(appSettings.isPinAutoHide());
appViewState.streamPin.set(appSettings.getUserPin());
appViewState.wifiConnected.set(isWiFiConnected());

windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
densityDPI = getDensityDPI();
Expand All @@ -70,6 +64,10 @@ public void onCreate() {
.putExtra(SERVICE_MESSAGE, SERVICE_MESSAGE_PREPARE_STREAMING));
}

static AppViewState getAppViewState() {
return instance.appViewState;
}

static AppState getAppState() {
return instance.appState;
}
Expand All @@ -96,13 +94,9 @@ static Point getScreenSize() {
return screenSize;
}

static boolean isStreamRunning() {
return instance.isStreamRunning;
}

static void setIsStreamRunning(final boolean isRunning) {
instance.isStreamRunning = isRunning;
getAppState().streaming.set(isRunning);
instance.appState.isStreamRunning = isRunning;
getAppViewState().streaming.set(isRunning);
}

static String getIndexHTMLPage(final String streamAddress) {
Expand All @@ -122,14 +116,6 @@ static String getServerAddress() {
return "http://" + instance.getIPAddress() + ":" + instance.appSettings.getSeverPort();
}

static ConcurrentLinkedDeque<byte[]> getJPEGQueue() {
return instance.JPEGQueue;
}

static ConcurrentLinkedQueue<Client> getClientQueue() {
return instance.clientQueue;
}

static boolean isWiFiConnected() {
final WifiManager wifi = (WifiManager) instance.getSystemService(Context.WIFI_SERVICE);
return wifi.getConnectionInfo().getIpAddress() > 0;
Expand Down
19 changes: 7 additions & 12 deletions app/src/main/java/info/dvkr/screenstream/AppState.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package info.dvkr.screenstream;

import android.databinding.ObservableBoolean;
import android.databinding.ObservableField;
import android.databinding.ObservableInt;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentLinkedQueue;

public final class AppState {
public final ObservableField<String> serverAddress = new ObservableField<>();
public final ObservableBoolean pinEnabled = new ObservableBoolean();
public final ObservableBoolean pinAutoHide = new ObservableBoolean();
public final ObservableField<String> streamPin = new ObservableField<>();
public final ObservableBoolean streaming = new ObservableBoolean();
public final ObservableBoolean wifiConnected = new ObservableBoolean();
public final ObservableBoolean httpServerError = new ObservableBoolean();
public final ObservableInt clients = new ObservableInt();
class AppState {
final ConcurrentLinkedDeque<byte[]> JPEGQueue = new ConcurrentLinkedDeque<>();
final ConcurrentLinkedQueue<Client> clientQueue = new ConcurrentLinkedQueue<>();
volatile boolean isStreamRunning;
volatile int httpServerStatus = HTTPServer.SERVER_STATUS_UNKNOWN;
}
16 changes: 16 additions & 0 deletions app/src/main/java/info/dvkr/screenstream/AppViewState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package info.dvkr.screenstream;

import android.databinding.ObservableBoolean;
import android.databinding.ObservableField;
import android.databinding.ObservableInt;

public final class AppViewState {
public final ObservableField<String> serverAddress = new ObservableField<>();
public final ObservableBoolean pinEnabled = new ObservableBoolean();
public final ObservableBoolean pinAutoHide = new ObservableBoolean();
public final ObservableField<String> streamPin = new ObservableField<>();
public final ObservableBoolean streaming = new ObservableBoolean();
public final ObservableBoolean wifiConnected = new ObservableBoolean();
public final ObservableBoolean httpServerError = new ObservableBoolean();
public final ObservableInt clients = new ObservableInt();
}
4 changes: 2 additions & 2 deletions app/src/main/java/info/dvkr/screenstream/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ private void closeSocket() {
} catch (IOException e) {
FirebaseCrash.report(e);
}
AppContext.getClientQueue().remove(Client.this);
AppContext.getAppState().clients.set(AppContext.getClientQueue().size());
AppContext.getAppState().clientQueue.remove(Client.this);
AppContext.getAppViewState().clients.set(AppContext.getAppState().clientQueue.size());
}


Expand Down
134 changes: 64 additions & 70 deletions app/src/main/java/info/dvkr/screenstream/ForegroundService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;

import java.util.concurrent.ConcurrentLinkedQueue;

import static info.dvkr.screenstream.AppContext.getAppSettings;
import static info.dvkr.screenstream.AppContext.getAppState;
import static info.dvkr.screenstream.AppContext.getAppViewState;
import static info.dvkr.screenstream.AppContext.getServerAddress;
import static info.dvkr.screenstream.AppContext.isWiFiConnected;

public final class ForegroundService extends Service {
private static ForegroundService foregroundService;

Expand All @@ -27,15 +35,12 @@ public final class ForegroundService extends Service {
private ImageGenerator imageGenerator;
private ForegroundTaskHandler foregroundServiceTaskHandler;

private int httpServerStatus = HTTPServer.SERVER_STATUS_UNKNOWN;

// Fields for broadcast
static final String SERVICE_ACTION = "info.dvkr.screenstream.ForegroundService.SERVICE_ACTION";
static final String SERVICE_PERMISSION = "info.dvkr.screenstream.RECEIVE_BROADCAST";
static final String SERVICE_MESSAGE = "SERVICE_MESSAGE";
static final int SERVICE_MESSAGE_EMPTY = 0;
static final int SERVICE_MESSAGE_HAS_NEW = 1;
static final int SERVICE_MESSAGE_GET_CURRENT = 11;
static final int SERVICE_MESSAGE_PREPARE_STREAMING = 110;
static final int SERVICE_MESSAGE_START_STREAMING = 111;
static final int SERVICE_MESSAGE_STOP_STREAMING = 112;
Expand All @@ -46,7 +51,7 @@ public final class ForegroundService extends Service {
static final int SERVICE_MESSAGE_IMAGE_GENERATOR_ERROR = 4000;
static final int SERVICE_MESSAGE_EXIT = 9000;

private int currentServiceMessage;
private ConcurrentLinkedQueue<Integer> serviceMessages = new ConcurrentLinkedQueue<>();

// Fields for notifications
private BroadcastReceiver localNotificationReceiver;
Expand All @@ -59,31 +64,33 @@ public final class ForegroundService extends Service {

private BroadcastReceiver broadcastReceiver;

static MediaProjectionManager getProjectionManager() {
return foregroundService.projectionManager;
}

static void setMediaProjection(final MediaProjection mediaProjection) {
foregroundService.mediaProjection = mediaProjection;
}

@Nullable
static MediaProjectionManager getProjectionManager() {
return foregroundService == null ? null : foregroundService.projectionManager;
}

@Nullable
static MediaProjection getMediaProjection() {
return foregroundService.mediaProjection;
return foregroundService == null ? null : foregroundService.mediaProjection;
}

@Nullable
static ImageGenerator getImageGenerator() {
return foregroundService.imageGenerator;
return foregroundService == null ? null : foregroundService.imageGenerator;
}

static int getHttpServerStatus() {
if (foregroundService == null) return HTTPServer.SERVER_STATUS_UNKNOWN;
return foregroundService.httpServerStatus;
@Nullable
static ConcurrentLinkedQueue<Integer> getServiceMessages() {
return foregroundService == null ? null : foregroundService.serviceMessages;
}

static void errorInImageGenerator() {
foregroundService.currentServiceMessage = SERVICE_MESSAGE_IMAGE_GENERATOR_ERROR;
foregroundService.relayMessageViaActivity();
if (foregroundService != null)
foregroundService.relayMessageViaActivity(SERVICE_MESSAGE_IMAGE_GENERATOR_ERROR);
}

@Override
Expand All @@ -99,6 +106,7 @@ public void onStop() {
};
httpServer = new HTTPServer();
imageGenerator = new ImageGenerator();
imageGenerator.addDefaultScreen(getApplicationContext());

// Starting thread Handler
final HandlerThread looperThread = new HandlerThread(ForegroundService.class.getSimpleName(), Process.THREAD_PRIORITY_MORE_FAVORABLE);
Expand All @@ -114,70 +122,61 @@ public void onStop() {
localNotificationReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(KEY_START)) {
currentServiceMessage = SERVICE_MESSAGE_START_STREAMING;
relayMessageViaActivity();
}

if (intent.getAction().equals(KEY_STOP)) {
currentServiceMessage = SERVICE_MESSAGE_STOP_STREAMING;
relayMessageViaActivity();
}

if (intent.getAction().equals(KEY_CLOSE)) {
currentServiceMessage = SERVICE_MESSAGE_EXIT;
relayMessageViaActivity();
final String action = intent.getAction();
switch (action) {
case KEY_START:
relayMessageViaActivity(SERVICE_MESSAGE_START_STREAMING);
break;
case KEY_STOP:
relayMessageViaActivity(SERVICE_MESSAGE_STOP_STREAMING);
break;
case KEY_CLOSE:
relayMessageViaActivity(SERVICE_MESSAGE_EXIT);
break;
}
}
};

registerReceiver(localNotificationReceiver, localNotificationIntentFilter);

// Registering receiver for screen off messages
final IntentFilter screenOnOffFilter = new IntentFilter();
screenOnOffFilter.addAction(Intent.ACTION_SCREEN_OFF);
screenOnOffFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
// Registering receiver for screen off messages and WiFi changes
final IntentFilter screenOnOffAndWiFiFilter = new IntentFilter();
screenOnOffAndWiFiFilter.addAction(Intent.ACTION_SCREEN_OFF);
screenOnOffAndWiFiFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);

broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (AppContext.getAppSettings().isPauseOnSleep())
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
if (AppContext.isStreamRunning()) {
currentServiceMessage = SERVICE_MESSAGE_STOP_STREAMING;
relayMessageViaActivity();
}

if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
if (AppContext.getAppState().wifiConnected.get() != AppContext.isWiFiConnected()) {
AppContext.getAppState().serverAddress.set(AppContext.getServerAddress());
AppContext.getAppState().wifiConnected.set(AppContext.isWiFiConnected());

if ((!AppContext.getAppState().wifiConnected.get()) && AppContext.isStreamRunning()) {
currentServiceMessage = SERVICE_MESSAGE_STOP_STREAMING;
relayMessageViaActivity();
}
final String action = intent.getAction();
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
if (getAppSettings().isPauseOnSleep() && getAppState().isStreamRunning)
relayMessageViaActivity(SERVICE_MESSAGE_STOP_STREAMING);
}

if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
if (getAppViewState().wifiConnected.get() != isWiFiConnected()) {
getAppViewState().serverAddress.set(getServerAddress());
getAppViewState().wifiConnected.set(isWiFiConnected());

if ((!getAppViewState().wifiConnected.get()) && getAppState().isStreamRunning)
relayMessageViaActivity(SERVICE_MESSAGE_STOP_STREAMING);
}
}
}
};

registerReceiver(broadcastReceiver, screenOnOffFilter);
imageGenerator.addDefaultScreen(getApplicationContext());
registerReceiver(broadcastReceiver, screenOnOffAndWiFiFilter);
httpServerStartAndCheck();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
final int messageFromActivity = intent.getIntExtra(SERVICE_MESSAGE, 0);

final int messageFromActivity = intent.getIntExtra(SERVICE_MESSAGE, SERVICE_MESSAGE_EMPTY);
// Log.wtf(">>>>>>>>>>> messageFromActivity", "" + messageFromActivity);
switch (messageFromActivity) {
case SERVICE_MESSAGE_PREPARE_STREAMING:
startForeground(110, getNotificationStart());
break;
case SERVICE_MESSAGE_GET_CURRENT:
serviceGetCurrentMessage();
break;
case SERVICE_MESSAGE_START_STREAMING:
serviceStartStreaming();
break;
Expand All @@ -201,12 +200,6 @@ private void serviceStartStreaming() {
if (mediaProjection != null) mediaProjection.registerCallback(projectionCallback, null);
}

private void serviceGetCurrentMessage() {
if (currentServiceMessage == SERVICE_MESSAGE_EMPTY) return;
sendBroadcast(new Intent(SERVICE_ACTION).putExtra(SERVICE_MESSAGE, currentServiceMessage), SERVICE_PERMISSION);
currentServiceMessage = SERVICE_MESSAGE_EMPTY;
}

private void serviceStopStreaming() {
stopForeground(true);
foregroundServiceTaskHandler.obtainMessage(ForegroundTaskHandler.HANDLER_STOP_STREAMING).sendToTarget();
Expand All @@ -227,21 +220,22 @@ private void serviceUpdatePinStatus() {
httpServerStartAndCheck();
}

private void relayMessageViaActivity() {
private void relayMessageViaActivity(final int message) {
if (message == SERVICE_MESSAGE_EMPTY) return;
serviceMessages.add(message);
startActivity(new Intent(this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
sendBroadcast(new Intent(SERVICE_ACTION).putExtra(SERVICE_MESSAGE, SERVICE_MESSAGE_HAS_NEW), SERVICE_PERMISSION);
}

private void httpServerStartAndCheck() {
httpServerStatus = httpServer.start();
if (httpServerStatus == HTTPServer.SERVER_ERROR_PORT_IN_USE) {
currentServiceMessage = SERVICE_MESSAGE_HTTP_PORT_IN_USE;
AppContext.getAppState().httpServerError.set(true);
AppContext.getAppState().httpServerStatus = httpServer.start();
if (AppContext.getAppState().httpServerStatus == HTTPServer.SERVER_ERROR_PORT_IN_USE) {
getAppViewState().httpServerError.set(true);
relayMessageViaActivity(SERVICE_MESSAGE_HTTP_PORT_IN_USE);
} else {
currentServiceMessage = SERVICE_MESSAGE_HTTP_OK;
AppContext.getAppState().httpServerError.set(false);
getAppViewState().httpServerError.set(false);
relayMessageViaActivity(SERVICE_MESSAGE_HTTP_OK);
}
relayMessageViaActivity();
}

@Override
Expand Down Expand Up @@ -280,7 +274,7 @@ private Notification getNotificationStop() {
stopNotificationBuilder.setSmallIcon(R.drawable.ic_cast_http_24dp);
stopNotificationBuilder.setColor(ContextCompat.getColor(this, R.color.colorPrimaryDark));
stopNotificationBuilder.setContentTitle(getString(R.string.stream));
stopNotificationBuilder.setContentText(getString(R.string.go_to) + AppContext.getServerAddress());
stopNotificationBuilder.setContentText(getString(R.string.go_to) + getServerAddress());
stopNotificationBuilder.setContentIntent(pendingMainActivityIntent);
stopNotificationBuilder.addAction(R.drawable.ic_stop_24dp, getString(R.string.stop).toUpperCase(), PendingIntent.getBroadcast(this, 0, stopStreamIntent, 0));
stopNotificationBuilder.setPriority(NotificationCompat.PRIORITY_MAX);
Expand Down
Loading

0 comments on commit 19d75ac

Please sign in to comment.