Skip to content

Refactor MainService to prevent unnecessary activity starts #243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 105 additions & 85 deletions app/src/main/java/net/christianbeier/droidvnc_ng/MainService.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

package net.christianbeier.droidvnc_ng;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
Expand All @@ -31,6 +32,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.net.ConnectivityManager;
import android.net.Network;
Expand Down Expand Up @@ -337,32 +339,7 @@ public int onStartCommand(Intent intent, int flags, int startId)
stopScreenCapture();
startScreenCapture();
} else {
DisplayMetrics displayMetrics = Utils.getDisplayMetrics(this, Display.DEFAULT_DISPLAY);
int port = PreferenceManager.getDefaultSharedPreferences(this).getInt(PREFS_KEY_SERVER_LAST_PORT, mDefaults.getPort());
// get device name
String name = Utils.getDeviceName(this);

boolean status = vncStartServer(displayMetrics.widthPixels,
displayMetrics.heightPixels,
port,
name,
PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_PASSWORD, mDefaults.getPassword()),
getFilesDir().getAbsolutePath() + File.separator + "novnc");
Intent answer = new Intent(ACTION_START);
answer.putExtra(EXTRA_REQUEST_ID, PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_START_REQUEST_ID, null));
answer.putExtra(EXTRA_REQUEST_SUCCESS, status);
sendBroadcastToOthersAndUs(answer);

if (status) {
startScreenCapture();
registerNSD(name, port);
updateNotification();
// if we got here, we want to restart if we were killed
return START_REDELIVER_INTENT;
} else {
stopSelfByUs();
return START_NOT_STICKY;
}
return step4StartCapture();
}
}

Expand All @@ -378,64 +355,14 @@ public int onStartCommand(Intent intent, int flags, int startId)
// or ask for capturing permission first (then going in step 4)
}

if (mResultCode != 0 && mResultData != null
|| (Build.VERSION.SDK_INT >= 30 && PreferenceManager.getDefaultSharedPreferences(this).getBoolean(PREFS_KEY_SERVER_LAST_FALLBACK_SCREEN_CAPTURE, false))) {
DisplayMetrics displayMetrics = Utils.getDisplayMetrics(this, Display.DEFAULT_DISPLAY);
int port = PreferenceManager.getDefaultSharedPreferences(this).getInt(PREFS_KEY_SERVER_LAST_PORT, mDefaults.getPort());
String name = Utils.getDeviceName(this);
boolean status = vncStartServer(displayMetrics.widthPixels,
displayMetrics.heightPixels,
port,
name,
PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_PASSWORD, mDefaults.getPassword()),
getFilesDir().getAbsolutePath() + File.separator + "novnc");

Intent answer = new Intent(ACTION_START);
answer.putExtra(EXTRA_REQUEST_ID, PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_START_REQUEST_ID, null));
answer.putExtra(EXTRA_REQUEST_SUCCESS, status);
sendBroadcastToOthersAndUs(answer);

if(status) {
startScreenCapture();
registerNSD(name, port);
updateNotification();
// if we got here, we want to restart if we were killed
return START_REDELIVER_INTENT;
} else {
stopSelfByUs();
return START_NOT_STICKY;
}
} else {
Log.i(TAG, "Requesting confirmation");
// This initiates a prompt dialog for the user to confirm screen projection.
Intent mediaProjectionRequestIntent = new Intent(this, MediaProjectionRequestActivity.class);
mediaProjectionRequestIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(mediaProjectionRequestIntent);
// if screen capturing was not started, we don't want a restart if we were killed
// especially, we don't want the permission asking to replay.
return START_NOT_STICKY;
}
return step3RequestProjectionPermission();
}

if(ACTION_HANDLE_INPUT_RESULT.equals(intent.getAction())) {
Log.d(TAG, "onStartCommand: handle input result");
// Step 2: coming back from input permission check, now setup InputService and ask for write storage permission or notification permission
InputService.isInputEnabled = intent.getBooleanExtra(EXTRA_INPUT_RESULT, false);
if(Build.VERSION.SDK_INT < 33) {
Intent writeStorageRequestIntent = new Intent(this, WriteStorageRequestActivity.class);
writeStorageRequestIntent.putExtra(
EXTRA_FILE_TRANSFER,
PreferenceManager.getDefaultSharedPreferences(this).getBoolean(PREFS_KEY_SERVER_LAST_FILE_TRANSFER, mDefaults.getFileTransfer()));
writeStorageRequestIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(writeStorageRequestIntent);
} else {
Intent notificationRequestIntent = new Intent(this, NotificationRequestActivity.class);
notificationRequestIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(notificationRequestIntent);
}
// if screen capturing was not started, we don't want a restart if we were killed
// especially, we don't want the permission asking to replay.
return START_NOT_STICKY;
return step2RequestStorageOrNotifications();
}

if(ACTION_START.equals(intent.getAction())) {
Expand Down Expand Up @@ -468,13 +395,7 @@ public int onStartCommand(Intent intent, int flags, int startId)
InputService.scaling = PreferenceManager.getDefaultSharedPreferences(this).getFloat(Constants.PREFS_KEY_SERVER_LAST_SCALING, new Defaults(this).getScaling());

// Step 1: check input/start-on-boot permission
Intent inputRequestIntent = new Intent(this, InputRequestActivity.class);
inputRequestIntent.putExtra(EXTRA_VIEW_ONLY, intent.getBooleanExtra(EXTRA_VIEW_ONLY, mDefaults.getViewOnly()));
inputRequestIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(inputRequestIntent);
// if screen capturing was not started, we don't want a restart if we were killed
// especially, we don't want the permission asking to replay.
return START_NOT_STICKY;
return step1ConnectInputService(intent.getBooleanExtra(EXTRA_VIEW_ONLY, mDefaults.getViewOnly()));
}

if(ACTION_STOP.equals(intent.getAction())) {
Expand Down Expand Up @@ -506,6 +427,10 @@ public int onStartCommand(Intent intent, int flags, int startId)
}).start();
} else {
stopSelfByUs();
Intent answer = new Intent(ACTION_CONNECT_REVERSE);
answer.putExtra(EXTRA_REQUEST_ID, intent.getStringExtra(EXTRA_REQUEST_ID));
answer.putExtra(EXTRA_REQUEST_SUCCESS, false);
sendBroadcastToOthersAndUs(answer);
}

return START_NOT_STICKY;
Expand Down Expand Up @@ -534,6 +459,10 @@ public int onStartCommand(Intent intent, int flags, int startId)
}).start();
} else {
stopSelfByUs();
Intent answer = new Intent(ACTION_CONNECT_REPEATER);
answer.putExtra(EXTRA_REQUEST_ID, intent.getStringExtra(EXTRA_REQUEST_ID));
answer.putExtra(EXTRA_REQUEST_SUCCESS, false);
sendBroadcastToOthersAndUs(answer);
}

return START_NOT_STICKY;
Expand All @@ -543,10 +472,101 @@ public int onStartCommand(Intent intent, int flags, int startId)
if(!vncIsActive()) {
stopSelfByUs();
}
Intent answer = new Intent(intent.getAction());
answer.putExtra(EXTRA_REQUEST_ID, intent.getStringExtra(EXTRA_REQUEST_ID));
answer.putExtra(EXTRA_REQUEST_SUCCESS, false);
sendBroadcastToOthersAndUs(answer);

return START_NOT_STICKY;
}

private int step1ConnectInputService(boolean viewOnly) {
if (!InputService.isConnected()) {
Intent inputRequestIntent = new Intent(this, InputRequestActivity.class);
inputRequestIntent.putExtra(EXTRA_VIEW_ONLY, viewOnly);
inputRequestIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(inputRequestIntent);
// if screen capturing was not started, we don't want a restart if we were killed
// especially, we don't want the permission asking to replay.
return START_NOT_STICKY;
} else {
InputService.isInputEnabled = true;
return step2RequestStorageOrNotifications();
}
}

private int step2RequestStorageOrNotifications() {
if (Build.VERSION.SDK_INT < 33) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
!PreferenceManager.getDefaultSharedPreferences(this).getBoolean(WriteStorageRequestActivity.PREFS_KEY_PERMISSION_ASKED_BEFORE, false)) {
Intent writeStorageRequestIntent = new Intent(this, WriteStorageRequestActivity.class);
writeStorageRequestIntent.putExtra(
EXTRA_FILE_TRANSFER,
PreferenceManager.getDefaultSharedPreferences(this).getBoolean(PREFS_KEY_SERVER_LAST_FILE_TRANSFER, mDefaults.getFileTransfer()));
writeStorageRequestIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(writeStorageRequestIntent);
} else {
return step3RequestProjectionPermission();
}
} else {
if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED &&
!PreferenceManager.getDefaultSharedPreferences(this).getBoolean(NotificationRequestActivity.PREFS_KEY_POST_NOTIFICATION_PERMISSION_ASKED_BEFORE, false)) {
Intent notificationRequestIntent = new Intent(this, NotificationRequestActivity.class);
notificationRequestIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(notificationRequestIntent);
} else {
return step3RequestProjectionPermission();
}
}
// if screen capturing was not started, we don't want a restart if we were killed
// especially, we don't want the permission asking to replay.
return START_NOT_STICKY;
}

private int step3RequestProjectionPermission() {
if (mResultCode != 0 && mResultData != null
|| (Build.VERSION.SDK_INT >= 30 && PreferenceManager.getDefaultSharedPreferences(this).getBoolean(PREFS_KEY_SERVER_LAST_FALLBACK_SCREEN_CAPTURE, false))) {
return step4StartCapture();
} else {
Log.i(TAG, "Requesting confirmation");
// This initiates a prompt dialog for the user to confirm screen projection.
Intent mediaProjectionRequestIntent = new Intent(this, MediaProjectionRequestActivity.class);
mediaProjectionRequestIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(mediaProjectionRequestIntent);
// if screen capturing was not started, we don't want a restart if we were killed
// especially, we don't want the permission asking to replay.
return START_NOT_STICKY;
}
}

private int step4StartCapture() {
DisplayMetrics displayMetrics = Utils.getDisplayMetrics(this, Display.DEFAULT_DISPLAY);
int port = PreferenceManager.getDefaultSharedPreferences(this).getInt(PREFS_KEY_SERVER_LAST_PORT, mDefaults.getPort());
String name = Utils.getDeviceName(this);
boolean status = vncStartServer(displayMetrics.widthPixels,
displayMetrics.heightPixels,
port,
name,
PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_PASSWORD, mDefaults.getPassword()),
getFilesDir().getAbsolutePath() + File.separator + "novnc");

Intent answer = new Intent(ACTION_START);
answer.putExtra(EXTRA_REQUEST_ID, PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_START_REQUEST_ID, null));
answer.putExtra(EXTRA_REQUEST_SUCCESS, status);
sendBroadcastToOthersAndUs(answer);

if (status) {
startScreenCapture();
registerNSD(name, port);
updateNotification();
// if we got here, we want to restart if we were killed
return START_REDELIVER_INTENT;
} else {
stopSelfByUs();
return START_NOT_STICKY;
}
}

@SuppressLint("WakelockTimeout")
@SuppressWarnings("unused")
static void onClientConnected(long client) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class NotificationRequestActivity extends AppCompatActivity {

private static final String TAG = "NotificationRequestActivity";
private static final int REQUEST_POST_NOTIFICATION = 45;
private static final String PREFS_KEY_POST_NOTIFICATION_PERMISSION_ASKED_BEFORE = "post_notification_permission_asked_before";
public static final String PREFS_KEY_POST_NOTIFICATION_PERMISSION_ASKED_BEFORE = "post_notification_permission_asked_before";


@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class WriteStorageRequestActivity extends AppCompatActivity {

private static final String TAG = "WriteStorageRequestActivity";
private static final int REQUEST_WRITE_STORAGE = 44;
private static final String PREFS_KEY_PERMISSION_ASKED_BEFORE = "write_storage_permission_asked_before";
public static final String PREFS_KEY_PERMISSION_ASKED_BEFORE = "write_storage_permission_asked_before";

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand Down