Refactor: (Major) Shift DeviceListFragment functionality to LocalFileTransferActivity

This commit is contained in:
Aditya-Sood 2019-07-18 15:44:32 +05:30
parent c667315a97
commit e7bc597a78
11 changed files with 475 additions and 130 deletions

View File

@ -54,33 +54,33 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTra
*
* The starting point for the module is {@link LocalFileTransferActivity}
*/
public class DeviceListFragment extends ListFragment
implements WifiP2pManager.PeerListListener, WifiP2pManager.ConnectionInfoListener {
public class DeviceListFragment extends ListFragment {
//implements WifiP2pManager.PeerListListener, WifiP2pManager.ConnectionInfoListener {
public static final String TAG = "DeviceListFragment";
public static int PEER_HANDSHAKE_PORT = 8009;
public static int FILE_TRANSFER_PORT = 8008;
/*public static int PEER_HANDSHAKE_PORT = 8009;
public static int FILE_TRANSFER_PORT = 8008;*/
private SharedPreferenceUtil sharedPreferenceUtil;
private AlertDialogShower alertDialogShower;
private LocalFileTransferActivity localFileTransferActivity;
// Parent activity, starting point of the module
private TransferProgressFragment transferProgressFragment;
/*private TransferProgressFragment transferProgressFragment;*/
// Sibling fragment, for displaying transfer progress
// Views part of the DeviceListFragment
/*// Views part of the DeviceListFragment
@BindView(R.id.text_view_device_name) TextView deviceName;
@BindView(R.id.progress_bar_searching_peers) ProgressBar searchingPeersProgressBar;
@BindView(android.R.id.list) ListView listViewPeerDevices;
@BindView(android.R.id.empty) TextView textViewPeerDevices;
@BindView(android.R.id.empty) TextView textViewPeerDevices;*/
private Unbinder unbinder;
private boolean fileSender = false; // Whether file sending device or not
private ArrayList<Uri> fileUriList;
// Uris of files to be shared, available only for the sender device
private int totalFilesForTransfer = -1;
/*private int totalFilesForTransfer = -1;
private int filesSent = 0; // Count of number of files transferred until now
private ArrayList<FileItem> filesToSend = new ArrayList<>();
@ -97,7 +97,7 @@ public class DeviceListFragment extends ListFragment
private PeerGroupHandshakeAsyncTask peerGroupHandshakeAsyncTask;
private SenderDeviceAsyncTask senderDeviceAsyncTaskArray[];
private ReceiverDeviceAsyncTask receiverDeviceAsyncTask;
private ReceiverDeviceAsyncTask receiverDeviceAsyncTask;*/
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
@ -105,10 +105,10 @@ public class DeviceListFragment extends ListFragment
localFileTransferActivity = (LocalFileTransferActivity) getActivity();
// As DeviceListFragment extends ListFragment for the purpose of displaying list of peers
this.setListAdapter(
new WifiPeerListAdapter(localFileTransferActivity, R.layout.row_peer_device, peerDevices));
/*this.setListAdapter(
new WifiPeerListAdapter(localFileTransferActivity, R.layout.row_peer_device, peerDevices));*/
if (localFileTransferActivity.isFileSender()) {
/*if (localFileTransferActivity.isFileSender()) {
fileSender = true;
fileUriList = localFileTransferActivity.getFileUriArrayList();
totalFilesForTransfer = fileUriList.size();
@ -118,7 +118,7 @@ public class DeviceListFragment extends ListFragment
}
displayTransferProgressFragment();
}
}*/
}
@Override
@ -138,7 +138,7 @@ public class DeviceListFragment extends ListFragment
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
/* Connection can only be initiated by user of the sender device, & only when transfer has not been started */
/* Connection can only be initiated by user of the sender device, & only when transfer has not been started *//*
if (!isFileSender() || fileTransferStarted) {
return;
}
@ -151,27 +151,27 @@ public class DeviceListFragment extends ListFragment
showToast(localFileTransferActivity, R.string.performing_handshake, Toast.LENGTH_LONG);
return Unit.INSTANCE;
}
});
});*/
}
private void displayTransferProgressFragment() {
/*private void displayTransferProgressFragment() {
transferProgressFragment = TransferProgressFragment.newInstance(filesToSend);
FragmentManager fragmentManager = localFileTransferActivity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.container_fragment_transfer_progress, transferProgressFragment)
.commit();
}
}*/
public void updateUserDevice(WifiP2pDevice device) { // Update UI with user device's details
/*public void updateUserDevice(WifiP2pDevice device) { // Update UI with user device's details
this.userDevice = device;
if (userDevice != null) {
deviceName.setText(userDevice.deviceName);
Log.d(TAG, getDeviceStatus(userDevice.status));
}
}
}*/
public static String getDeviceStatus(int status) {
/*public static String getDeviceStatus(int status) {
if (BuildConfig.DEBUG) Log.d(TAG, "Peer Status: " + status);
switch (status) {
@ -189,9 +189,9 @@ public class DeviceListFragment extends ListFragment
default:
return "Unknown";
}
}
}*/
/* From WifiP2pManager.PeerListListener callback-interface */
/* From WifiP2pManager.PeerListListener callback-interface *//*
@Override
public void onPeersAvailable(WifiP2pDeviceList peers) {
searchingPeersProgressBar.setVisibility(View.GONE);
@ -204,9 +204,9 @@ public class DeviceListFragment extends ListFragment
if (peerDevices.size() == 0) {
Log.d(LocalFileTransferActivity.TAG, "No devices found");
}
}
}*/
public void clearPeers() {
/*public void clearPeers() {
peerDevices.clear();
((WifiPeerListAdapter) getListAdapter()).notifyDataSetChanged();
}
@ -231,10 +231,10 @@ public class DeviceListFragment extends ListFragment
textViewPeerDevices.setVisibility(View.INVISIBLE);
}
/* From WifiP2pManager.ConnectionInfoListener callback-interface */
*//* From WifiP2pManager.ConnectionInfoListener callback-interface *//*
@Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
/* Devices have successfully connected, and 'info' holds information about the wifi p2p group formed */
*//* Devices have successfully connected, and 'info' holds information about the wifi p2p group formed *//*
groupInfo = info;
// Start handshake between the devices
peerGroupHandshakeAsyncTask = new PeerGroupHandshakeAsyncTask(this, groupInfo);
@ -283,7 +283,7 @@ public class DeviceListFragment extends ListFragment
}
}
/* Helper methods */
*//* Helper methods *//*
public WifiP2pDevice getUserDevice() {
return userDevice;
@ -335,11 +335,11 @@ public class DeviceListFragment extends ListFragment
return fileReceiverDeviceAddress;
}
public static String getFileName(Uri fileUri) {
*//*public static String getFileName(Uri fileUri) {
String fileUriString = fileUri.toString();
// Returns text after location of last slash in the file path
return fileUriString.substring(fileUriString.lastIndexOf('/') + 1);
}
}*//*
public static void copyToOutputStream(InputStream inputStream, OutputStream outputStream)
throws IOException {
@ -354,7 +354,7 @@ public class DeviceListFragment extends ListFragment
outputStream.close();
inputStream.close();
Log.d(LocalFileTransferActivity.TAG, "Both streams closed");
}
}*/
public interface DeviceActionListener {
void connect(@NonNull WifiP2pDevice peerDevice);

View File

@ -11,6 +11,8 @@ import android.net.Uri;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Build;
import android.os.Bundle;
@ -18,6 +20,10 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
@ -26,12 +32,19 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import butterknife.BindView;
import butterknife.ButterKnife;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.util.List;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import org.kiwix.kiwixmobile.BuildConfig;
import org.kiwix.kiwixmobile.KiwixApplication;
import org.kiwix.kiwixmobile.R;
import org.kiwix.kiwixmobile.utils.AlertDialogShower;
@ -42,6 +55,8 @@ import java.util.ArrayList;
import javax.inject.Inject;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.FileItem.FileStatus.TO_BE_SENT;
/**
* Created by @Aditya-Sood as a part of GSoC 2019.
*
@ -53,8 +68,7 @@ import javax.inject.Inject;
* The module uses this activity along with {@link DeviceListFragment} to manage connection
* and file transfer between the devices.
*/
public class LocalFileTransferActivity extends AppCompatActivity {
//implements WifiP2pManager.ChannelListener, DeviceListFragment.DeviceActionListener {
public class LocalFileTransferActivity extends AppCompatActivity implements WifiP2pManager.PeerListListener, WifiP2pManager.ConnectionInfoListener {
public static final String TAG = "LocalFileTransferActvty";
// Not a typo, 'Log' tags have a length upper limit of 25 characters
@ -63,29 +77,46 @@ public class LocalFileTransferActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE_COARSE_LOCATION = 1;
private static final int PERMISSION_REQUEST_CODE_STORAGE_WRITE_ACCESS = 2;
public static int PEER_HANDSHAKE_PORT = 8009;
public static int FILE_TRANSFER_PORT = 8008;
private TransferProgressFragment transferProgressFragment;
@Inject SharedPreferenceUtil sharedPreferenceUtil;
@Inject AlertDialogShower alertDialogShower;
@BindView(R.id.toolbar_local_file_transfer) Toolbar actionBar;
// Views part of the DeviceListFragment
@BindView(R.id.text_view_device_name) TextView deviceName;
@BindView(R.id.progress_bar_searching_peers) ProgressBar searchingPeersProgressBar;
@BindView(R.id.list_peer_devices) ListView listViewPeerDevices;
@BindView(R.id.text_view_empty_peer_list) TextView textViewPeerDevices;
private ArrayList<Uri> fileUriArrayList;
// For sender device, stores Uris of files to be transferred
public Boolean fileSendingDevice = false;// Whether the device is the file sender or not
/* Variables related to the WiFi P2P API */
/*private boolean wifiP2pEnabled = false; // Whether WiFi has been enabled or not
private boolean retryChannel = false; // Whether channel has retried connecting previously
private WifiP2pManager manager; // Overall manager of Wifi p2p connections for the module
private WifiP2pManager.Channel channel;
// Connects the module to device's underlying Wifi p2p framework
private final IntentFilter intentFilter = new IntentFilter();
// For specifying broadcasts (of the P2P API) that the module needs to respond to
private BroadcastReceiver receiver = null; // For receiving the broadcasts given by above filter*/
public WifiDirectManager wifiDirectManager;
private int totalFilesForTransfer = -1;
private int filesSent = 0; // Count of number of files transferred until now
private ArrayList<FileItem> filesToSend = new ArrayList<>();
private WifiP2pDevice userDevice; // Represents the device on which the app is running
private WifiP2pInfo groupInfo;
// Corresponds to the WiFi P2P group formed between the two devices
private List<WifiP2pDevice> peerDevices = new ArrayList<WifiP2pDevice>();
private WifiP2pDevice selectedPeerDevice = null;
private InetAddress selectedPeerDeviceInetAddress;
private InetAddress fileReceiverDeviceAddress; // IP address of the file receiving device
private boolean fileTransferStarted = false;
private PeerGroupHandshakeAsyncTask peerGroupHandshakeAsyncTask;
private SenderDeviceAsyncTask senderDeviceAsyncTaskArray[];
private ReceiverDeviceAsyncTask receiverDeviceAsyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -120,18 +151,39 @@ public class LocalFileTransferActivity extends AppCompatActivity {
/* Initialisations for using the WiFi P2P API */
/*
// Intents that the broadcast receiver will be responding to
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = manager.initialize(this, getMainLooper(), null);*/
this.wifiDirectManager = new WifiDirectManager(this);
wifiDirectManager.initialiseWifiDirectManager();
listViewPeerDevices.setAdapter(new WifiPeerListAdapter(this, R.layout.row_peer_device, peerDevices));
if(isFileSender()) {
totalFilesForTransfer = fileUriArrayList.size();
for (int i = 0; i < fileUriArrayList.size(); i++) {
filesToSend.add(new FileItem(getFileName(fileUriArrayList.get(i)), TO_BE_SENT));
}
displayTransferProgressFragment();
listViewPeerDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
/* Connection can only be initiated by user of the sender device, & only when transfer has not been started */
if (!isFileSender() || fileTransferStarted) {
return;
}
selectedPeerDevice = (WifiP2pDevice) listViewPeerDevices.getAdapter().getItem(position);
alertDialogShower.show(new KiwixDialog.FileTransferConfirmation(selectedPeerDevice),
new Function0<Unit>() {
@Override public Unit invoke() {
((DeviceListFragment.DeviceActionListener) wifiDirectManager).connect(selectedPeerDevice);
showToast(LocalFileTransferActivity.this, R.string.performing_handshake, Toast.LENGTH_LONG);
return Unit.INSTANCE;
}
});
}
});
}
}
@Override
@ -160,11 +212,12 @@ public class LocalFileTransferActivity extends AppCompatActivity {
return true;
}
final DeviceListFragment deviceListFragment =
onInitiateDiscovery();
/*final DeviceListFragment deviceListFragment =
(DeviceListFragment) getSupportFragmentManager().findFragmentById(
R.id.fragment_device_list);
deviceListFragment.onInitiateDiscovery();
deviceListFragment.performFieldInjection(sharedPreferenceUtil, alertDialogShower);
deviceListFragment.performFieldInjection(sharedPreferenceUtil, alertDialogShower);*/
/*manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
@ -225,21 +278,23 @@ public class LocalFileTransferActivity extends AppCompatActivity {
}
public void resetPeers() {
DeviceListFragment deviceListFragment =
/*DeviceListFragment deviceListFragment =
(DeviceListFragment) getSupportFragmentManager().findFragmentById(
R.id.fragment_device_list);
if (deviceListFragment != null) {
deviceListFragment.clearPeers();
}
}*/
clearPeers();
}
public void resetData() {
DeviceListFragment deviceListFragment =
/*DeviceListFragment deviceListFragment =
(DeviceListFragment) getSupportFragmentManager().findFragmentById(
R.id.fragment_device_list);
if (deviceListFragment != null) {
deviceListFragment.clearPeers();
}
}*/
clearPeers();
}
static void showToast(Context context, int stringResource, int duration) {
@ -484,12 +539,7 @@ public class LocalFileTransferActivity extends AppCompatActivity {
@Override protected void onDestroy() {
super.onDestroy();
final DeviceListFragment deviceListFragment =
(DeviceListFragment) getSupportFragmentManager().findFragmentById(
R.id.fragment_device_list);
if (deviceListFragment != null) {
deviceListFragment.cancelAsyncTasks();
}
cancelAsyncTasks();
}
@Override
@ -497,4 +547,208 @@ public class LocalFileTransferActivity extends AppCompatActivity {
super.onBackPressed();
wifiDirectManager.closeLocalFileTransferActivity();
}
public static String getFileName(Uri fileUri) {
String fileUriString = fileUri.toString();
// Returns text after location of last slash in the file path
return fileUriString.substring(fileUriString.lastIndexOf('/') + 1);
}
private void displayTransferProgressFragment() {
transferProgressFragment = TransferProgressFragment.newInstance(filesToSend);
FragmentManager fragmentManager = this.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.container_fragment_transfer_progress, transferProgressFragment)
.commit();
}
public void updateUserDevice(WifiP2pDevice device) { // Update UI with user device's details
this.userDevice = device;
if (userDevice != null) {
deviceName.setText(userDevice.deviceName);
Log.d(TAG, getDeviceStatus(userDevice.status));
}
}
public static String getDeviceStatus(int status) {
if (BuildConfig.DEBUG) Log.d(TAG, "Peer Status: " + status);
switch (status) {
case WifiP2pDevice.AVAILABLE:
return "Available";
case WifiP2pDevice.INVITED:
return "Invited";
case WifiP2pDevice.CONNECTED:
return "Connected";
case WifiP2pDevice.FAILED:
return "Failed";
case WifiP2pDevice.UNAVAILABLE:
return "Unavailable";
default:
return "Unknown";
}
}
/* From WifiP2pManager.PeerListListener callback-interface */
@Override
public void onPeersAvailable(WifiP2pDeviceList peers) {
searchingPeersProgressBar.setVisibility(View.GONE);
listViewPeerDevices.setVisibility(View.VISIBLE);
peerDevices.clear();
peerDevices.addAll(peers.getDeviceList());
((WifiPeerListAdapter) listViewPeerDevices.getAdapter()).notifyDataSetChanged();
if (peerDevices.size() == 0) {
Log.d(LocalFileTransferActivity.TAG, "No devices found");
}
}
public void clearPeers() {
peerDevices.clear();
((WifiPeerListAdapter) listViewPeerDevices.getAdapter()).notifyDataSetChanged();
}
void cancelAsyncTasks() {
if (peerGroupHandshakeAsyncTask != null) {
peerGroupHandshakeAsyncTask.cancel(true);
}
if (senderDeviceAsyncTaskArray != null) {
for (SenderDeviceAsyncTask task : senderDeviceAsyncTaskArray) {
task.cancel(true);
}
} else if (receiverDeviceAsyncTask != null) {
receiverDeviceAsyncTask.cancel(true);
}
}
public void onInitiateDiscovery() { // Setup UI for searching peers
searchingPeersProgressBar.setVisibility(View.VISIBLE);
listViewPeerDevices.setVisibility(View.INVISIBLE);
textViewPeerDevices.setVisibility(View.INVISIBLE);
}
/* From WifiP2pManager.ConnectionInfoListener callback-interface */
@Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
/* Devices have successfully connected, and 'info' holds information about the wifi p2p group formed */
groupInfo = info;
// Start handshake between the devices
peerGroupHandshakeAsyncTask = new PeerGroupHandshakeAsyncTask(this, groupInfo);
peerGroupHandshakeAsyncTask.execute();
}
public void setClientAddress(InetAddress clientAddress) {
if (clientAddress == null) {
// null is returned only in case of a failed handshake
showToast(this, R.string.device_not_cooperating, Toast.LENGTH_LONG);
wifiDirectManager.closeLocalFileTransferActivity();
return;
}
// If control reaches here, means handshake was successful
selectedPeerDeviceInetAddress = clientAddress;
startFileTransfer();
}
private void startFileTransfer() {
fileTransferStarted = true;
if (groupInfo.groupFormed && !isFileSender()) {
displayTransferProgressFragment();
receiverDeviceAsyncTask = new ReceiverDeviceAsyncTask(this, transferProgressFragment);
receiverDeviceAsyncTask.execute();
} else if (groupInfo.groupFormed) {
{
Log.d(LocalFileTransferActivity.TAG, "Starting file transfer");
fileReceiverDeviceAddress =
(groupInfo.isGroupOwner) ? selectedPeerDeviceInetAddress : groupInfo.groupOwnerAddress;
// Hack for allowing slower receiver devices to setup server before sender device requests to connect
showToast(this, R.string.preparing_files, Toast.LENGTH_LONG);
for (int i = 0; i < 20000000; i++) ;
senderDeviceAsyncTaskArray = new SenderDeviceAsyncTask[totalFilesForTransfer];
for (int i = 0; i < totalFilesForTransfer; i++) {
senderDeviceAsyncTaskArray[i] =
new SenderDeviceAsyncTask(this, transferProgressFragment, i);
senderDeviceAsyncTaskArray[i].execute(fileUriArrayList.get(i));
}
}
}
}
/* Helper methods */
public WifiP2pDevice getUserDevice() {
return userDevice;
}
public int getTotalFilesForTransfer() {
return totalFilesForTransfer;
}
public void setTotalFilesForTransfer(int totalFilesForTransfer) {
this.totalFilesForTransfer = totalFilesForTransfer;
}
public ArrayList<FileItem> getFileItems() {
return filesToSend;
}
public void setFileItems(ArrayList<FileItem> fileItems) {
this.filesToSend = fileItems;
}
public ArrayList<Uri> getFileUriList() {
return fileUriArrayList;
}
public void incrementTotalFilesSent() {
this.filesSent++;
}
public boolean allFilesSent() {
return (filesSent == totalFilesForTransfer);
}
/*public void performFieldInjection(SharedPreferenceUtil sharedPreferenceUtil,
AlertDialogShower alertDialogShower) {
this.sharedPreferenceUtil = sharedPreferenceUtil;
this.alertDialogShower = alertDialogShower;
}*/
public String getZimStorageRootPath() {
return (sharedPreferenceUtil.getPrefStorage() + "/Kiwix/");
}
public InetAddress getFileReceiverDeviceAddress() {
return fileReceiverDeviceAddress;
}
/*public static String getFileName(Uri fileUri) {
String fileUriString = fileUri.toString();
// Returns text after location of last slash in the file path
return fileUriString.substring(fileUriString.lastIndexOf('/') + 1);
}*/
public static void copyToOutputStream(InputStream inputStream, OutputStream outputStream)
throws IOException {
byte[] bufferForBytes = new byte[1024];
int bytesRead;
Log.d(TAG, "Copying to OutputStream...");
while ((bytesRead = inputStream.read(bufferForBytes)) != -1) {
outputStream.write(bufferForBytes, 0, bytesRead);
}
outputStream.close();
inputStream.close();
Log.d(LocalFileTransferActivity.TAG, "Both streams closed");
}
}

View File

@ -17,9 +17,9 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.DeviceListFragment.PEER_HANDSHAKE_PORT;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.DeviceListFragment.getFileName;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.FileItem.FileStatus.TO_BE_SENT;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.PEER_HANDSHAKE_PORT;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.getFileName;
/**
* Helper class for the local file sharing module, used in {@link DeviceListFragment}.
@ -39,11 +39,11 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
private static final String TAG = "PeerGrpHndshakeAsyncTsk";
private final String HANDSHAKE_MESSAGE = "Request Kiwix File Sharing";
private DeviceListFragment deviceListFragment;
private LocalFileTransferActivity localFileTransferActivity;
private WifiP2pInfo groupInfo;
public PeerGroupHandshakeAsyncTask(DeviceListFragment deviceListFragment, WifiP2pInfo groupInfo) {
this.deviceListFragment = deviceListFragment;
public PeerGroupHandshakeAsyncTask(LocalFileTransferActivity localFileTransferActivity, WifiP2pInfo groupInfo) {
this.localFileTransferActivity = localFileTransferActivity;
this.groupInfo = groupInfo;
}
@ -100,12 +100,12 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
}
private void exchangeFileTransferMetadata(OutputStream outputStream, InputStream inputStream) {
if (deviceListFragment.isFileSender()) {
if (localFileTransferActivity.isFileSender()) {
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)) {
// Send total number of files which will be transferred
objectOutputStream.writeObject("" + deviceListFragment.getTotalFilesForTransfer());
objectOutputStream.writeObject("" + localFileTransferActivity.getTotalFilesForTransfer());
ArrayList<Uri> fileUriList = deviceListFragment.getFileUriList();
ArrayList<Uri> fileUriList = localFileTransferActivity.getFileUriList();
for (
Uri fileUri : fileUriList) { // Send the names of each of those files, in order
objectOutputStream.writeObject(getFileName(fileUri));
@ -120,7 +120,7 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
if (totalFilesObject.getClass().equals(String.class)) {
int total = Integer.parseInt((String) totalFilesObject);
deviceListFragment.setTotalFilesForTransfer(total);
localFileTransferActivity.setTotalFilesForTransfer(total);
ArrayList<FileItem> fileItems = new ArrayList<>();
for (int i = 0; i < total; i++) { // Read names of each of those files, in order
@ -131,7 +131,7 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
}
}
deviceListFragment.setFileItems(fileItems);
localFileTransferActivity.setFileItems(fileItems);
}
} catch (Exception e) {
e.printStackTrace();
@ -145,6 +145,6 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
@Override
protected void onPostExecute(InetAddress inetAddress) {
deviceListFragment.setClientAddress(inetAddress);
localFileTransferActivity.setClientAddress(inetAddress);
}
}

View File

@ -14,10 +14,10 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.DeviceListFragment.FILE_TRANSFER_PORT;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.DeviceListFragment.copyToOutputStream;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.FileItem.FileStatus.SENDING;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.FileItem.FileStatus.SENT;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.FILE_TRANSFER_PORT;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.copyToOutputStream;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.showToast;
/**
@ -34,13 +34,13 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private static final String TAG = "ReceiverDeviceAsyncTask";
private DeviceListFragment deviceListFragment;
private LocalFileTransferActivity localFileTransferActivity;
private TransferProgressFragment transferProgressFragment;
private int fileItemIndex;
public ReceiverDeviceAsyncTask(DeviceListFragment deviceListFragment,
public ReceiverDeviceAsyncTask(LocalFileTransferActivity localFileTransferActivity,
TransferProgressFragment transferProgressFragment) {
this.deviceListFragment = deviceListFragment;
this.localFileTransferActivity = localFileTransferActivity;
this.transferProgressFragment = transferProgressFragment;
}
@ -49,9 +49,9 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
try (ServerSocket serverSocket = new ServerSocket(FILE_TRANSFER_PORT)) {
if (BuildConfig.DEBUG) Log.d(TAG, "Server: Socket opened at " + FILE_TRANSFER_PORT);
final String KIWIX_ROOT = deviceListFragment.getZimStorageRootPath();
final String KIWIX_ROOT = localFileTransferActivity.getZimStorageRootPath();
int totalFileCount = deviceListFragment.getTotalFilesForTransfer();
int totalFileCount = localFileTransferActivity.getTotalFilesForTransfer();
for (int currentFile = 1; currentFile <= totalFileCount && !isCancelled(); currentFile++) {
Socket client = serverSocket.accept();
@ -60,7 +60,7 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
fileItemIndex = currentFile - 1;
publishProgress(SENDING);
ArrayList<FileItem> fileItems = deviceListFragment.getFileItems();
ArrayList<FileItem> fileItems = localFileTransferActivity.getFileItems();
String incomingFileName = fileItems.get(fileItemIndex).getFileName();
final File clientNoteFileLocation = new File(KIWIX_ROOT + incomingFileName);
@ -76,7 +76,7 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
copyToOutputStream(client.getInputStream(), new FileOutputStream(clientNoteFileLocation));
publishProgress(SENT);
deviceListFragment.incrementTotalFilesSent();
localFileTransferActivity.incrementTotalFilesSent();
}
if (isCancelled()) {
@ -105,13 +105,13 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
if (BuildConfig.DEBUG) Log.d(TAG, "File transfer complete");
if (allFilesReceived) {
showToast(deviceListFragment.getActivity(), R.string.file_transfer_complete,
showToast(localFileTransferActivity, R.string.file_transfer_complete,
Toast.LENGTH_LONG);
} else {
showToast(deviceListFragment.getActivity(), R.string.error_during_transfer,
showToast(localFileTransferActivity, R.string.error_during_transfer,
Toast.LENGTH_LONG);
}
((LocalFileTransferActivity) deviceListFragment.getActivity()).wifiDirectManager.closeLocalFileTransferActivity();
(localFileTransferActivity).wifiDirectManager.closeLocalFileTransferActivity();
}
}

View File

@ -16,9 +16,10 @@ import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.DeviceListFragment.FILE_TRANSFER_PORT;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.DeviceListFragment.getFileName;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.FileItem.FileStatus.*;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.FILE_TRANSFER_PORT;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.copyToOutputStream;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.getFileName;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.showToast;
/**
@ -37,13 +38,13 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
private static final String TAG = "SenderDeviceAsyncTask";
private DeviceListFragment deviceListFragment;
private LocalFileTransferActivity localFileTransferActivity;
private TransferProgressFragment transferProgressFragment;
private int fileItemIndex;
public SenderDeviceAsyncTask(DeviceListFragment deviceListFragment,
public SenderDeviceAsyncTask(LocalFileTransferActivity localFileTransferActivity,
TransferProgressFragment transferProgressFragment, int fileItemIndex) {
this.deviceListFragment = deviceListFragment;
this.localFileTransferActivity = localFileTransferActivity;
this.transferProgressFragment = transferProgressFragment;
this.fileItemIndex = fileItemIndex;
}
@ -56,7 +57,7 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
@Override
protected Boolean doInBackground(Uri... fileUris) {
Uri fileUri = fileUris[0]; // Uri of file to be transferred
ContentResolver contentResolver = deviceListFragment.getActivity().getContentResolver();
ContentResolver contentResolver = localFileTransferActivity.getContentResolver();
try (Socket socket = new Socket();
InputStream fileInputStream = contentResolver.openInputStream(
@ -67,14 +68,14 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
}
socket.bind(null);
String hostAddress = deviceListFragment.getFileReceiverDeviceAddress().getHostAddress();
String hostAddress = localFileTransferActivity.getFileReceiverDeviceAddress().getHostAddress();
socket.connect((new InetSocketAddress(hostAddress, FILE_TRANSFER_PORT)), 15000);
if (BuildConfig.DEBUG) Log.d(TAG, "Sender socket - " + socket.isConnected());
OutputStream socketOutputStream = socket.getOutputStream();
DeviceListFragment.copyToOutputStream(fileInputStream, socketOutputStream);
copyToOutputStream(fileInputStream, socketOutputStream);
if (BuildConfig.DEBUG) Log.d(TAG, "Sender: Data written");
return true;
@ -90,21 +91,20 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
@Override
protected void onPostExecute(Boolean fileSendSuccessful) {
deviceListFragment.incrementTotalFilesSent();
localFileTransferActivity.incrementTotalFilesSent();
if (fileSendSuccessful) { // Whether this task was successful in sending the file
transferProgressFragment.changeStatus(fileItemIndex, SENT);
} else {
Activity activity = deviceListFragment.getActivity();
showToast(activity, activity.getString(R.string.error_sending,
getFileName(deviceListFragment.getFileUriList().get(fileItemIndex))), Toast.LENGTH_SHORT);
showToast(localFileTransferActivity, localFileTransferActivity.getString(R.string.error_sending,
getFileName(localFileTransferActivity.getFileUriList().get(fileItemIndex))), Toast.LENGTH_SHORT);
transferProgressFragment.changeStatus(fileItemIndex, ERROR);
}
if (deviceListFragment.allFilesSent()) {
showToast(deviceListFragment.getActivity(), R.string.file_transfer_complete,
if (localFileTransferActivity.allFilesSent()) {
showToast(localFileTransferActivity, R.string.file_transfer_complete,
Toast.LENGTH_SHORT);
deviceListFragment.getActivity().finish();
localFileTransferActivity.finish();
}
}
}

View File

@ -54,9 +54,7 @@ public class WifiDirectBroadcastReceiver extends BroadcastReceiver {
if (manager != null) {
/* List of available peers has changed, so request & use the new list through
* PeerListListener.requestPeers() callback */
manager.requestPeers(channel,
(WifiP2pManager.PeerListListener) wifiActivity.getSupportFragmentManager()
.findFragmentById(R.id.fragment_device_list));
manager.requestPeers(channel, wifiActivity);
}
Log.d(LocalFileTransferActivity.TAG, "P2P peers changed");
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
@ -68,19 +66,14 @@ public class WifiDirectBroadcastReceiver extends BroadcastReceiver {
if (networkInfo.isConnected()) {
// Request connection info about the wifi p2p group formed upon connection
manager.requestConnectionInfo(channel,
(DeviceListFragment) wifiActivity.getSupportFragmentManager()
.findFragmentById(R.id.fragment_device_list));
manager.requestConnectionInfo(channel, wifiActivity);
} else {
// Not connected after connection change -> Disconnected
wifiActivity.resetData();
}
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// Update UI with wifi-direct details about the user device
DeviceListFragment deviceListFragment =
(DeviceListFragment) wifiActivity.getSupportFragmentManager()
.findFragmentById(R.id.fragment_device_list);
deviceListFragment.updateUserDevice(
wifiActivity.updateUserDevice(
intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
}
}

View File

@ -16,11 +16,15 @@ import org.kiwix.kiwixmobile.R;
import static android.os.Looper.getMainLooper;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.showToast;
/**
* Manager for the Wifi-P2p API, used in the local file transfer module
* */
public class WifiDirectManager implements WifiP2pManager.ChannelListener, DeviceListFragment.DeviceActionListener {
private static final String TAG = "WifiDirectManager";
LocalFileTransferActivity activity;
private LocalFileTransferActivity activity;
/* Variables related to the WiFi P2P API */
private boolean wifiP2pEnabled = false; // Whether WiFi has been enabled or not
@ -125,12 +129,7 @@ public class WifiDirectManager implements WifiP2pManager.ChannelListener, Device
@Override
public void closeLocalFileTransferActivity() {
final DeviceListFragment deviceListFragment =
(DeviceListFragment) activity.getSupportFragmentManager().findFragmentById(
R.id.fragment_device_list);
if (deviceListFragment != null) {
deviceListFragment.cancelAsyncTasks();
}
activity.cancelAsyncTasks();
activity.fileSendingDevice = false;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {

View File

@ -17,8 +17,8 @@ import org.kiwix.kiwixmobile.R;
import java.util.List;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.DeviceListFragment.getDeviceStatus;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.DeviceListFragment.TAG;
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.getDeviceStatus;
/**
* Helper class, part of the local file sharing module.

View File

@ -14,20 +14,117 @@
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/fragment_device_list">
app:layout_constraintRight_toRightOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_local_file_transfer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:titleTextColor="#FFFFFF"
app:title="Local ZIM Sharing">
app:title="@string/local_zim_sharing">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<fragment
<TextView
android:id="@+id/text_view_your_device"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:paddingRight="5dp"
android:paddingBottom="1dp"
android:text="@string/your_device"
android:textSize="13sp"
android:textStyle="italic"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/app_bar_local_file_transfer" />
<TextView
android:id="@+id/text_view_device_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Device Name"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintTop_toBottomOf="@id/text_view_your_device"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:textStyle="bold"
android:textSize="17sp"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingBottom="5dp"/>
<View
android:id="@+id/view_device_list_boundary"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#0000f0"
app:layout_constraintTop_toBottomOf="@id/text_view_device_name"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
<TextView
android:id="@+id/text_view_available_device"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/nearby_devices"
android:gravity="center"
android:textSize="16sp"
app:fontFamily="monospace"
app:layout_constraintTop_toBottomOf="@id/view_device_list_boundary"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:paddingTop="5dp"/>
<!--<androidx.constraintlayout.widget.Group
android:id="@+id/group_peer_devices"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="list_peer_devices,text_view_empty_peer_list"/>-->
<ListView
android:id="@+id/list_peer_devices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/text_view_available_device"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintVertical_bias="0.0"
android:visibility="invisible"/>
<TextView
android:id="@+id/text_view_empty_peer_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/no_devices_found"
android:gravity="center"
android:layout_margin="50dp"
android:textColor="@android:color/black"
app:layout_constraintTop_toBottomOf="@id/text_view_available_device"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<ProgressBar
android:id="@+id/progress_bar_searching_peers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_margin="50dp"
app:layout_constraintTop_toBottomOf="@id/text_view_available_device"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:visibility="gone"/>
<!--<fragment
class="org.kiwix.kiwixmobile.zim_manager.local_file_transfer.DeviceListFragment"
android:id="@+id/fragment_device_list"
android:layout_width="match_parent"
@ -35,13 +132,14 @@
app:layout_constraintTop_toBottomOf="@id/app_bar_local_file_transfer"
app:layout_constraintBottom_toTopOf="@id/container_fragment_transfer_progress"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
app:layout_constraintRight_toRightOf="parent"/>-->
<FrameLayout
android:id="@+id/container_fragment_transfer_progress"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/fragment_device_list"
android:layout_marginTop="200dp"
app:layout_constraintTop_toBottomOf="@id/text_view_available_device"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>

View File

@ -5,7 +5,7 @@
android:background="@android:color/transparent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
<!--<TextView
android:id="@+id/text_view_your_device"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -97,6 +97,6 @@
app:layout_constraintTop_toBottomOf="@id/text_view_available_device"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:visibility="gone"/>
android:visibility="gone"/>-->
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -286,4 +286,5 @@
<string name="files_for_transfer">FILES FOR TRANSFER</string>
<string name="preparing_files">Preparing files for transfer....</string>
<string name="performing_handshake">Performing handshake....</string>
<string name="local_zim_sharing">Local ZIM Sharing</string>
</resources>