diff --git a/app/src/main/java/net/christianbeier/droidvnc_ng/MainService.java b/app/src/main/java/net/christianbeier/droidvnc_ng/MainService.java index 9ab71ba..f29ceac 100644 --- a/app/src/main/java/net/christianbeier/droidvnc_ng/MainService.java +++ b/app/src/main/java/net/christianbeier/droidvnc_ng/MainService.java @@ -21,6 +21,7 @@ package net.christianbeier.droidvnc_ng; +import android.Manifest; import android.annotation.SuppressLint; import android.app.Notification; import android.app.NotificationChannel; @@ -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; @@ -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(); } } @@ -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())) { @@ -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())) { @@ -547,6 +468,93 @@ public int onStartCommand(Intent intent, int flags, int startId) 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) { diff --git a/app/src/main/java/net/christianbeier/droidvnc_ng/NotificationRequestActivity.java b/app/src/main/java/net/christianbeier/droidvnc_ng/NotificationRequestActivity.java index 65a6b4b..10858d2 100644 --- a/app/src/main/java/net/christianbeier/droidvnc_ng/NotificationRequestActivity.java +++ b/app/src/main/java/net/christianbeier/droidvnc_ng/NotificationRequestActivity.java @@ -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 diff --git a/app/src/main/java/net/christianbeier/droidvnc_ng/WriteStorageRequestActivity.java b/app/src/main/java/net/christianbeier/droidvnc_ng/WriteStorageRequestActivity.java index e36622e..e26cc84 100644 --- a/app/src/main/java/net/christianbeier/droidvnc_ng/WriteStorageRequestActivity.java +++ b/app/src/main/java/net/christianbeier/droidvnc_ng/WriteStorageRequestActivity.java @@ -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) {