Restyle: Applied project code style to entire local_file_transfer sub-package

This commit is contained in:
Aditya-Sood 2019-07-17 13:14:38 +05:30
parent d4ffe18ad8
commit 57e3aa0182
11 changed files with 293 additions and 230 deletions

View File

@ -51,11 +51,12 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTra
* File transfer involves two phases: * File transfer involves two phases:
* 1) Handshake with the selected peer device, using {@link PeerGroupHandshakeAsyncTask} * 1) Handshake with the selected peer device, using {@link PeerGroupHandshakeAsyncTask}
* 2) After handshake, starting the files transfer using {@link SenderDeviceAsyncTask} on the sender * 2) After handshake, starting the files transfer using {@link SenderDeviceAsyncTask} on the sender
* device and {@link ReceiverDeviceAsyncTask} files receiving device * device and {@link ReceiverDeviceAsyncTask} files receiving device
* *
* The starting point for the module is {@link LocalFileTransferActivity} * 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 final String TAG = "DeviceListFragment";
public static int PEER_HANDSHAKE_PORT = 8009; public static int PEER_HANDSHAKE_PORT = 8009;
@ -64,8 +65,10 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
private SharedPreferenceUtil sharedPreferenceUtil; private SharedPreferenceUtil sharedPreferenceUtil;
private AlertDialogShower alertDialogShower; private AlertDialogShower alertDialogShower;
private LocalFileTransferActivity localFileTransferActivity; // Parent activity, starting point of the module private LocalFileTransferActivity localFileTransferActivity;
private TransferProgressFragment transferProgressFragment; // Sibling fragment, for displaying transfer progress // Parent activity, starting point of the module
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.text_view_device_name) TextView deviceName;
@ -75,13 +78,15 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
private Unbinder unbinder; private Unbinder unbinder;
private boolean fileSender = false; // Whether file sending device or not 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 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 int filesSent = 0; // Count of number of files transferred until now
private ArrayList<FileItem> filesToSend = new ArrayList<>(); private ArrayList<FileItem> filesToSend = new ArrayList<>();
private WifiP2pDevice userDevice; // Represents the device on which the app is running 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 WifiP2pInfo groupInfo;
// Corresponds to the WiFi P2P group formed between the two devices
private List<WifiP2pDevice> peerDevices = new ArrayList<WifiP2pDevice>(); private List<WifiP2pDevice> peerDevices = new ArrayList<WifiP2pDevice>();
private WifiP2pDevice selectedPeerDevice = null; private WifiP2pDevice selectedPeerDevice = null;
@ -100,24 +105,25 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
localFileTransferActivity = (LocalFileTransferActivity) getActivity(); localFileTransferActivity = (LocalFileTransferActivity) getActivity();
// As DeviceListFragment extends ListFragment for the purpose of displaying list of peers // 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; fileSender = true;
fileUriList = localFileTransferActivity.getFileUriArrayList(); fileUriList = localFileTransferActivity.getFileUriArrayList();
totalFilesForTransfer = fileUriList.size(); totalFilesForTransfer = fileUriList.size();
for(int i = 0; i < fileUriList.size(); i++) { for (int i = 0; i < fileUriList.size(); i++) {
filesToSend.add(new FileItem(getFileName(fileUriList.get(i)), TO_BE_SENT)); filesToSend.add(new FileItem(getFileName(fileUriList.get(i)), TO_BE_SENT));
} }
displayTransferProgressFragment(); displayTransferProgressFragment();
} }
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_device_list, null); View view = inflater.inflate(R.layout.fragment_device_list, null);
unbinder = ButterKnife.bind(this, view); unbinder = ButterKnife.bind(this, view);
@ -127,23 +133,25 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
if(unbinder != null) unbinder.unbind(); if (unbinder != null) unbinder.unbind();
} }
@Override @Override
public void onListItemClick(ListView l, View v, int position, long id) { 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) if (!isFileSender() || fileTransferStarted) {
return; return;
}
selectedPeerDevice = (WifiP2pDevice) getListAdapter().getItem(position); selectedPeerDevice = (WifiP2pDevice) getListAdapter().getItem(position);
alertDialogShower.show(new KiwixDialog.FileTransferConfirmation(selectedPeerDevice), new Function0<Unit>() { alertDialogShower.show(new KiwixDialog.FileTransferConfirmation(selectedPeerDevice),
@Override public Unit invoke() { new Function0<Unit>() {
((DeviceActionListener) localFileTransferActivity).connect(selectedPeerDevice); @Override public Unit invoke() {
showToast(localFileTransferActivity, R.string.performing_handshake, Toast.LENGTH_LONG); ((DeviceActionListener) localFileTransferActivity).connect(selectedPeerDevice);
return Unit.INSTANCE; showToast(localFileTransferActivity, R.string.performing_handshake, Toast.LENGTH_LONG);
} return Unit.INSTANCE;
}); }
});
} }
private void displayTransferProgressFragment() { private void displayTransferProgressFragment() {
@ -157,7 +165,7 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
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; this.userDevice = device;
if(userDevice != null) { if (userDevice != null) {
deviceName.setText(userDevice.deviceName); deviceName.setText(userDevice.deviceName);
Log.d(TAG, getDeviceStatus(userDevice.status)); Log.d(TAG, getDeviceStatus(userDevice.status));
} }
@ -165,15 +173,21 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
public static String getDeviceStatus(int status) { public static String getDeviceStatus(int status) {
if(BuildConfig.DEBUG) Log.d(TAG, "Peer Status: " + status); if (BuildConfig.DEBUG) Log.d(TAG, "Peer Status: " + status);
switch (status) { switch (status) {
case WifiP2pDevice.AVAILABLE : return "Available"; case WifiP2pDevice.AVAILABLE:
case WifiP2pDevice.INVITED : return "Invited"; return "Available";
case WifiP2pDevice.CONNECTED : return "Connected"; case WifiP2pDevice.INVITED:
case WifiP2pDevice.FAILED : return "Failed"; return "Invited";
case WifiP2pDevice.UNAVAILABLE:return "Unavailable"; case WifiP2pDevice.CONNECTED:
return "Connected";
case WifiP2pDevice.FAILED:
return "Failed";
case WifiP2pDevice.UNAVAILABLE:
return "Unavailable";
default: return "Unknown"; default:
return "Unknown";
} }
} }
@ -187,7 +201,7 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
peerDevices.addAll(peers.getDeviceList()); peerDevices.addAll(peers.getDeviceList());
((WifiPeerListAdapter) getListAdapter()).notifyDataSetChanged(); ((WifiPeerListAdapter) getListAdapter()).notifyDataSetChanged();
if(peerDevices.size() == 0) { if (peerDevices.size() == 0) {
Log.d(LocalFileTransferActivity.TAG, "No devices found"); Log.d(LocalFileTransferActivity.TAG, "No devices found");
} }
} }
@ -198,15 +212,15 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
} }
void cancelAsyncTasks() { void cancelAsyncTasks() {
if(peerGroupHandshakeAsyncTask != null) { if (peerGroupHandshakeAsyncTask != null) {
peerGroupHandshakeAsyncTask.cancel(true); peerGroupHandshakeAsyncTask.cancel(true);
} }
if(senderDeviceAsyncTaskArray != null) { if (senderDeviceAsyncTaskArray != null) {
for(SenderDeviceAsyncTask task : senderDeviceAsyncTaskArray) { for (SenderDeviceAsyncTask task : senderDeviceAsyncTaskArray) {
task.cancel(true); task.cancel(true);
} }
} else if(receiverDeviceAsyncTask != null) { } else if (receiverDeviceAsyncTask != null) {
receiverDeviceAsyncTask.cancel(true); receiverDeviceAsyncTask.cancel(true);
} }
} }
@ -227,7 +241,7 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
} }
public void setClientAddress(InetAddress clientAddress) { public void setClientAddress(InetAddress clientAddress) {
if(clientAddress == null) { if (clientAddress == null) {
// null is returned only in case of a failed handshake // null is returned only in case of a failed handshake
showToast(localFileTransferActivity, R.string.device_not_cooperating, Toast.LENGTH_LONG); showToast(localFileTransferActivity, R.string.device_not_cooperating, Toast.LENGTH_LONG);
localFileTransferActivity.closeLocalFileTransferActivity(); localFileTransferActivity.closeLocalFileTransferActivity();
@ -242,25 +256,26 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
private void startFileTransfer() { private void startFileTransfer() {
fileTransferStarted = true; fileTransferStarted = true;
if(groupInfo.groupFormed && !fileSender) { if (groupInfo.groupFormed && !fileSender) {
displayTransferProgressFragment(); displayTransferProgressFragment();
receiverDeviceAsyncTask = new ReceiverDeviceAsyncTask(this, transferProgressFragment); receiverDeviceAsyncTask = new ReceiverDeviceAsyncTask(this, transferProgressFragment);
receiverDeviceAsyncTask.execute(); receiverDeviceAsyncTask.execute();
} else if (groupInfo.groupFormed) {
} else if(groupInfo.groupFormed) {
{ {
Log.d(LocalFileTransferActivity.TAG, "Starting file transfer"); Log.d(LocalFileTransferActivity.TAG, "Starting file transfer");
fileReceiverDeviceAddress = (groupInfo.isGroupOwner) ? selectedPeerDeviceInetAddress : groupInfo.groupOwnerAddress; fileReceiverDeviceAddress =
(groupInfo.isGroupOwner) ? selectedPeerDeviceInetAddress : groupInfo.groupOwnerAddress;
// Hack for allowing slower receiver devices to setup server before sender device requests to connect // Hack for allowing slower receiver devices to setup server before sender device requests to connect
showToast(localFileTransferActivity, R.string.preparing_files, Toast.LENGTH_LONG); showToast(localFileTransferActivity, R.string.preparing_files, Toast.LENGTH_LONG);
for(int i = 0; i < 20000000; i++); for (int i = 0; i < 20000000; i++) ;
senderDeviceAsyncTaskArray = new SenderDeviceAsyncTask[totalFilesForTransfer]; senderDeviceAsyncTaskArray = new SenderDeviceAsyncTask[totalFilesForTransfer];
for(int i = 0; i < totalFilesForTransfer; i++) { for (int i = 0; i < totalFilesForTransfer; i++) {
senderDeviceAsyncTaskArray[i] = new SenderDeviceAsyncTask(this, transferProgressFragment, i); senderDeviceAsyncTaskArray[i] =
new SenderDeviceAsyncTask(this, transferProgressFragment, i);
senderDeviceAsyncTaskArray[i].execute(fileUriList.get(i)); senderDeviceAsyncTaskArray[i].execute(fileUriList.get(i));
} }
} }
@ -305,7 +320,8 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
return (filesSent == totalFilesForTransfer); return (filesSent == totalFilesForTransfer);
} }
public void performFieldInjection(SharedPreferenceUtil sharedPreferenceUtil, AlertDialogShower alertDialogShower) { public void performFieldInjection(SharedPreferenceUtil sharedPreferenceUtil,
AlertDialogShower alertDialogShower) {
this.sharedPreferenceUtil = sharedPreferenceUtil; this.sharedPreferenceUtil = sharedPreferenceUtil;
this.alertDialogShower = alertDialogShower; this.alertDialogShower = alertDialogShower;
} }
@ -318,14 +334,14 @@ public class DeviceListFragment extends ListFragment implements WifiP2pManager.P
return fileReceiverDeviceAddress; return fileReceiverDeviceAddress;
} }
public static String getFileName(Uri fileUri) { public static String getFileName(Uri fileUri) {
String fileUriString = fileUri.toString(); String fileUriString = fileUri.toString();
// Returns text after location of last slash in the file path // Returns text after location of last slash in the file path
return fileUriString.substring(fileUriString.lastIndexOf('/')+1); return fileUriString.substring(fileUriString.lastIndexOf('/') + 1);
} }
public static void copyToOutputStream(InputStream inputStream, OutputStream outputStream) throws IOException { public static void copyToOutputStream(InputStream inputStream, OutputStream outputStream)
throws IOException {
byte[] bufferForBytes = new byte[1024]; byte[] bufferForBytes = new byte[1024];
int bytesRead; int bytesRead;

View File

@ -13,11 +13,11 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.FileItem.Fil
* Helper class, part of the local file sharing module. * Helper class, part of the local file sharing module.
* *
* Defines a file-item to represent the files being transferred. * Defines a file-item to represent the files being transferred.
* */ */
public class FileItem implements Parcelable { public class FileItem implements Parcelable {
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({TO_BE_SENT, SENDING, SENT, ERROR}) @IntDef({ TO_BE_SENT, SENDING, SENT, ERROR })
public @interface FileStatus { public @interface FileStatus {
int TO_BE_SENT = -1; // File yet to be sent int TO_BE_SENT = -1; // File yet to be sent
int SENDING = 0; // Being sent int SENDING = 0; // Being sent

View File

@ -20,7 +20,7 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.FileItem.Fil
* Helper class, part of the local file sharing module. * Helper class, part of the local file sharing module.
* *
* Defines the Adapter for the list of file-items displayed in {@link TransferProgressFragment} * Defines the Adapter for the list of file-items displayed in {@link TransferProgressFragment}
* */ */
public class FileListAdapter extends RecyclerView.Adapter<FileListAdapter.FileViewHolder> { public class FileListAdapter extends RecyclerView.Adapter<FileListAdapter.FileViewHolder> {
private final ArrayList<FileItem> fileItems; private final ArrayList<FileItem> fileItems;
@ -30,8 +30,10 @@ public class FileListAdapter extends RecyclerView.Adapter<FileListAdapter.FileVi
@NonNull @NonNull
@Override @Override
public FileListAdapter.FileViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public FileListAdapter.FileViewHolder onCreateViewHolder(@NonNull ViewGroup parent,
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_transfer_list, parent, false); int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_transfer_list, parent, false);
return new FileViewHolder(itemView, this); return new FileViewHolder(itemView, this);
} }
@ -42,18 +44,20 @@ public class FileListAdapter extends RecyclerView.Adapter<FileListAdapter.FileVi
String name = fileItem.getFileName(); String name = fileItem.getFileName();
holder.fileName.setText(name); holder.fileName.setText(name);
if(fileItem.getFileStatus() == SENDING) { if (fileItem.getFileStatus() == SENDING) {
holder.statusImage.setVisibility(View.GONE); holder.statusImage.setVisibility(View.GONE);
holder.progressBar.setVisibility(View.VISIBLE); holder.progressBar.setVisibility(View.VISIBLE);
} else if (fileItem.getFileStatus()
} else if(fileItem.getFileStatus() != TO_BE_SENT){ // Icon for TO_BE_SENT is assigned by default in the item layout != TO_BE_SENT) { // Icon for TO_BE_SENT is assigned by default in the item layout
holder.progressBar.setVisibility(View.GONE); holder.progressBar.setVisibility(View.GONE);
switch (fileItem.getFileStatus()) { switch (fileItem.getFileStatus()) {
case SENT : holder.statusImage.setImageResource(R.drawable.ic_baseline_check_24px); case SENT:
break; holder.statusImage.setImageResource(R.drawable.ic_baseline_check_24px);
case ERROR: holder.statusImage.setImageResource(R.drawable.ic_baseline_error_24px); break;
break; case ERROR:
holder.statusImage.setImageResource(R.drawable.ic_baseline_error_24px);
break;
} }
holder.statusImage.setVisibility(View.VISIBLE); holder.statusImage.setVisibility(View.VISIBLE);

View File

@ -52,10 +52,12 @@ import javax.inject.Inject;
* *
* The module uses this activity along with {@link DeviceListFragment} to manage connection * The module uses this activity along with {@link DeviceListFragment} to manage connection
* and file transfer between the devices. * and file transfer between the devices.
* */ */
public class LocalFileTransferActivity extends AppCompatActivity implements WifiP2pManager.ChannelListener, DeviceListFragment.DeviceActionListener { public class LocalFileTransferActivity extends AppCompatActivity
implements WifiP2pManager.ChannelListener, DeviceListFragment.DeviceActionListener {
public static final String TAG = "LocalFileTransferActvty"; // Not a typo, 'Log' tags have a length upper limit of 25 characters public static final String TAG = "LocalFileTransferActvty";
// Not a typo, 'Log' tags have a length upper limit of 25 characters
public static final int REQUEST_ENABLE_WIFI_P2P = 1; public static final int REQUEST_ENABLE_WIFI_P2P = 1;
public static final int REQUEST_ENABLE_LOCATION_SERVICES = 2; public static final int REQUEST_ENABLE_LOCATION_SERVICES = 2;
private static final int PERMISSION_REQUEST_CODE_COARSE_LOCATION = 1; private static final int PERMISSION_REQUEST_CODE_COARSE_LOCATION = 1;
@ -66,18 +68,20 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
@BindView(R.id.toolbar_local_file_transfer) Toolbar actionBar; @BindView(R.id.toolbar_local_file_transfer) Toolbar actionBar;
private ArrayList<Uri> fileUriArrayList; // For sender device, stores Uris of files to be transferred private ArrayList<Uri> fileUriArrayList;
// For sender device, stores Uris of files to be transferred
private Boolean fileSendingDevice = false;// Whether the device is the file sender or not private Boolean fileSendingDevice = false;// Whether the device is the file sender or not
/* Variables related to the WiFi P2P API */ /* Variables related to the WiFi P2P API */
private boolean wifiP2pEnabled = false; // Whether WiFi has been enabled or not private boolean wifiP2pEnabled = false; // Whether WiFi has been enabled or not
private boolean retryChannel = false; // Whether channel has retried connecting previously private boolean retryChannel = false; // Whether channel has retried connecting previously
private WifiP2pManager manager; // Overall manager of Wifi p2p connections for the module 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 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 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 private BroadcastReceiver receiver = null; // For receiving the broadcasts given by above filter
@Override @Override
@ -91,21 +95,21 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
ButterKnife.bind(this); ButterKnife.bind(this);
/* /*
* Presence of file Uris decides whether the device with the activity open is a sender or receiver: * Presence of file Uris decides whether the device with the activity open is a sender or receiver:
* - On the sender device, this activity is started from the app chooser post selection * - On the sender device, this activity is started from the app chooser post selection
* of files to share in the Library * of files to share in the Library
* - On the receiver device, the activity is started directly from within the 'Get Content' * - On the receiver device, the activity is started directly from within the 'Get Content'
* activity, without any file Uris * activity, without any file Uris
* */ * */
Intent filesIntent = getIntent(); Intent filesIntent = getIntent();
fileUriArrayList = filesIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); fileUriArrayList = filesIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if(fileUriArrayList != null && fileUriArrayList.size() > 0) { if (fileUriArrayList != null && fileUriArrayList.size() > 0) {
setDeviceAsFileSender(); setDeviceAsFileSender();
} }
setSupportActionBar(actionBar); setSupportActionBar(actionBar);
actionBar.setNavigationIcon(R.drawable.ic_close_white_24dp); actionBar.setNavigationIcon(R.drawable.ic_close_white_24dp);
actionBar.setNavigationOnClickListener(new View.OnClickListener(){ actionBar.setNavigationOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
closeLocalFileTransferActivity(); closeLocalFileTransferActivity();
@ -133,48 +137,51 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.menu_item_search_devices) { if (item.getItemId() == R.id.menu_item_search_devices) {
/* Permissions essential for this module */ /* Permissions essential for this module */
if(!checkCoarseLocationAccessPermission()) return true; if (!checkCoarseLocationAccessPermission()) return true;
if(!checkExternalStorageWritePermission()) return true; if (!checkExternalStorageWritePermission()) return true;
// Initiate discovery // Initiate discovery
if(!isWifiP2pEnabled()) { if (!isWifiP2pEnabled()) {
requestEnableWifiP2pServices(); requestEnableWifiP2pServices();
return true; return true;
} }
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !isLocationServicesEnabled()) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !isLocationServicesEnabled()) {
requestEnableLocationServices(); requestEnableLocationServices();
return true; return true;
} }
final DeviceListFragment deviceListFragment = (DeviceListFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_device_list); final DeviceListFragment deviceListFragment =
(DeviceListFragment) getSupportFragmentManager().findFragmentById(
R.id.fragment_device_list);
deviceListFragment.onInitiateDiscovery(); deviceListFragment.onInitiateDiscovery();
deviceListFragment.performFieldInjection(sharedPreferenceUtil, alertDialogShower); deviceListFragment.performFieldInjection(sharedPreferenceUtil, alertDialogShower);
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() { manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
@Override @Override
public void onSuccess() { public void onSuccess() {
showToast(LocalFileTransferActivity.this, R.string.discovery_initiated, Toast.LENGTH_SHORT); showToast(LocalFileTransferActivity.this, R.string.discovery_initiated,
Toast.LENGTH_SHORT);
} }
@Override @Override
public void onFailure(int reason) { public void onFailure(int reason) {
String errorMessage = getErrorMessage(reason); String errorMessage = getErrorMessage(reason);
Log.d(TAG, getString(R.string.discovery_failed) + ": " + errorMessage); Log.d(TAG, getString(R.string.discovery_failed) + ": " + errorMessage);
showToast(LocalFileTransferActivity.this, LocalFileTransferActivity.this.getString(R.string.discovery_failed), Toast.LENGTH_SHORT); showToast(LocalFileTransferActivity.this,
LocalFileTransferActivity.this.getString(R.string.discovery_failed),
Toast.LENGTH_SHORT);
} }
}); });
return true; return true;
} else { } else {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
} }
/* Helper methods used in the activity */ /* Helper methods used in the activity */
public void setDeviceAsFileSender() { public void setDeviceAsFileSender() {
fileSendingDevice = true; fileSendingDevice = true;
@ -198,28 +205,36 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
private String getErrorMessage(int reason) { private String getErrorMessage(int reason) {
switch (reason) { switch (reason) {
case WifiP2pManager.ERROR: return "Internal error"; case WifiP2pManager.ERROR:
case WifiP2pManager.BUSY: return "Framework busy, unable to service request"; return "Internal error";
case WifiP2pManager.P2P_UNSUPPORTED: return "P2P unsupported on this device"; case WifiP2pManager.BUSY:
return "Framework busy, unable to service request";
case WifiP2pManager.P2P_UNSUPPORTED:
return "P2P unsupported on this device";
default: return "Unknown error code - "+reason; default:
return "Unknown error code - " + reason;
} }
} }
public void resetPeers() { public void resetPeers() {
DeviceListFragment deviceListFragment = (DeviceListFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_device_list); DeviceListFragment deviceListFragment =
if(deviceListFragment != null) { (DeviceListFragment) getSupportFragmentManager().findFragmentById(
R.id.fragment_device_list);
if (deviceListFragment != null) {
deviceListFragment.clearPeers(); deviceListFragment.clearPeers();
} }
} }
public void resetData() { public void resetData() {
DeviceListFragment deviceListFragment = (DeviceListFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_device_list); DeviceListFragment deviceListFragment =
if(deviceListFragment != null) { (DeviceListFragment) getSupportFragmentManager().findFragmentById(
R.id.fragment_device_list);
if (deviceListFragment != null) {
deviceListFragment.clearPeers(); deviceListFragment.clearPeers();
} }
} }
static void showToast(Context context, int stringResource, int duration) { static void showToast(Context context, int stringResource, int duration) {
showToast(context, context.getString(stringResource), duration); showToast(context, context.getString(stringResource), duration);
} }
@ -228,23 +243,20 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
Toast.makeText(context, text, duration).show(); Toast.makeText(context, text, duration).show();
} }
/* From WifiP2pManager.ChannelListener interface */ /* From WifiP2pManager.ChannelListener interface */
@Override @Override
public void onChannelDisconnected() { public void onChannelDisconnected() {
// Upon disconnection, retry one more time // Upon disconnection, retry one more time
if(manager != null && !retryChannel) { if (manager != null && !retryChannel) {
Log.d(TAG, "Channel lost, trying again"); Log.d(TAG, "Channel lost, trying again");
resetData(); resetData();
retryChannel = true; retryChannel = true;
manager.initialize(this, getMainLooper(), this); manager.initialize(this, getMainLooper(), this);
} else { } else {
showToast(this, R.string.severe_loss_error, Toast.LENGTH_LONG); showToast(this, R.string.severe_loss_error, Toast.LENGTH_LONG);
} }
} }
/* From DeviceListFragment.DeviceActionListener interface */ /* From DeviceListFragment.DeviceActionListener interface */
@Override @Override
public void connect(@NonNull final WifiP2pDevice peerDevice) { public void connect(@NonNull final WifiP2pDevice peerDevice) {
@ -262,15 +274,18 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
public void onFailure(int reason) { public void onFailure(int reason) {
String errorMessage = getErrorMessage(reason); String errorMessage = getErrorMessage(reason);
Log.d(TAG, getString(R.string.connection_failed) + ": " + errorMessage); Log.d(TAG, getString(R.string.connection_failed) + ": " + errorMessage);
showToast(LocalFileTransferActivity.this, getString(R.string.connection_failed), Toast.LENGTH_LONG); showToast(LocalFileTransferActivity.this, getString(R.string.connection_failed),
Toast.LENGTH_LONG);
} }
}); });
} }
@Override @Override
public void closeLocalFileTransferActivity() { public void closeLocalFileTransferActivity() {
final DeviceListFragment deviceListFragment = (DeviceListFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_device_list); final DeviceListFragment deviceListFragment =
if(deviceListFragment != null) { (DeviceListFragment) getSupportFragmentManager().findFragmentById(
R.id.fragment_device_list);
if (deviceListFragment != null) {
deviceListFragment.cancelAsyncTasks(); deviceListFragment.cancelAsyncTasks();
} }
@ -291,26 +306,28 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
public void onSuccess() { public void onSuccess() {
Log.d(TAG, "Disconnect successful"); Log.d(TAG, "Disconnect successful");
} }
}); });
} }
/* Helper methods used in the activity */ /* Helper methods used in the activity */
private boolean checkCoarseLocationAccessPermission() { // Required by Android to detect wifi-p2p peers private boolean checkCoarseLocationAccessPermission() { // Required by Android to detect wifi-p2p peers
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if(shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION)) {
alertDialogShower.show(KiwixDialog.LocationPermissionRationale.INSTANCE, new Function0<Unit>() {
@Override public Unit invoke() {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE_COARSE_LOCATION);
return Unit.INSTANCE;
}
});
if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION)) {
alertDialogShower.show(KiwixDialog.LocationPermissionRationale.INSTANCE,
new Function0<Unit>() {
@Override public Unit invoke() {
requestPermissions(new String[] { Manifest.permission.ACCESS_COARSE_LOCATION },
PERMISSION_REQUEST_CODE_COARSE_LOCATION);
return Unit.INSTANCE;
}
});
} else { } else {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE_COARSE_LOCATION); requestPermissions(new String[] { Manifest.permission.ACCESS_COARSE_LOCATION },
PERMISSION_REQUEST_CODE_COARSE_LOCATION);
} }
return false; return false;
@ -321,20 +338,23 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
} }
private boolean checkExternalStorageWritePermission() { // To access and store the zims private boolean checkExternalStorageWritePermission() { // To access and store the zims
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if(shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
alertDialogShower.show(KiwixDialog.StoragePermissionRationale.INSTANCE, new Function0<Unit>() {
@Override public Unit invoke() {
requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE_STORAGE_WRITE_ACCESS);
return Unit.INSTANCE;
}
});
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
alertDialogShower.show(KiwixDialog.StoragePermissionRationale.INSTANCE,
new Function0<Unit>() {
@Override public Unit invoke() {
requestPermissions(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
PERMISSION_REQUEST_CODE_STORAGE_WRITE_ACCESS);
return Unit.INSTANCE;
}
});
} else { } else {
requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE_STORAGE_WRITE_ACCESS); requestPermissions(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
PERMISSION_REQUEST_CODE_STORAGE_WRITE_ACCESS);
} }
return false; return false;
@ -346,7 +366,7 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) { @NonNull int[] grantResults) {
switch (requestCode) { switch (requestCode) {
case PERMISSION_REQUEST_CODE_COARSE_LOCATION: { case PERMISSION_REQUEST_CODE_COARSE_LOCATION: {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) { if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
@ -371,36 +391,44 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
} }
private boolean isLocationServicesEnabled() { private boolean isLocationServicesEnabled() {
LocationManager locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); LocationManager locationManager =
(LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
boolean gps_enabled = false; boolean gps_enabled = false;
boolean network_enabled = false; boolean network_enabled = false;
try { try {
gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch(Exception ex) {ex.printStackTrace();} } catch (Exception ex) {
ex.printStackTrace();
}
try { try {
network_enabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); network_enabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch(Exception ex) {ex.printStackTrace();} } catch (Exception ex) {
ex.printStackTrace();
}
return (gps_enabled || network_enabled); return (gps_enabled || network_enabled);
} }
private void requestEnableLocationServices() { private void requestEnableLocationServices() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag(RequestEnableLocationServicesDialog.TAG); Fragment prev =
getSupportFragmentManager().findFragmentByTag(RequestEnableLocationServicesDialog.TAG);
if(prev == null) { if (prev == null) {
RequestEnableLocationServicesDialog dialogFragment = new RequestEnableLocationServicesDialog(); RequestEnableLocationServicesDialog dialogFragment =
new RequestEnableLocationServicesDialog();
dialogFragment.show(fragmentTransaction, RequestEnableLocationServicesDialog.TAG); dialogFragment.show(fragmentTransaction, RequestEnableLocationServicesDialog.TAG);
} }
} }
private void requestEnableWifiP2pServices() { private void requestEnableWifiP2pServices() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag(RequestEnableWifiP2pServicesDialog.TAG); Fragment prev =
getSupportFragmentManager().findFragmentByTag(RequestEnableWifiP2pServicesDialog.TAG);
if(prev == null) { if (prev == null) {
RequestEnableWifiP2pServicesDialog dialogFragment = new RequestEnableWifiP2pServicesDialog(); RequestEnableWifiP2pServicesDialog dialogFragment = new RequestEnableWifiP2pServicesDialog();
dialogFragment.show(fragmentTransaction, RequestEnableWifiP2pServicesDialog.TAG); dialogFragment.show(fragmentTransaction, RequestEnableWifiP2pServicesDialog.TAG);
} }
@ -412,9 +440,11 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
switch (requestCode) { switch (requestCode) {
case REQUEST_ENABLE_LOCATION_SERVICES: { case REQUEST_ENABLE_LOCATION_SERVICES: {
LocationManager locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); LocationManager locationManager =
(LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
if(!(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) { if (!(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|| locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) {
// If neither provider is enabled // If neither provider is enabled
showToast(this, R.string.permission_refused_location, Toast.LENGTH_LONG); showToast(this, R.string.permission_refused_location, Toast.LENGTH_LONG);
} }
@ -422,7 +452,7 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
} }
case REQUEST_ENABLE_WIFI_P2P: { case REQUEST_ENABLE_WIFI_P2P: {
if(!isWifiP2pEnabled()) { if (!isWifiP2pEnabled()) {
showToast(this, R.string.discovery_needs_wifi, Toast.LENGTH_LONG); showToast(this, R.string.discovery_needs_wifi, Toast.LENGTH_LONG);
} }
break; break;
@ -445,8 +475,10 @@ public class LocalFileTransferActivity extends AppCompatActivity implements Wifi
@Override protected void onDestroy() { @Override protected void onDestroy() {
super.onDestroy(); super.onDestroy();
final DeviceListFragment deviceListFragment = (DeviceListFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_device_list); final DeviceListFragment deviceListFragment =
if(deviceListFragment != null) { (DeviceListFragment) getSupportFragmentManager().findFragmentById(
R.id.fragment_device_list);
if (deviceListFragment != null) {
deviceListFragment.cancelAsyncTasks(); deviceListFragment.cancelAsyncTasks();
} }
} }

View File

@ -33,7 +33,7 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.FileItem.Fil
* (no. of files & their names) with the receiver. Finally, the onPostExecute() of the sender * (no. of files & their names) with the receiver. Finally, the onPostExecute() of the sender
* initiates the file transfer through {@link SenderDeviceAsyncTask} on the sender and using * initiates the file transfer through {@link SenderDeviceAsyncTask} on the sender and using
* {@link ReceiverDeviceAsyncTask} on the receiver. * {@link ReceiverDeviceAsyncTask} on the receiver.
* */ */
class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> { class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
private static final String TAG = "PeerGrpHndshakeAsyncTsk"; private static final String TAG = "PeerGrpHndshakeAsyncTsk";
@ -50,7 +50,7 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
@Override @Override
protected InetAddress doInBackground(Void... voids) { protected InetAddress doInBackground(Void... voids) {
if(groupInfo.groupFormed && groupInfo.isGroupOwner && !isCancelled()) { if (groupInfo.groupFormed && groupInfo.isGroupOwner && !isCancelled()) {
try (ServerSocket serverSocket = new ServerSocket(PEER_HANDSHAKE_PORT)) { try (ServerSocket serverSocket = new ServerSocket(PEER_HANDSHAKE_PORT)) {
serverSocket.setReuseAddress(true); serverSocket.setReuseAddress(true);
Socket server = serverSocket.accept(); Socket server = serverSocket.accept();
@ -60,13 +60,12 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
// Verify that the peer trying to communicate is a kiwix app intending to transfer files // Verify that the peer trying to communicate is a kiwix app intending to transfer files
if (isKiwixHandshake(object) && !isCancelled()) { if (isKiwixHandshake(object) && !isCancelled()) {
if(BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
Log.d(TAG, "Client IP address: "+ server.getInetAddress()); Log.d(TAG, "Client IP address: " + server.getInetAddress());
} }
exchangeFileTransferMetadata(server.getOutputStream(), server.getInputStream()); exchangeFileTransferMetadata(server.getOutputStream(), server.getInputStream());
return server.getInetAddress(); return server.getInetAddress();
} else { // Selected device is not accepting wifi direct connections through the kiwix app } else { // Selected device is not accepting wifi direct connections through the kiwix app
return null; return null;
} }
@ -74,25 +73,24 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
ex.printStackTrace(); ex.printStackTrace();
return null; return null;
} }
} } else if (groupInfo.groupFormed && !isCancelled()) { //&& !groupInfo.isGroupOwner
else if(groupInfo.groupFormed && !isCancelled()) { //&& !groupInfo.isGroupOwner
try (Socket client = new Socket()) { try (Socket client = new Socket()) {
client.setReuseAddress(true); client.setReuseAddress(true);
client.connect((new InetSocketAddress(groupInfo.groupOwnerAddress.getHostAddress(), PEER_HANDSHAKE_PORT)), 15000); client.connect((new InetSocketAddress(groupInfo.groupOwnerAddress.getHostAddress(),
PEER_HANDSHAKE_PORT)), 15000);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(client.getOutputStream()); ObjectOutputStream objectOutputStream = new ObjectOutputStream(client.getOutputStream());
objectOutputStream.writeObject(HANDSHAKE_MESSAGE); // Send message for the peer device to verify objectOutputStream.writeObject(
HANDSHAKE_MESSAGE); // Send message for the peer device to verify
exchangeFileTransferMetadata(client.getOutputStream(), client.getInputStream()); exchangeFileTransferMetadata(client.getOutputStream(), client.getInputStream());
return groupInfo.groupOwnerAddress; return groupInfo.groupOwnerAddress;
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
return null; return null;
} }
} } else {
else {
return null; return null;
} }
} }
@ -102,46 +100,43 @@ class PeerGroupHandshakeAsyncTask extends AsyncTask<Void, Void, InetAddress> {
} }
private void exchangeFileTransferMetadata(OutputStream outputStream, InputStream inputStream) { private void exchangeFileTransferMetadata(OutputStream outputStream, InputStream inputStream) {
if(deviceListFragment.isFileSender()) { if (deviceListFragment.isFileSender()) {
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)) { try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)) {
// Send total number of files which will be transferred // Send total number of files which will be transferred
objectOutputStream.writeObject(""+deviceListFragment.getTotalFilesForTransfer()); objectOutputStream.writeObject("" + deviceListFragment.getTotalFilesForTransfer());
ArrayList<Uri> fileUriList = deviceListFragment.getFileUriList(); ArrayList<Uri> fileUriList = deviceListFragment.getFileUriList();
for( for (
Uri fileUri :fileUriList) Uri fileUri : fileUriList) { // Send the names of each of those files, in order
objectOutputStream.writeObject(getFileName(fileUri));
{ // Send the names of each of those files, in order
objectOutputStream.writeObject(getFileName(fileUri));
}
} catch (Exception e) {
e.printStackTrace();
} }
} catch (Exception e) {
e.printStackTrace();
} }
else { // Device is not the file sender } else { // Device is not the file sender
try (ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) { try (ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {
// Read the number of files // Read the number of files
Object totalFilesObject = objectInputStream.readObject(); Object totalFilesObject = objectInputStream.readObject();
if (totalFilesObject.getClass().equals(String.class)) { if (totalFilesObject.getClass().equals(String.class)) {
int total = Integer.parseInt((String) totalFilesObject); int total = Integer.parseInt((String) totalFilesObject);
deviceListFragment.setTotalFilesForTransfer(total); deviceListFragment.setTotalFilesForTransfer(total);
ArrayList<FileItem> fileItems = new ArrayList<>(); ArrayList<FileItem> fileItems = new ArrayList<>();
for (int i = 0; i < total; i++) { // Read names of each of those files, in order for (int i = 0; i < total; i++) { // Read names of each of those files, in order
Object fileNameObject = objectInputStream.readObject(); Object fileNameObject = objectInputStream.readObject();
if (fileNameObject.getClass().equals(String.class)) { if (fileNameObject.getClass().equals(String.class)) {
fileItems.add(new FileItem((String) fileNameObject, TO_BE_SENT)); fileItems.add(new FileItem((String) fileNameObject, TO_BE_SENT));
}
} }
deviceListFragment.setFileItems(fileItems);
} }
} catch (Exception e) {
e.printStackTrace(); deviceListFragment.setFileItems(fileItems);
} }
} catch (Exception e) {
e.printStackTrace();
} }
}
} }
@Override protected void onCancelled() { @Override protected void onCancelled() {

View File

@ -29,7 +29,7 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTra
* *
* A single Task is used for the entire file transfer (the server socket accepts connections as * A single Task is used for the entire file transfer (the server socket accepts connections as
* many times as the no. of files). * many times as the no. of files).
* */ */
class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> { class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private static final String TAG = "ReceiverDeviceAsyncTask"; private static final String TAG = "ReceiverDeviceAsyncTask";
@ -38,7 +38,8 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private TransferProgressFragment transferProgressFragment; private TransferProgressFragment transferProgressFragment;
private int fileItemIndex; private int fileItemIndex;
public ReceiverDeviceAsyncTask(DeviceListFragment deviceListFragment, TransferProgressFragment transferProgressFragment) { public ReceiverDeviceAsyncTask(DeviceListFragment deviceListFragment,
TransferProgressFragment transferProgressFragment) {
this.deviceListFragment = deviceListFragment; this.deviceListFragment = deviceListFragment;
this.transferProgressFragment = transferProgressFragment; this.transferProgressFragment = transferProgressFragment;
} }
@ -46,17 +47,17 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
@Override @Override
protected Boolean doInBackground(Void... voids) { protected Boolean doInBackground(Void... voids) {
try (ServerSocket serverSocket = new ServerSocket(FILE_TRANSFER_PORT)) { try (ServerSocket serverSocket = new ServerSocket(FILE_TRANSFER_PORT)) {
if(BuildConfig.DEBUG) Log.d(TAG, "Server: Socket opened at " + 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 = deviceListFragment.getZimStorageRootPath();
int totalFileCount = deviceListFragment.getTotalFilesForTransfer(); int totalFileCount = deviceListFragment.getTotalFilesForTransfer();
for(int currentFile = 1; currentFile <= totalFileCount && !isCancelled(); currentFile++) { for (int currentFile = 1; currentFile <= totalFileCount && !isCancelled(); currentFile++) {
Socket client = serverSocket.accept(); Socket client = serverSocket.accept();
if(BuildConfig.DEBUG) Log.d(TAG, "Server: Client connected for file " + currentFile); if (BuildConfig.DEBUG) Log.d(TAG, "Server: Client connected for file " + currentFile);
fileItemIndex = currentFile-1; fileItemIndex = currentFile - 1;
publishProgress(SENDING); publishProgress(SENDING);
ArrayList<FileItem> fileItems = deviceListFragment.getFileItems(); ArrayList<FileItem> fileItems = deviceListFragment.getFileItems();
@ -64,13 +65,13 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
final File clientNoteFileLocation = new File(KIWIX_ROOT + incomingFileName); final File clientNoteFileLocation = new File(KIWIX_ROOT + incomingFileName);
File dirs = new File(clientNoteFileLocation.getParent()); File dirs = new File(clientNoteFileLocation.getParent());
if(!dirs.exists() && !dirs.mkdirs()) { if (!dirs.exists() && !dirs.mkdirs()) {
Log.d(TAG, "ERROR: Required parent directories couldn't be created"); Log.d(TAG, "ERROR: Required parent directories couldn't be created");
return false; return false;
} }
boolean fileCreated = clientNoteFileLocation.createNewFile(); boolean fileCreated = clientNoteFileLocation.createNewFile();
if(BuildConfig.DEBUG) Log.d(TAG, "File creation: "+ fileCreated); if (BuildConfig.DEBUG) Log.d(TAG, "File creation: " + fileCreated);
copyToOutputStream(client.getInputStream(), new FileOutputStream(clientNoteFileLocation)); copyToOutputStream(client.getInputStream(), new FileOutputStream(clientNoteFileLocation));
@ -78,11 +79,11 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
deviceListFragment.incrementTotalFilesSent(); deviceListFragment.incrementTotalFilesSent();
} }
if(isCancelled()) if (isCancelled()) {
return false; // Returned in case the task was cancelled return false; // Returned in case the task was cancelled
else } else {
return true; // Returned in case of a successful file transfer return true; // Returned in case of a successful file transfer
}
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, e.getMessage()); Log.e(TAG, e.getMessage());
return false; // Returned when an error was encountered during transfer return false; // Returned when an error was encountered during transfer
@ -101,12 +102,14 @@ class ReceiverDeviceAsyncTask extends AsyncTask<Void, Integer, Boolean> {
@Override @Override
protected void onPostExecute(Boolean allFilesReceived) { protected void onPostExecute(Boolean allFilesReceived) {
if(BuildConfig.DEBUG) Log.d(TAG, "File transfer complete"); if (BuildConfig.DEBUG) Log.d(TAG, "File transfer complete");
if(allFilesReceived) { if (allFilesReceived) {
showToast(deviceListFragment.getActivity(), R.string.file_transfer_complete, Toast.LENGTH_LONG); showToast(deviceListFragment.getActivity(), R.string.file_transfer_complete,
Toast.LENGTH_LONG);
} else { } else {
showToast(deviceListFragment.getActivity(), R.string.error_during_transfer, Toast.LENGTH_LONG); showToast(deviceListFragment.getActivity(), R.string.error_during_transfer,
Toast.LENGTH_LONG);
} }
((LocalFileTransferActivity) deviceListFragment.getActivity()).closeLocalFileTransferActivity(); ((LocalFileTransferActivity) deviceListFragment.getActivity()).closeLocalFileTransferActivity();

View File

@ -27,7 +27,8 @@ public class RequestEnableLocationServicesDialog extends DialogFragment {
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) { public void onClick(DialogInterface paramDialogInterface, int paramInt) {
startActivityForResult(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), LocalFileTransferActivity.REQUEST_ENABLE_LOCATION_SERVICES); startActivityForResult(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS),
LocalFileTransferActivity.REQUEST_ENABLE_LOCATION_SERVICES);
} }
}) })
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {

View File

@ -32,7 +32,7 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTra
* on the list of files for transfer in {@link TransferProgressFragment}. * on the list of files for transfer in {@link TransferProgressFragment}.
* *
* A new task is created by the sender for every file to be transferred * A new task is created by the sender for every file to be transferred
* */ */
class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> { class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
private static final String TAG = "SenderDeviceAsyncTask"; private static final String TAG = "SenderDeviceAsyncTask";
@ -41,7 +41,8 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
private TransferProgressFragment transferProgressFragment; private TransferProgressFragment transferProgressFragment;
private int fileItemIndex; private int fileItemIndex;
public SenderDeviceAsyncTask(DeviceListFragment deviceListFragment, TransferProgressFragment transferProgressFragment, int fileItemIndex) { public SenderDeviceAsyncTask(DeviceListFragment deviceListFragment,
TransferProgressFragment transferProgressFragment, int fileItemIndex) {
this.deviceListFragment = deviceListFragment; this.deviceListFragment = deviceListFragment;
this.transferProgressFragment = transferProgressFragment; this.transferProgressFragment = transferProgressFragment;
this.fileItemIndex = fileItemIndex; this.fileItemIndex = fileItemIndex;
@ -57,9 +58,11 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
Uri fileUri = fileUris[0]; // Uri of file to be transferred Uri fileUri = fileUris[0]; // Uri of file to be transferred
ContentResolver contentResolver = deviceListFragment.getActivity().getContentResolver(); ContentResolver contentResolver = deviceListFragment.getActivity().getContentResolver();
try (Socket socket = new Socket(); InputStream fileInputStream = contentResolver.openInputStream(fileUri)) { // Represents the sender device try (Socket socket = new Socket();
InputStream fileInputStream = contentResolver.openInputStream(
fileUri)) { // Represents the sender device
if(isCancelled()) { if (isCancelled()) {
return false; return false;
} }
socket.bind(null); socket.bind(null);
@ -67,15 +70,14 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
String hostAddress = deviceListFragment.getFileReceiverDeviceAddress().getHostAddress(); String hostAddress = deviceListFragment.getFileReceiverDeviceAddress().getHostAddress();
socket.connect((new InetSocketAddress(hostAddress, FILE_TRANSFER_PORT)), 15000); socket.connect((new InetSocketAddress(hostAddress, FILE_TRANSFER_PORT)), 15000);
if(BuildConfig.DEBUG) Log.d(TAG, "Sender socket - " + socket.isConnected()); if (BuildConfig.DEBUG) Log.d(TAG, "Sender socket - " + socket.isConnected());
OutputStream socketOutputStream = socket.getOutputStream(); OutputStream socketOutputStream = socket.getOutputStream();
DeviceListFragment.copyToOutputStream(fileInputStream, socketOutputStream); DeviceListFragment.copyToOutputStream(fileInputStream, socketOutputStream);
if(BuildConfig.DEBUG) Log.d(TAG, "Sender: Data written"); if (BuildConfig.DEBUG) Log.d(TAG, "Sender: Data written");
return true; return true;
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, e.getMessage()); Log.e(TAG, e.getMessage());
return false; return false;
@ -90,16 +92,18 @@ class SenderDeviceAsyncTask extends AsyncTask<Uri, Void, Boolean> {
protected void onPostExecute(Boolean fileSendSuccessful) { protected void onPostExecute(Boolean fileSendSuccessful) {
deviceListFragment.incrementTotalFilesSent(); deviceListFragment.incrementTotalFilesSent();
if(fileSendSuccessful) { // Whether this task was successful in sending the file if (fileSendSuccessful) { // Whether this task was successful in sending the file
transferProgressFragment.changeStatus(fileItemIndex, SENT); transferProgressFragment.changeStatus(fileItemIndex, SENT);
} else { } else {
Activity activity = deviceListFragment.getActivity(); Activity activity = deviceListFragment.getActivity();
showToast(activity, activity.getString(R.string.error_sending, getFileName(deviceListFragment.getFileUriList().get(fileItemIndex))), Toast.LENGTH_SHORT); showToast(activity, activity.getString(R.string.error_sending,
getFileName(deviceListFragment.getFileUriList().get(fileItemIndex))), Toast.LENGTH_SHORT);
transferProgressFragment.changeStatus(fileItemIndex, ERROR); transferProgressFragment.changeStatus(fileItemIndex, ERROR);
} }
if(deviceListFragment.allFilesSent()) { if (deviceListFragment.allFilesSent()) {
showToast(deviceListFragment.getActivity(), R.string.file_transfer_complete, Toast.LENGTH_SHORT); showToast(deviceListFragment.getActivity(), R.string.file_transfer_complete,
Toast.LENGTH_SHORT);
deviceListFragment.getActivity().finish(); deviceListFragment.getActivity().finish();
} }
} }

View File

@ -22,7 +22,7 @@ import java.util.ArrayList;
* Part of the local file sharing module, this fragment is used to display the progress of the * Part of the local file sharing module, this fragment is used to display the progress of the
* file transfer. It displays a list of files along with their current status (as defined in the * file transfer. It displays a list of files along with their current status (as defined in the
* {@link FileItem} class. * {@link FileItem} class.
* */ */
public class TransferProgressFragment extends Fragment { public class TransferProgressFragment extends Fragment {
private static final String FILE_ITEMS = "file_items"; private static final String FILE_ITEMS = "file_items";
@ -53,7 +53,8 @@ public class TransferProgressFragment extends Fragment {
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_transfer_progress, container, false); View view = inflater.inflate(R.layout.fragment_transfer_progress, container, false);
unbinder = ButterKnife.bind(this, view); unbinder = ButterKnife.bind(this, view);
@ -68,7 +69,7 @@ public class TransferProgressFragment extends Fragment {
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
if(unbinder != null) unbinder.unbind(); if (unbinder != null) unbinder.unbind();
} }
public void changeStatus(int itemIndex, @FileItem.FileStatus int status) { public void changeStatus(int itemIndex, @FileItem.FileStatus int status) {

View File

@ -18,14 +18,15 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTra
* *
* Handles the broadcasts pertaining to the wifi p2p group formed in WiFi Direct. Works along with * Handles the broadcasts pertaining to the wifi p2p group formed in WiFi Direct. Works along with
* the wifi p2p manager in {@link LocalFileTransferActivity}. * the wifi p2p manager in {@link LocalFileTransferActivity}.
* */ */
public class WifiDirectBroadcastReceiver extends BroadcastReceiver { public class WifiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager manager; private WifiP2pManager manager;
private WifiP2pManager.Channel channel; private WifiP2pManager.Channel channel;
private LocalFileTransferActivity wifiActivity; private LocalFileTransferActivity wifiActivity;
public WifiDirectBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel, LocalFileTransferActivity activity) { public WifiDirectBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel,
LocalFileTransferActivity activity) {
super(); super();
this.manager = manager; this.manager = manager;
this.channel = channel; this.channel = channel;
@ -36,11 +37,11 @@ public class WifiDirectBroadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
if(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
// Update wifi p2p state // Update wifi p2p state
int wifiP2pState = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1); int wifiP2pState = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if(wifiP2pState == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { if (wifiP2pState == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
wifiActivity.setWifiP2pEnabled(true); wifiActivity.setWifiP2pEnabled(true);
} else { } else {
wifiActivity.setWifiP2pEnabled(false); wifiActivity.setWifiP2pEnabled(false);
@ -48,35 +49,39 @@ public class WifiDirectBroadcastReceiver extends BroadcastReceiver {
wifiActivity.resetPeers(); wifiActivity.resetPeers();
} }
Log.d(LocalFileTransferActivity.TAG, "WiFi P2P state changed - " + wifiP2pState); Log.d(LocalFileTransferActivity.TAG, "WiFi P2P state changed - " + wifiP2pState);
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
} else if(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { if (manager != null) {
if(manager != null) {
/* List of available peers has changed, so request & use the new list through /* List of available peers has changed, so request & use the new list through
* PeerListListener.requestPeers() callback */ * PeerListListener.requestPeers() callback */
manager.requestPeers(channel, (WifiP2pManager.PeerListListener) wifiActivity.getSupportFragmentManager().findFragmentById(R.id.fragment_device_list)); manager.requestPeers(channel,
(WifiP2pManager.PeerListListener) wifiActivity.getSupportFragmentManager()
.findFragmentById(R.id.fragment_device_list));
} }
Log.d(LocalFileTransferActivity.TAG, "P2P peers changed"); Log.d(LocalFileTransferActivity.TAG, "P2P peers changed");
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
} else if(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { if (manager == null) {
if(manager == null) {
return; return;
} }
NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if(networkInfo.isConnected()) { if (networkInfo.isConnected()) {
// Request connection info about the wifi p2p group formed upon connection // 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,
(DeviceListFragment) wifiActivity.getSupportFragmentManager()
.findFragmentById(R.id.fragment_device_list));
} else { } else {
// Not connected after connection change -> Disconnected // Not connected after connection change -> Disconnected
wifiActivity.resetData(); wifiActivity.resetData();
} }
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
} else if(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// Update UI with wifi-direct details about the user device // Update UI with wifi-direct details about the user device
DeviceListFragment deviceListFragment = (DeviceListFragment) wifiActivity.getSupportFragmentManager().findFragmentById(R.id.fragment_device_list); DeviceListFragment deviceListFragment =
deviceListFragment.updateUserDevice(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)); (DeviceListFragment) wifiActivity.getSupportFragmentManager()
.findFragmentById(R.id.fragment_device_list);
deviceListFragment.updateUserDevice(
intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
} }
} }
} }

View File

@ -23,14 +23,16 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.DeviceListFr
/** /**
* Helper class, part of the local file sharing module. * Helper class, part of the local file sharing module.
* *
* Defines the Adapter for the list of wifi peer-device items displayed in {@link DeviceListFragment} * Defines the Adapter for the list of wifi peer-device items displayed in {@link
* */ * DeviceListFragment}
*/
public class WifiPeerListAdapter extends ArrayAdapter<WifiP2pDevice> { public class WifiPeerListAdapter extends ArrayAdapter<WifiP2pDevice> {
private Context context; private Context context;
private List<WifiP2pDevice> listItems; private List<WifiP2pDevice> listItems;
public WifiPeerListAdapter(@NonNull Context context, int resource, @NonNull List<WifiP2pDevice> objects) { public WifiPeerListAdapter(@NonNull Context context, int resource,
@NonNull List<WifiP2pDevice> objects) {
super(context, resource, objects); super(context, resource, objects);
this.context = context; this.context = context;
this.listItems = objects; this.listItems = objects;
@ -42,7 +44,7 @@ public class WifiPeerListAdapter extends ArrayAdapter<WifiP2pDevice> {
View rowView = convertView; View rowView = convertView;
ViewHolder viewHolder; ViewHolder viewHolder;
if(rowView == null) { if (rowView == null) {
LayoutInflater layoutInflater = ((Activity) context).getLayoutInflater(); LayoutInflater layoutInflater = ((Activity) context).getLayoutInflater();
rowView = layoutInflater.inflate(R.layout.row_peer_device, parent, false); rowView = layoutInflater.inflate(R.layout.row_peer_device, parent, false);
viewHolder = new ViewHolder(rowView); viewHolder = new ViewHolder(rowView);
@ -53,7 +55,7 @@ public class WifiPeerListAdapter extends ArrayAdapter<WifiP2pDevice> {
WifiP2pDevice device = listItems.get(position); WifiP2pDevice device = listItems.get(position);
if(device != null) { if (device != null) {
viewHolder.deviceName.setText(device.deviceName); viewHolder.deviceName.setText(device.deviceName);
Log.d(TAG, getDeviceStatus(device.status)); Log.d(TAG, getDeviceStatus(device.status));
} }