2015-11-19 10:21:19 -08:00
|
|
|
package org.thoughtcrime.securesms;
|
|
|
|
|
|
|
|
import android.app.Activity;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.DialogInterface;
|
2017-10-23 13:03:32 -07:00
|
|
|
import android.os.AsyncTask;
|
2015-11-19 10:21:19 -08:00
|
|
|
import android.os.Bundle;
|
2019-05-22 13:51:56 -03:00
|
|
|
import android.support.annotation.NonNull;
|
2015-11-19 10:21:19 -08:00
|
|
|
import android.support.v4.app.ListFragment;
|
|
|
|
import android.support.v4.app.LoaderManager;
|
|
|
|
import android.support.v4.content.Loader;
|
|
|
|
import android.support.v7.app.AlertDialog;
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.widget.AdapterView;
|
|
|
|
import android.widget.ArrayAdapter;
|
|
|
|
import android.widget.Button;
|
|
|
|
import android.widget.ListView;
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
import com.melnykov.fab.FloatingActionButton;
|
|
|
|
|
|
|
|
import org.thoughtcrime.securesms.database.loaders.DeviceListLoader;
|
|
|
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
2019-07-24 12:30:23 +10:00
|
|
|
import org.thoughtcrime.securesms.devicelist.Device;
|
|
|
|
import org.thoughtcrime.securesms.jobs.RefreshUnidentifiedDeliveryAbilityJob;
|
|
|
|
import org.thoughtcrime.securesms.logging.Log;
|
2015-11-19 10:21:19 -08:00
|
|
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|
|
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
2019-07-24 12:30:23 +10:00
|
|
|
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
2016-03-23 10:34:41 -07:00
|
|
|
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
2015-11-19 10:21:19 -08:00
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.util.List;
|
2015-12-02 16:35:07 +09:00
|
|
|
import java.util.Locale;
|
2015-11-19 10:21:19 -08:00
|
|
|
|
|
|
|
import javax.inject.Inject;
|
|
|
|
|
2019-07-24 12:30:23 +10:00
|
|
|
import network.loki.messenger.R;
|
|
|
|
|
2015-11-19 10:21:19 -08:00
|
|
|
public class DeviceListFragment extends ListFragment
|
2018-12-19 08:09:22 -08:00
|
|
|
implements LoaderManager.LoaderCallbacks<List<Device>>,
|
2015-11-19 10:21:19 -08:00
|
|
|
ListView.OnItemClickListener, InjectableType, Button.OnClickListener
|
|
|
|
{
|
|
|
|
|
|
|
|
private static final String TAG = DeviceListFragment.class.getSimpleName();
|
|
|
|
|
|
|
|
@Inject
|
2016-03-23 10:34:41 -07:00
|
|
|
SignalServiceAccountManager accountManager;
|
2015-11-19 10:21:19 -08:00
|
|
|
|
2015-12-02 16:35:07 +09:00
|
|
|
private Locale locale;
|
|
|
|
private View empty;
|
2015-11-19 10:21:19 -08:00
|
|
|
private View progressContainer;
|
2015-12-02 16:35:07 +09:00
|
|
|
private FloatingActionButton addDeviceButton;
|
2015-11-19 10:21:19 -08:00
|
|
|
private Button.OnClickListener addDeviceButtonListener;
|
|
|
|
|
2015-12-02 16:35:07 +09:00
|
|
|
@Override
|
|
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
this.locale = (Locale) getArguments().getSerializable(PassphraseRequiredActionBarActivity.LOCALE_EXTRA);
|
|
|
|
}
|
|
|
|
|
2015-11-19 10:21:19 -08:00
|
|
|
@Override
|
|
|
|
public void onAttach(Activity activity) {
|
|
|
|
super.onAttach(activity);
|
|
|
|
ApplicationContext.getInstance(activity).injectDependencies(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
|
|
|
|
View view = inflater.inflate(R.layout.device_list_fragment, container, false);
|
|
|
|
|
|
|
|
this.empty = view.findViewById(R.id.empty);
|
|
|
|
this.progressContainer = view.findViewById(R.id.progress_container);
|
|
|
|
this.addDeviceButton = ViewUtil.findById(view, R.id.add_device);
|
|
|
|
this.addDeviceButton.setOnClickListener(this);
|
|
|
|
|
|
|
|
return view;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onActivityCreated(Bundle bundle) {
|
|
|
|
super.onActivityCreated(bundle);
|
2016-09-14 14:46:18 +02:00
|
|
|
getLoaderManager().initLoader(0, null, this);
|
2015-11-19 10:21:19 -08:00
|
|
|
getListView().setOnItemClickListener(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setAddDeviceButtonListener(Button.OnClickListener listener) {
|
|
|
|
this.addDeviceButtonListener = listener;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-05-22 13:51:56 -03:00
|
|
|
public @NonNull Loader<List<Device>> onCreateLoader(int id, Bundle args) {
|
2015-11-19 10:21:19 -08:00
|
|
|
empty.setVisibility(View.GONE);
|
|
|
|
progressContainer.setVisibility(View.VISIBLE);
|
|
|
|
|
|
|
|
return new DeviceListLoader(getActivity(), accountManager);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-05-22 13:51:56 -03:00
|
|
|
public void onLoadFinished(@NonNull Loader<List<Device>> loader, List<Device> data) {
|
2015-11-19 10:21:19 -08:00
|
|
|
progressContainer.setVisibility(View.GONE);
|
|
|
|
|
|
|
|
if (data == null) {
|
|
|
|
handleLoaderFailed();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-02 16:35:07 +09:00
|
|
|
setListAdapter(new DeviceListAdapter(getActivity(), R.layout.device_list_item_view, data, locale));
|
2015-11-19 10:21:19 -08:00
|
|
|
|
|
|
|
if (data.isEmpty()) {
|
|
|
|
empty.setVisibility(View.VISIBLE);
|
|
|
|
TextSecurePreferences.setMultiDevice(getActivity(), false);
|
|
|
|
} else {
|
|
|
|
empty.setVisibility(View.GONE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-05-22 13:51:56 -03:00
|
|
|
public void onLoaderReset(@NonNull Loader<List<Device>> loader) {
|
2015-11-19 10:21:19 -08:00
|
|
|
setListAdapter(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
|
|
final String deviceName = ((DeviceListItem)view).getDeviceName();
|
|
|
|
final long deviceId = ((DeviceListItem)view).getDeviceId();
|
|
|
|
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
|
|
|
builder.setTitle(getActivity().getString(R.string.DeviceListActivity_unlink_s, deviceName));
|
|
|
|
builder.setMessage(R.string.DeviceListActivity_by_unlinking_this_device_it_will_no_longer_be_able_to_send_or_receive);
|
|
|
|
builder.setNegativeButton(android.R.string.cancel, null);
|
|
|
|
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
handleDisconnectDevice(deviceId);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
builder.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleLoaderFailed() {
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
|
|
|
builder.setMessage(R.string.DeviceListActivity_network_connection_failed);
|
|
|
|
builder.setPositiveButton(R.string.DeviceListActivity_try_again,
|
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
2016-09-14 14:46:18 +02:00
|
|
|
getLoaderManager().restartLoader(0, null, DeviceListFragment.this);
|
2015-11-19 10:21:19 -08:00
|
|
|
}
|
|
|
|
});
|
2015-12-14 19:29:39 +01:00
|
|
|
|
|
|
|
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
DeviceListFragment.this.getActivity().onBackPressed();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
|
|
|
@Override
|
|
|
|
public void onCancel(DialogInterface dialog) {
|
|
|
|
DeviceListFragment.this.getActivity().onBackPressed();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-11-19 10:21:19 -08:00
|
|
|
builder.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleDisconnectDevice(final long deviceId) {
|
|
|
|
new ProgressDialogAsyncTask<Void, Void, Void>(getActivity(),
|
|
|
|
R.string.DeviceListActivity_unlinking_device_no_ellipsis,
|
|
|
|
R.string.DeviceListActivity_unlinking_device)
|
|
|
|
{
|
|
|
|
@Override
|
|
|
|
protected Void doInBackground(Void... params) {
|
|
|
|
try {
|
|
|
|
accountManager.removeDevice(deviceId);
|
2018-10-11 16:45:22 -07:00
|
|
|
|
|
|
|
ApplicationContext.getInstance(getContext())
|
|
|
|
.getJobManager()
|
2019-03-28 08:56:35 -07:00
|
|
|
.add(new RefreshUnidentifiedDeliveryAbilityJob());
|
2015-11-19 10:21:19 -08:00
|
|
|
} catch (IOException e) {
|
|
|
|
Log.w(TAG, e);
|
|
|
|
Toast.makeText(getActivity(), R.string.DeviceListActivity_network_failed, Toast.LENGTH_LONG).show();
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(Void result) {
|
|
|
|
super.onPostExecute(result);
|
|
|
|
getLoaderManager().restartLoader(0, null, DeviceListFragment.this);
|
|
|
|
}
|
2017-10-23 13:03:32 -07:00
|
|
|
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
2015-11-19 10:21:19 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
if (addDeviceButtonListener != null) addDeviceButtonListener.onClick(v);
|
|
|
|
}
|
|
|
|
|
2018-12-19 08:09:22 -08:00
|
|
|
private static class DeviceListAdapter extends ArrayAdapter<Device> {
|
2015-11-19 10:21:19 -08:00
|
|
|
|
2015-12-02 16:35:07 +09:00
|
|
|
private final int resource;
|
|
|
|
private final Locale locale;
|
2015-11-19 10:21:19 -08:00
|
|
|
|
2018-12-19 08:09:22 -08:00
|
|
|
public DeviceListAdapter(Context context, int resource, List<Device> objects, Locale locale) {
|
2015-11-19 10:21:19 -08:00
|
|
|
super(context, resource, objects);
|
|
|
|
this.resource = resource;
|
2015-12-02 16:35:07 +09:00
|
|
|
this.locale = locale;
|
2015-11-19 10:21:19 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-05-22 13:51:56 -03:00
|
|
|
public @NonNull View getView(int position, View convertView, @NonNull ViewGroup parent) {
|
2015-11-19 10:21:19 -08:00
|
|
|
if (convertView == null) {
|
|
|
|
convertView = ((Activity)getContext()).getLayoutInflater().inflate(resource, parent, false);
|
|
|
|
}
|
|
|
|
|
2015-12-02 16:35:07 +09:00
|
|
|
((DeviceListItem)convertView).set(getItem(position), locale);
|
2015-11-19 10:21:19 -08:00
|
|
|
|
|
|
|
return convertView;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|