Skip to content
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
18 changes: 17 additions & 1 deletion app/src/main/cpp/droidvnc-ng.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ JNIEXPORT jboolean JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncS
}


JNIEXPORT jboolean JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncStartServer(JNIEnv *env, jobject thiz, jint width, jint height, jint port, jstring desktopname, jstring password, jstring httpRootDir) {
JNIEXPORT jboolean JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncStartServer(JNIEnv *env, jobject thiz, jint width, jint height, jstring listenIf, jint port, jstring desktopname, jstring password, jstring httpRootDir) {

int argc = 0;

Expand Down Expand Up @@ -305,6 +305,22 @@ JNIEXPORT jboolean JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncS
theScreen->setXCutTextUTF8 = onCutTextUTF8;
theScreen->newClientHook = onClientConnected;

in_addr_t address = 0; // Default is 0.0.0.0
if (listenIf != NULL) {
const char *cListenInterface = (*env)->GetStringUTFChars(env, listenIf, NULL);
int addrConvSucceded = rfbStringToAddr((char*)cListenInterface, &address);
(*env)->ReleaseStringUTFChars(env, listenIf, cListenInterface);

if (!addrConvSucceded) {
__android_log_print(ANDROID_LOG_ERROR, TAG, "vncStartServer: invalid listen address");
Java_net_christianbeier_droidvnc_1ng_MainService_vncStopServer(env, thiz);
return JNI_FALSE;
}
}


// With the listenInterface property one can define where the server will be available
theScreen->listenInterface = address;
theScreen->port = port;
theScreen->ipv6port = port;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class Constants {
/*
user settings
*/
public static final String PREFS_KEY_SETTINGS_LISTEN_INTERFACE = "settings_listen_interface";
public static final String PREFS_KEY_SETTINGS_PORT = "settings_port";
public static final String PREFS_KEY_SETTINGS_PASSWORD = "settings_password" ;
public static final String PREFS_KEY_SETTINGS_START_ON_BOOT = "settings_start_on_boot" ;
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/net/christianbeier/droidvnc_ng/Defaults.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class Defaults {
private const val PREFS_KEY_DEFAULTS_ACCESS_KEY = "defaults_access_key"
}

@EncodeDefault
var listenInterface = "loopback"
private set

@EncodeDefault
var port = 5900
private set
Expand Down
159 changes: 159 additions & 0 deletions app/src/main/java/net/christianbeier/droidvnc_ng/ListenIfAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* DroidVNC-NG ListenIfAdapter, this is the adapter concrete implementation that is set to the Spinner in the main activity.
*
* Author: elluisian <elluisian@yandex.com>
*
* Copyright (C) 2024 Christian Beier.
*
* You can redistribute and/or modify this program under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place Suite 330, Boston, MA 02111-1307, USA.
*/
package net.christianbeier.droidvnc_ng;


import android.content.res.Resources;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.Spinner;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


import java.util.ArrayList;
import java.util.List;


import net.christianbeier.droidvnc_ng.ifaceutils.NetIfData;
import net.christianbeier.droidvnc_ng.ifaceutils.NetIfDataDecorator;
import net.christianbeier.droidvnc_ng.ifaceutils.NetworkInterfaceTester;



public class ListenIfAdapter extends ArrayAdapter<NetIfData> implements NetworkInterfaceTester.OnNetworkStateChangedListener {
// This adapter uses the ViewHolder pattern
private static class ViewHolder {
public TextView txtLabel;
}

// Data to be shown with the adapter
private List<NetIfDataDecorator> data;
private int dataSize;


// Some context data for "easy retrieval"
private Context mContext;
private LayoutInflater mInflater;


// UI related
private Handler handler;



public ListenIfAdapter(Context context) {
super(context, R.layout.spinner_row, R.id.spinner_text);

this.mContext = context;
this.mInflater = LayoutInflater.from(this.mContext);
this.handler = new Handler(Looper.getMainLooper());

NetworkInterfaceTester nit = NetworkInterfaceTester.getInstance(context);
nit.addOnNetworkStateChangedListener(this);
this.onNetworkStateChanged(nit);
}



public int getItemPositionByOptionId(String optionId) {
int i = 0;
for (NetIfDataDecorator nid : this.data) {
if (nid.getOptionId().equals(optionId)) {
return i;
}
i++;
}

return 1; // return loopback position as default
}



@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return this.handleViewRecreation(position, convertView, parent);
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
return this.handleViewRecreation(position, convertView, parent);
}


private View handleViewRecreation(int position, View convertView, ViewGroup parent) {
if (convertView == null) { // Check if view must be recreated using the famous ViewHolder pattern
convertView = this.mInflater.inflate(R.layout.spinner_row, parent, false);

ViewHolder vh = new ViewHolder();
vh.txtLabel = convertView.findViewById(R.id.spinner_text);
convertView.setTag(vh);
}

ViewHolder vh = (ViewHolder)convertView.getTag();
vh.txtLabel.setText(this.data.get(position).getName());

return convertView;
}



@Override
public NetIfData getItem(int position) {
if (0 <= position && position < this.getCount()) {
return this.data.get(position).getWrapped();
}
return null;
}



@Override
public int getCount() {
return this.dataSize;
}



public void onNetworkStateChanged(NetworkInterfaceTester nit) {
List<NetIfData> avNetIfs = nit.getAvailableNetIfs();

this.data = new ArrayList<>();
for (NetIfData nid : avNetIfs) {
this.data.add(new NetIfDataDefaultNameDecorator(nid, this.mContext));
}
this.dataSize = this.data.size();


// update Spinner
this.handler.post(new Runnable() {
public void run() {
ListenIfAdapter.this.notifyDataSetChanged();
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import android.util.TypedValue;
import android.view.View;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
Expand All @@ -69,6 +70,9 @@
import android.widget.TableLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Spinner;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.AdapterView;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
Expand All @@ -83,6 +87,8 @@
import java.util.Objects;
import java.util.UUID;

import net.christianbeier.droidvnc_ng.ifaceutils.NetIfData;

public class MainActivity extends AppCompatActivity {

private static final String TAG = "MainActivity";
Expand Down Expand Up @@ -125,6 +131,7 @@ protected void onCreate(Bundle savedInstanceState) {
mButtonToggle.setOnClickListener(view -> {

Intent intent = new Intent(MainActivity.this, MainService.class);
intent.putExtra(MainService.EXTRA_LISTEN_INTERFACE, prefs.getString(Constants.PREFS_KEY_SETTINGS_LISTEN_INTERFACE, mDefaults.getListenInterface()));
intent.putExtra(MainService.EXTRA_PORT, prefs.getInt(Constants.PREFS_KEY_SETTINGS_PORT, mDefaults.getPort()));
intent.putExtra(MainService.EXTRA_PASSWORD, prefs.getString(Constants.PREFS_KEY_SETTINGS_PASSWORD, mDefaults.getPassword()));
intent.putExtra(MainService.EXTRA_FILE_TRANSFER, prefs.getBoolean(Constants.PREFS_KEY_SETTINGS_FILE_TRANSFER, mDefaults.getFileTransfer()));
Expand Down Expand Up @@ -331,6 +338,34 @@ protected void onCreate(Bundle savedInstanceState) {
});



ListenIfAdapter lsif = new ListenIfAdapter(this);
final Spinner listenInterfaceSpin = findViewById(R.id.settings_listening_interface);
listenInterfaceSpin.setAdapter(lsif);
listenInterfaceSpin.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
NetIfData d = (NetIfData)parent.getItemAtPosition(pos);
if(!(prefs.getString(Constants.PREFS_KEY_SETTINGS_LISTEN_INTERFACE, null) == null && d.getName().equals(mDefaults.getListenInterface()))) {
SharedPreferences.Editor ed = prefs.edit();
ed.putString(Constants.PREFS_KEY_SETTINGS_LISTEN_INTERFACE, d.getName());
ed.apply();
}
}

@Override
public void onNothingSelected(AdapterView<?> parent) {

}
});
// Restore last selected interface
listenInterfaceSpin.setSelection(
lsif.getItemPositionByOptionId(
prefs.getString(Constants.PREFS_KEY_SETTINGS_LISTEN_INTERFACE, mDefaults.getListenInterface())));




final EditText port = findViewById(R.id.settings_port);
if(prefs.getInt(Constants.PREFS_KEY_SETTINGS_PORT, mDefaults.getPort()) < 0) {
port.setHint(R.string.main_activity_settings_port_not_listening);
Expand Down Expand Up @@ -875,7 +910,8 @@ private void updateAddressesDisplay() {
if(MainService.getPort() >= 0) {
HashMap<ClickableSpan, Pair<Integer,Integer>> spans = new HashMap<>();
// uhh there must be a nice functional way for this
ArrayList<String> hosts = MainService.getIPv4s();
ArrayList<String> hosts = MainService.getReachableIPv4s();

StringBuilder sb = new StringBuilder();
sb.append(getString(R.string.main_activity_address)).append(" ");
if(hosts.isEmpty()) {
Expand Down Expand Up @@ -940,6 +976,7 @@ private void onServerStarted() {
findViewById(R.id.outbound_buttons).setVisibility(View.VISIBLE);

// indicate that changing these settings does not have an effect when the server is running
findViewById(R.id.settings_listening_interface).setEnabled(false);
findViewById(R.id.settings_port).setEnabled(false);
findViewById(R.id.settings_password).setEnabled(false);
findViewById(R.id.settings_access_key).setEnabled(false);
Expand Down Expand Up @@ -969,6 +1006,7 @@ private void onServerStopped() {
findViewById(R.id.outbound_buttons).setVisibility(View.GONE);

// indicate that changing these settings does have an effect when the server is stopped
findViewById(R.id.settings_listening_interface).setEnabled(true);
findViewById(R.id.settings_port).setEnabled(true);
findViewById(R.id.settings_password).setEnabled(true);
findViewById(R.id.settings_access_key).setEnabled(true);
Expand Down
Loading