mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-23 04:33:54 -04:00
Major Refactor!
- Shift all async-tasks and file transfer code to WDM from LocalFileTransferActivity - LocalFileTransferActivity only deals with setting up the UI now
This commit is contained in:
parent
19b316644e
commit
d11af7ba65
@ -9,7 +9,6 @@ import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.p2p.WifiP2pDevice;
|
||||
import android.net.wifi.p2p.WifiP2pDeviceList;
|
||||
import android.net.wifi.p2p.WifiP2pInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
@ -34,14 +33,10 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnItemClick;
|
||||
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;
|
||||
@ -53,6 +48,8 @@ import java.util.ArrayList;
|
||||
import javax.inject.Inject;
|
||||
|
||||
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.WifiDirectManager.getDeviceStatus;
|
||||
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.WifiDirectManager.getFileName;
|
||||
|
||||
/**
|
||||
* Created by @Aditya-Sood as a part of GSoC 2019.
|
||||
@ -92,20 +89,12 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
|
||||
|
||||
public @NonNull WifiDirectManager wifiDirectManager = new WifiDirectManager(this);
|
||||
|
||||
private int totalFilesForTransfer = -1;
|
||||
private int filesSent = 0; // Count of number of files transferred until now
|
||||
private ArrayList<FileItem> filesToSend = new ArrayList<>();
|
||||
private FileListAdapter fileListAdapter;
|
||||
|
||||
private List<WifiP2pDevice> peerDevices = new ArrayList<WifiP2pDevice>();
|
||||
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(@Nullable Bundle savedInstanceState) {
|
||||
KiwixApplication.getApplicationComponent().activityComponent()
|
||||
@ -137,19 +126,17 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
|
||||
}
|
||||
});
|
||||
|
||||
wifiDirectManager.createWifiDirectManager(alertDialogShower);
|
||||
wifiDirectManager.createWifiDirectManager(sharedPreferenceUtil, alertDialogShower, fileUriArrayList);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
displayFileTransferProgress();
|
||||
displayFileTransferProgress(filesToSend);
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,14 +192,6 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
|
||||
}
|
||||
|
||||
/* Helper methods used in the activity */
|
||||
public boolean isFileSender() {
|
||||
return isFileSender;
|
||||
}
|
||||
|
||||
public @NonNull ArrayList<Uri> getFileUriArrayList() {
|
||||
return fileUriArrayList;
|
||||
}
|
||||
|
||||
public void updateUserDevice(@Nullable WifiP2pDevice userDevice) { // Update UI with user device's details
|
||||
wifiDirectManager.setUserDevice(userDevice);
|
||||
|
||||
@ -227,33 +206,11 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
|
||||
((WifiPeerListAdapter) listViewPeerDevices.getAdapter()).notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public static @NonNull 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";
|
||||
@Override
|
||||
public void displayFileTransferProgress(ArrayList<FileItem> filesToSend) {
|
||||
if(!isFileSender) {
|
||||
this.filesToSend = filesToSend;
|
||||
}
|
||||
}
|
||||
|
||||
public static @NonNull String getFileName(@NonNull 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 displayFileTransferProgress() {
|
||||
fileListAdapter = new FileListAdapter(filesToSend);
|
||||
filesRecyclerView.setAdapter(fileListAdapter);
|
||||
filesRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
@ -265,92 +222,6 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
|
||||
textViewPeerDevices.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
public void setClientAddress(@Nullable 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);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// If control reaches here, means handshake was successful
|
||||
selectedPeerDeviceInetAddress = clientAddress;
|
||||
startFileTransfer();
|
||||
}
|
||||
|
||||
private void startFileTransfer() {
|
||||
fileTransferStarted = true;
|
||||
|
||||
if (wifiDirectManager.isGroupFormed() && !isFileSender) {
|
||||
displayFileTransferProgress();
|
||||
|
||||
receiverDeviceAsyncTask = new ReceiverDeviceAsyncTask(this);
|
||||
receiverDeviceAsyncTask.execute();
|
||||
} else if (wifiDirectManager.isGroupFormed()) { // && isFileSender
|
||||
{
|
||||
Log.d(LocalFileTransferActivity.TAG, "Starting file transfer");
|
||||
|
||||
fileReceiverDeviceAddress =
|
||||
(wifiDirectManager.isGroupOwner()) ? selectedPeerDeviceInetAddress
|
||||
: wifiDirectManager.getGroupOwnerAddress();
|
||||
|
||||
// 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(this);
|
||||
senderDeviceAsyncTaskArray.execute(fileUriArrayList.toArray(new Uri[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalFilesForTransfer() {
|
||||
return totalFilesForTransfer;
|
||||
}
|
||||
|
||||
public void setTotalFilesForTransfer(int totalFilesForTransfer) {
|
||||
this.totalFilesForTransfer = totalFilesForTransfer;
|
||||
}
|
||||
|
||||
public @NonNull ArrayList<FileItem> getFileItems() {
|
||||
return filesToSend;
|
||||
}
|
||||
|
||||
public void setFileItems(@NonNull ArrayList<FileItem> fileItems) {
|
||||
this.filesToSend = fileItems;
|
||||
}
|
||||
|
||||
public void incrementTotalFilesSent() {
|
||||
this.filesSent++;
|
||||
}
|
||||
|
||||
public boolean allFilesSent() {
|
||||
return (filesSent == totalFilesForTransfer);
|
||||
}
|
||||
|
||||
public @NonNull String getZimStorageRootPath() {
|
||||
return (sharedPreferenceUtil.getPrefStorage() + "/Kiwix/");
|
||||
}
|
||||
|
||||
public @NonNull InetAddress getFileReceiverDeviceAddress() {
|
||||
return fileReceiverDeviceAddress;
|
||||
}
|
||||
|
||||
public static void copyToOutputStream(@NonNull InputStream inputStream, @NonNull 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");
|
||||
}
|
||||
|
||||
public void changeStatus(int itemIndex, @FileItem.FileStatus int status) {
|
||||
filesToSend.get(itemIndex).setFileStatus(status);
|
||||
fileListAdapter.notifyItemChanged(itemIndex);
|
||||
@ -371,15 +242,6 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performHandshakeWithSelectedPeerDevice(@NonNull WifiP2pInfo groupInfo) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d(TAG, "Starting handshake");
|
||||
}
|
||||
peerGroupHandshakeAsyncTask = new PeerGroupHandshakeAsyncTask(this, groupInfo);
|
||||
peerGroupHandshakeAsyncTask.execute();
|
||||
}
|
||||
|
||||
/* Helper methods used for checking permissions and states of services */
|
||||
private boolean checkCoarseLocationAccessPermission() { // Required by Android to detect wifi-p2p peers
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
@ -547,19 +409,6 @@ public class LocalFileTransferActivity extends AppCompatActivity implements
|
||||
Toast.makeText(context, text, duration).show();
|
||||
}
|
||||
|
||||
void cancelAsyncTasks() {
|
||||
if (peerGroupHandshakeAsyncTask != null) {
|
||||
peerGroupHandshakeAsyncTask.cancel(true);
|
||||
}
|
||||
|
||||
if (senderDeviceAsyncTaskArray != null) {
|
||||
senderDeviceAsyncTaskArray.cancel(true);
|
||||
|
||||
} else if (receiverDeviceAsyncTask != null) {
|
||||
receiverDeviceAsyncTask.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -19,7 +19,7 @@ import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
|
||||
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.getFileName;
|
||||
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.WifiDirectManager.getFileName;
|
||||
|
||||
/**
|
||||
* Helper class for the local file sharing module.
|
||||
@ -40,12 +40,10 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
|
||||
private static int PEER_HANDSHAKE_PORT = 8009;
|
||||
private final String HANDSHAKE_MESSAGE = "Request Kiwix File Sharing";
|
||||
|
||||
private WeakReference<LocalFileTransferActivity> weakReferenceToActivity;
|
||||
private WifiP2pInfo groupInfo;
|
||||
private WifiDirectManager wifiDirectManager;
|
||||
|
||||
public PeerGroupHandshakeAsyncTask(LocalFileTransferActivity localFileTransferActivity, WifiP2pInfo groupInfo) {
|
||||
this.weakReferenceToActivity = new WeakReference<>(localFileTransferActivity);
|
||||
this.groupInfo = groupInfo;
|
||||
public PeerGroupHandshakeAsyncTask(WifiDirectManager wifiDirectManager) {
|
||||
this.wifiDirectManager = wifiDirectManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -54,7 +52,7 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
|
||||
Log.d(TAG, "Handshake in progress");
|
||||
}
|
||||
|
||||
if (groupInfo.groupFormed && groupInfo.isGroupOwner && !isCancelled()) {
|
||||
if (wifiDirectManager.isGroupFormed() && wifiDirectManager.isGroupOwner() && !isCancelled()) {
|
||||
try (ServerSocket serverSocket = new ServerSocket(PEER_HANDSHAKE_PORT)) {
|
||||
serverSocket.setReuseAddress(true);
|
||||
Socket server = serverSocket.accept();
|
||||
@ -77,10 +75,10 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
} else if (groupInfo.groupFormed && !isCancelled()) { //&& !groupInfo.isGroupOwner
|
||||
} else if (wifiDirectManager.isGroupFormed() && !isCancelled()) { //&& !groupInfo.isGroupOwner
|
||||
try (Socket client = new Socket()) {
|
||||
client.setReuseAddress(true);
|
||||
client.connect((new InetSocketAddress(groupInfo.groupOwnerAddress.getHostAddress(),
|
||||
client.connect((new InetSocketAddress(wifiDirectManager.getGroupOwnerAddress().getHostAddress(),
|
||||
PEER_HANDSHAKE_PORT)), 15000);
|
||||
|
||||
ObjectOutputStream objectOutputStream = new ObjectOutputStream(client.getOutputStream());
|
||||
@ -89,7 +87,7 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
|
||||
|
||||
exchangeFileTransferMetadata(client.getOutputStream(), client.getInputStream());
|
||||
|
||||
return groupInfo.groupOwnerAddress;
|
||||
return wifiDirectManager.getGroupOwnerAddress();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
@ -104,14 +102,13 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
|
||||
}
|
||||
|
||||
private void exchangeFileTransferMetadata(OutputStream outputStream, InputStream inputStream) {
|
||||
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
|
||||
|
||||
if (localFileTransferActivity.isFileSender()) {
|
||||
if (wifiDirectManager.isFileSender()) {
|
||||
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)) {
|
||||
// Send total number of files which will be transferred
|
||||
objectOutputStream.writeObject("" + localFileTransferActivity.getTotalFilesForTransfer());
|
||||
objectOutputStream.writeObject("" + wifiDirectManager.getTotalFilesForTransfer());
|
||||
|
||||
ArrayList<Uri> fileUriList = localFileTransferActivity.getFileUriArrayList();
|
||||
ArrayList<Uri> fileUriList = wifiDirectManager.getFileUriArrayList();
|
||||
for (
|
||||
Uri fileUri : fileUriList) { // Send the names of each of those files, in order
|
||||
objectOutputStream.writeObject(getFileName(fileUri));
|
||||
@ -127,7 +124,8 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
|
||||
|
||||
if (totalFilesObject.getClass().equals(String.class)) {
|
||||
int total = Integer.parseInt((String) totalFilesObject);
|
||||
localFileTransferActivity.setTotalFilesForTransfer(total);
|
||||
wifiDirectManager.setTotalFilesForTransfer(total);
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, "Metadata: "+total+" files");
|
||||
|
||||
ArrayList<FileItem> fileItems = new ArrayList<>();
|
||||
for (int i = 0; i < total; i++) { // Read names of each of those files, in order
|
||||
@ -135,10 +133,11 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
|
||||
|
||||
if (fileNameObject.getClass().equals(String.class)) {
|
||||
fileItems.add(new FileItem((String) fileNameObject, TO_BE_SENT));
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, "Expecting "+fileNameObject);
|
||||
}
|
||||
}
|
||||
|
||||
localFileTransferActivity.setFileItems(fileItems);
|
||||
wifiDirectManager.setFileItems(fileItems);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -152,7 +151,6 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(InetAddress inetAddress) {
|
||||
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
|
||||
localFileTransferActivity.setClientAddress(inetAddress);
|
||||
wifiDirectManager.setClientAddress(inetAddress);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.FileItem.Fil
|
||||
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.WifiDirectManager.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.WifiDirectManager.copyToOutputStream;
|
||||
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.showToast;
|
||||
|
||||
/**
|
||||
@ -38,6 +38,7 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
|
||||
private WeakReference<LocalFileTransferActivity> weakReferenceToActivity;
|
||||
private int fileItemIndex;
|
||||
private String incomingFileName;
|
||||
|
||||
public ReceiverDeviceAsyncTask(LocalFileTransferActivity localFileTransferActivity) {
|
||||
this.weakReferenceToActivity = new WeakReference<>(localFileTransferActivity);
|
||||
@ -49,14 +50,16 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, "Server: Socket opened at " + FILE_TRANSFER_PORT);
|
||||
|
||||
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
|
||||
final String KIWIX_ROOT = localFileTransferActivity.getZimStorageRootPath();
|
||||
int totalFileCount = localFileTransferActivity.getTotalFilesForTransfer();
|
||||
final String KIWIX_ROOT = localFileTransferActivity.wifiDirectManager.getZimStorageRootPath();
|
||||
int totalFileCount = localFileTransferActivity.wifiDirectManager.getTotalFilesForTransfer();
|
||||
boolean result = true;
|
||||
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, "Expecting "+totalFileCount+" files");
|
||||
|
||||
for (int currentFile = 1; currentFile <= totalFileCount && !isCancelled(); currentFile++) {
|
||||
fileItemIndex = currentFile - 1;
|
||||
ArrayList<FileItem> fileItems = localFileTransferActivity.getFileItems();
|
||||
String incomingFileName = fileItems.get(fileItemIndex).getFileName();
|
||||
ArrayList<FileItem> fileItems = localFileTransferActivity.wifiDirectManager.getFileItems();
|
||||
incomingFileName = fileItems.get(fileItemIndex).getFileName();
|
||||
|
||||
try (Socket client = serverSocket.accept()) {
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, "Server: Client connected for file " + currentFile);
|
||||
@ -79,11 +82,10 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, e.getMessage());
|
||||
result = false;
|
||||
showToast(localFileTransferActivity, localFileTransferActivity.getString(R.string.error_transferring, incomingFileName), Toast.LENGTH_SHORT);
|
||||
publishProgress(fileItemIndex, ERROR);
|
||||
}
|
||||
|
||||
localFileTransferActivity.incrementTotalFilesSent();
|
||||
localFileTransferActivity.wifiDirectManager.incrementTotalFilesSent();
|
||||
}
|
||||
|
||||
return (!isCancelled() && result);
|
||||
@ -100,6 +102,10 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
int fileStatus = values[1];
|
||||
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
|
||||
localFileTransferActivity.changeStatus(fileIndex, fileStatus);
|
||||
|
||||
if(fileStatus == ERROR) {
|
||||
showToast(localFileTransferActivity, localFileTransferActivity.getString(R.string.error_transferring, incomingFileName), Toast.LENGTH_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onCancelled() {
|
||||
|
@ -18,8 +18,8 @@ import java.net.Socket;
|
||||
|
||||
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.FileItem.FileStatus.*;
|
||||
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.WifiDirectManager.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.WifiDirectManager.copyToOutputStream;
|
||||
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.WifiDirectManager.getFileName;
|
||||
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.showToast;
|
||||
|
||||
/**
|
||||
@ -47,6 +47,16 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Integer, Boolean> {
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Uri... fileUris) {
|
||||
|
||||
/*try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, e.getMessage());
|
||||
return false;
|
||||
}*/
|
||||
|
||||
for(int i = 0; i < 2000000000; i++);
|
||||
|
||||
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
|
||||
ContentResolver contentResolver = localFileTransferActivity.getContentResolver();
|
||||
|
||||
@ -64,7 +74,7 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Integer, Boolean> {
|
||||
}
|
||||
socket.bind(null);
|
||||
|
||||
String hostAddress = localFileTransferActivity.getFileReceiverDeviceAddress().getHostAddress();
|
||||
String hostAddress = localFileTransferActivity.wifiDirectManager.getFileReceiverDeviceAddress().getHostAddress();
|
||||
socket.connect((new InetSocketAddress(hostAddress, FILE_TRANSFER_PORT)), 15000);
|
||||
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, "Sender socket - " + socket.isConnected());
|
||||
@ -79,12 +89,12 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Integer, Boolean> {
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, e.getMessage());
|
||||
e.printStackTrace();
|
||||
result = false;
|
||||
showToast(localFileTransferActivity, localFileTransferActivity.getString(R.string.error_transferring, getFileName(localFileTransferActivity.getFileUriArrayList().get(fileItemIndex))), Toast.LENGTH_SHORT);
|
||||
publishProgress(fileItemIndex, ERROR);
|
||||
|
||||
}
|
||||
localFileTransferActivity.incrementTotalFilesSent();
|
||||
|
||||
localFileTransferActivity.wifiDirectManager.incrementTotalFilesSent();
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -96,6 +106,10 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Integer, Boolean> {
|
||||
int fileStatus = values[1];
|
||||
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
|
||||
localFileTransferActivity.changeStatus(fileIndex, fileStatus);
|
||||
|
||||
if(fileStatus == ERROR) {
|
||||
showToast(localFileTransferActivity, localFileTransferActivity.getString(R.string.error_transferring, getFileName(localFileTransferActivity.wifiDirectManager.getFileUriArrayList().get(fileItemIndex))), Toast.LENGTH_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onCancelled() {
|
||||
@ -106,7 +120,7 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Integer, Boolean> {
|
||||
protected void onPostExecute(Boolean fileSendSuccessful) {
|
||||
final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get();
|
||||
|
||||
if (localFileTransferActivity.allFilesSent()) {
|
||||
if (localFileTransferActivity.wifiDirectManager.allFilesSent()) {
|
||||
showToast(localFileTransferActivity, R.string.file_transfer_complete,
|
||||
Toast.LENGTH_SHORT);
|
||||
localFileTransferActivity.finish();
|
||||
|
@ -3,6 +3,7 @@ package org.kiwix.kiwixmobile.zim_manager.local_file_transfer;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WpsInfo;
|
||||
import android.net.wifi.p2p.WifiP2pConfig;
|
||||
import android.net.wifi.p2p.WifiP2pDevice;
|
||||
@ -14,14 +15,21 @@ import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import org.kiwix.kiwixmobile.BuildConfig;
|
||||
import org.kiwix.kiwixmobile.R;
|
||||
import org.kiwix.kiwixmobile.utils.AlertDialogShower;
|
||||
import org.kiwix.kiwixmobile.utils.KiwixDialog;
|
||||
import org.kiwix.kiwixmobile.utils.SharedPreferenceUtil;
|
||||
|
||||
import static android.os.Looper.getMainLooper;
|
||||
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.showToast;
|
||||
|
||||
|
||||
@ -36,6 +44,9 @@ public class WifiDirectManager implements WifiP2pManager.ChannelListener, WifiP2
|
||||
|
||||
@NonNull LocalFileTransferActivity activity;
|
||||
|
||||
private SharedPreferenceUtil sharedPreferenceUtil;
|
||||
private AlertDialogShower alertDialogShower;
|
||||
|
||||
/* 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
|
||||
@ -50,15 +61,40 @@ public class WifiDirectManager implements WifiP2pManager.ChannelListener, WifiP2
|
||||
private WifiP2pInfo groupInfo; // Corresponds to P2P group formed between the two devices
|
||||
|
||||
private WifiP2pDevice senderSelectedPeerDevice = null;
|
||||
private AlertDialogShower alertDialogShower;
|
||||
|
||||
private PeerGroupHandshakeAsyncTask peerGroupHandshakeAsyncTask;
|
||||
private SenderDeviceAsyncTask senderDeviceAsyncTaskArray;
|
||||
private ReceiverDeviceAsyncTask receiverDeviceAsyncTask;
|
||||
|
||||
private boolean isFileTransferInProgress = false;
|
||||
private InetAddress selectedPeerDeviceInetAddress;
|
||||
private InetAddress fileReceiverDeviceAddress; // IP address of the file receiving device
|
||||
|
||||
private int totalFilesForTransfer = -1;
|
||||
private int filesSent = 0; // Count of number of files transferred until now
|
||||
private ArrayList<FileItem> filesToSend = new ArrayList<>();
|
||||
|
||||
private ArrayList<Uri> fileUriArrayList; // For sender device, stores uris of the files
|
||||
public boolean isFileSender = false; // Whether the device is the file sender or not
|
||||
|
||||
public WifiDirectManager(@NonNull LocalFileTransferActivity activity) {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
/* Initialisations for using the WiFi P2P API */
|
||||
public void createWifiDirectManager(@NonNull AlertDialogShower alertDialogShower) {
|
||||
public void createWifiDirectManager(@NonNull SharedPreferenceUtil sharedPreferenceUtil,
|
||||
@NonNull AlertDialogShower alertDialogShower, @Nullable ArrayList<Uri> fileUriArrayList) {
|
||||
this.sharedPreferenceUtil = sharedPreferenceUtil;
|
||||
this.alertDialogShower = alertDialogShower;
|
||||
this.fileUriArrayList = fileUriArrayList;
|
||||
this.isFileSender = (fileUriArrayList != null && fileUriArrayList.size() > 0);
|
||||
|
||||
if(isFileSender) {
|
||||
this.totalFilesForTransfer = fileUriArrayList.size();
|
||||
for (int i = 0; i < fileUriArrayList.size(); i++) {
|
||||
filesToSend.add(new FileItem(getFileName(fileUriArrayList.get(i)), TO_BE_SENT));
|
||||
}
|
||||
}
|
||||
|
||||
manager = (WifiP2pManager) activity.getSystemService(Context.WIFI_P2P_SERVICE);
|
||||
channel = manager.initialize(activity, getMainLooper(), null);
|
||||
@ -149,18 +185,14 @@ public class WifiDirectManager implements WifiP2pManager.ChannelListener, WifiP2
|
||||
@Override
|
||||
public void onConnectionInfoAvailable(@NonNull WifiP2pInfo groupInfo) {
|
||||
/* Devices have successfully connected, and 'info' holds information about the wifi p2p group formed */
|
||||
setGroupInfo(groupInfo);
|
||||
((Callbacks) activity).performHandshakeWithSelectedPeerDevice(groupInfo);
|
||||
this.groupInfo = groupInfo;
|
||||
performHandshakeWithSelectedPeerDevice();
|
||||
}
|
||||
|
||||
public void setUserDevice(@NonNull WifiP2pDevice userDevice) {
|
||||
this.userDevice = userDevice;
|
||||
}
|
||||
|
||||
public void setGroupInfo(@NonNull WifiP2pInfo groupInfo) {
|
||||
this.groupInfo = groupInfo;
|
||||
}
|
||||
|
||||
public boolean isGroupFormed() {
|
||||
return groupInfo.groupFormed;
|
||||
}
|
||||
@ -212,11 +244,127 @@ public class WifiDirectManager implements WifiP2pManager.ChannelListener, WifiP2
|
||||
});
|
||||
}
|
||||
|
||||
public void performHandshakeWithSelectedPeerDevice() {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d(TAG, "Starting handshake");
|
||||
}
|
||||
peerGroupHandshakeAsyncTask = new PeerGroupHandshakeAsyncTask(this);
|
||||
peerGroupHandshakeAsyncTask.execute();
|
||||
}
|
||||
|
||||
public boolean isFileSender() {
|
||||
return isFileSender;
|
||||
}
|
||||
|
||||
public @NonNull ArrayList<Uri> getFileUriArrayList() {
|
||||
return fileUriArrayList;
|
||||
}
|
||||
|
||||
public int getTotalFilesForTransfer() {
|
||||
return totalFilesForTransfer;
|
||||
}
|
||||
|
||||
public void setTotalFilesForTransfer(int totalFilesForTransfer) {
|
||||
this.totalFilesForTransfer = totalFilesForTransfer;
|
||||
}
|
||||
|
||||
public @NonNull ArrayList<FileItem> getFileItems() {
|
||||
return filesToSend;
|
||||
}
|
||||
|
||||
public void setFileItems(@NonNull ArrayList<FileItem> fileItems) {
|
||||
this.filesToSend = fileItems;
|
||||
}
|
||||
|
||||
public void incrementTotalFilesSent() {
|
||||
this.filesSent++;
|
||||
}
|
||||
|
||||
public boolean allFilesSent() {
|
||||
return (filesSent == totalFilesForTransfer);
|
||||
}
|
||||
|
||||
public @NonNull String getZimStorageRootPath() {
|
||||
return (sharedPreferenceUtil.getPrefStorage() + "/Kiwix/");
|
||||
}
|
||||
|
||||
public @NonNull InetAddress getFileReceiverDeviceAddress() {
|
||||
return fileReceiverDeviceAddress;
|
||||
}
|
||||
|
||||
public static void copyToOutputStream(@NonNull InputStream inputStream, @NonNull
|
||||
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");
|
||||
}
|
||||
|
||||
public void setClientAddress(@Nullable InetAddress clientAddress) {
|
||||
if (clientAddress == null) {
|
||||
// null is returned only in case of a failed handshake
|
||||
showToast(activity, R.string.device_not_cooperating, Toast.LENGTH_LONG);
|
||||
activity.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// If control reaches here, means handshake was successful
|
||||
selectedPeerDeviceInetAddress = clientAddress;
|
||||
startFileTransfer();
|
||||
}
|
||||
|
||||
private void startFileTransfer() {
|
||||
isFileTransferInProgress = true;
|
||||
|
||||
if (isGroupFormed() && !isFileSender) {
|
||||
((Callbacks) activity).displayFileTransferProgress(filesToSend);
|
||||
|
||||
receiverDeviceAsyncTask = new ReceiverDeviceAsyncTask(activity);
|
||||
receiverDeviceAsyncTask.execute();
|
||||
} else if (isGroupFormed()) { // && isFileSender
|
||||
{
|
||||
Log.d(LocalFileTransferActivity.TAG, "Starting file transfer");
|
||||
|
||||
fileReceiverDeviceAddress =
|
||||
(isGroupOwner()) ? selectedPeerDeviceInetAddress
|
||||
: getGroupOwnerAddress();
|
||||
|
||||
// Hack for allowing slower receiver devices to setup server before sender device requests to connect
|
||||
showToast(activity, R.string.preparing_files, Toast.LENGTH_LONG);
|
||||
//for (int i = 0; i < 20000000; i++) ;
|
||||
|
||||
senderDeviceAsyncTaskArray = new SenderDeviceAsyncTask(activity);
|
||||
senderDeviceAsyncTaskArray.execute(fileUriArrayList.toArray(new Uri[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cancelAsyncTasks() {
|
||||
if (peerGroupHandshakeAsyncTask != null) {
|
||||
peerGroupHandshakeAsyncTask.cancel(true);
|
||||
}
|
||||
|
||||
if (senderDeviceAsyncTaskArray != null) {
|
||||
senderDeviceAsyncTaskArray.cancel(true);
|
||||
|
||||
} else if (receiverDeviceAsyncTask != null) {
|
||||
receiverDeviceAsyncTask.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Shift async tasks to WDM and handle cleanup from here itself
|
||||
public void destroyWifiDirectManager() {
|
||||
activity.cancelAsyncTasks();
|
||||
cancelAsyncTasks();
|
||||
|
||||
if (!activity.isFileSender) {
|
||||
if (!isFileSender) {
|
||||
disconnect();
|
||||
} else {
|
||||
closeChannel();
|
||||
@ -261,9 +409,35 @@ public class WifiDirectManager implements WifiP2pManager.ChannelListener, WifiP2
|
||||
}
|
||||
}
|
||||
|
||||
public static @NonNull 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";
|
||||
}
|
||||
}
|
||||
|
||||
public static @NonNull String getFileName(@NonNull Uri fileUri) {
|
||||
String fileUriString = fileUri.toString();
|
||||
// Returns text after location of last slash in the file path
|
||||
return fileUriString.substring(fileUriString.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
public interface Callbacks {
|
||||
void updatePeerDevicesList(@NonNull WifiP2pDeviceList peers);
|
||||
|
||||
void performHandshakeWithSelectedPeerDevice(@NonNull WifiP2pInfo groupInfo);
|
||||
void displayFileTransferProgress(ArrayList<FileItem> filesToSend);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import org.kiwix.kiwixmobile.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTransferActivity.getDeviceStatus;
|
||||
import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.WifiDirectManager.getDeviceStatus;
|
||||
|
||||
/**
|
||||
* Helper class, part of the local file sharing module.
|
||||
|
Loading…
x
Reference in New Issue
Block a user