2015-08-20 00:59:21 -07:00
|
|
|
/*
|
|
|
|
* Copyright 2014 Albert Vaca Cintora <albertvaka@gmail.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of
|
|
|
|
* the License or (at your option) version 3 or any later version
|
|
|
|
* accepted by the membership of KDE e.V. (or its successor approved
|
|
|
|
* by the membership of KDE e.V.), which shall act as a proxy
|
|
|
|
* defined in Section 14 of version 3 of the license.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2015-09-07 01:49:12 -07:00
|
|
|
package org.kde.kdeconnect.UserInterface;
|
2015-08-20 00:59:21 -07:00
|
|
|
|
|
|
|
import android.app.Activity;
|
2015-09-11 09:24:35 -07:00
|
|
|
import android.app.AlertDialog;
|
2015-09-07 00:11:46 -07:00
|
|
|
import android.content.Context;
|
2015-09-11 09:24:35 -07:00
|
|
|
import android.content.DialogInterface;
|
2015-08-20 00:59:21 -07:00
|
|
|
import android.content.Intent;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.support.v4.app.Fragment;
|
|
|
|
import android.util.Log;
|
2015-09-07 00:11:46 -07:00
|
|
|
import android.view.KeyEvent;
|
2015-08-20 00:59:21 -07:00
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.Menu;
|
|
|
|
import android.view.MenuItem;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.widget.Button;
|
|
|
|
import android.widget.ListView;
|
|
|
|
import android.widget.TextView;
|
|
|
|
|
|
|
|
import org.kde.kdeconnect.BackgroundService;
|
|
|
|
import org.kde.kdeconnect.Device;
|
2017-02-25 21:12:32 +01:00
|
|
|
import org.kde.kdeconnect.Helpers.NetworkHelper;
|
2015-09-11 09:24:35 -07:00
|
|
|
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
|
2015-08-20 00:59:21 -07:00
|
|
|
import org.kde.kdeconnect.Plugins.Plugin;
|
|
|
|
import org.kde.kdeconnect.UserInterface.List.CustomItem;
|
|
|
|
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
|
2016-06-09 13:42:15 +02:00
|
|
|
import org.kde.kdeconnect.UserInterface.List.PluginItem;
|
2015-08-20 00:59:21 -07:00
|
|
|
import org.kde.kdeconnect.UserInterface.List.SmallEntryItem;
|
|
|
|
import org.kde.kdeconnect_tp.R;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.ConcurrentModificationException;
|
2016-07-07 17:45:04 +02:00
|
|
|
import java.util.Map;
|
2015-11-12 06:41:14 -08:00
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
2015-08-20 00:59:21 -07:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Main view. Displays the current device and its plugins
|
|
|
|
*/
|
|
|
|
public class DeviceFragment extends Fragment {
|
2015-08-20 01:00:05 -07:00
|
|
|
|
2017-02-05 15:42:42 +01:00
|
|
|
static final String ARG_DEVICE_ID = "deviceId";
|
2017-07-25 18:14:38 +02:00
|
|
|
static final String ARG_FROM_DEVICE_LIST = "fromDeviceList";
|
2015-08-20 00:59:21 -07:00
|
|
|
|
2017-02-05 15:42:42 +01:00
|
|
|
View rootView;
|
|
|
|
static String mDeviceId; //Static because if we get here by using the back button in the action bar, the extra deviceId will not be set.
|
|
|
|
Device device;
|
2015-08-20 01:00:05 -07:00
|
|
|
|
2017-02-05 15:42:42 +01:00
|
|
|
MaterialActivity mActivity;
|
2015-09-03 03:05:34 -07:00
|
|
|
|
2017-07-11 13:50:40 +02:00
|
|
|
ArrayList<ListAdapter.Item> pluginListItems;
|
|
|
|
|
|
|
|
public DeviceFragment() {
|
|
|
|
}
|
2015-08-20 00:59:21 -07:00
|
|
|
|
2015-09-07 00:11:46 -07:00
|
|
|
public DeviceFragment(String deviceId, boolean fromDeviceList) {
|
|
|
|
Bundle args = new Bundle();
|
|
|
|
args.putString(ARG_DEVICE_ID, deviceId);
|
2017-07-24 16:39:00 +02:00
|
|
|
args.putBoolean(ARG_FROM_DEVICE_LIST, fromDeviceList);
|
2015-09-07 00:11:46 -07:00
|
|
|
this.setArguments(args);
|
|
|
|
}
|
|
|
|
|
2017-07-11 13:50:40 +02:00
|
|
|
public DeviceFragment(String deviceId, MaterialActivity activity) {
|
2017-02-05 15:19:46 +01:00
|
|
|
this.mActivity = activity;
|
|
|
|
Bundle args = new Bundle();
|
|
|
|
args.putString(ARG_DEVICE_ID, deviceId);
|
|
|
|
this.setArguments(args);
|
|
|
|
}
|
|
|
|
|
2015-08-20 01:00:05 -07:00
|
|
|
@Override
|
|
|
|
public void onAttach(Activity activity) {
|
|
|
|
super.onAttach(activity);
|
2015-09-03 03:05:34 -07:00
|
|
|
mActivity = ((MaterialActivity) getActivity());
|
2015-08-20 01:00:05 -07:00
|
|
|
}
|
|
|
|
|
2015-08-20 00:59:21 -07:00
|
|
|
@Override
|
|
|
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
|
|
|
Bundle savedInstanceState) {
|
|
|
|
|
2015-09-07 01:49:12 -07:00
|
|
|
rootView = inflater.inflate(R.layout.activity_device, container, false);
|
2015-08-20 00:59:21 -07:00
|
|
|
|
2015-09-07 00:11:46 -07:00
|
|
|
final String deviceId = getArguments().getString(ARG_DEVICE_ID);
|
2015-08-20 00:59:21 -07:00
|
|
|
if (deviceId != null) {
|
|
|
|
mDeviceId = deviceId;
|
|
|
|
}
|
|
|
|
|
2015-09-03 03:05:34 -07:00
|
|
|
setHasOptionsMenu(true);
|
|
|
|
|
2015-09-08 05:18:57 -07:00
|
|
|
//Log.e("DeviceFragment", "device: " + deviceId);
|
2015-08-20 00:59:21 -07:00
|
|
|
|
|
|
|
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
|
|
|
|
@Override
|
|
|
|
public void onServiceStart(BackgroundService service) {
|
|
|
|
device = service.getDevice(mDeviceId);
|
2015-09-03 03:05:34 -07:00
|
|
|
if (device == null) {
|
|
|
|
Log.e("DeviceFragment", "Trying to display a device fragment but the device is not present");
|
|
|
|
mActivity.onDeviceSelected(null);
|
2015-09-07 00:11:46 -07:00
|
|
|
return;
|
2015-09-03 03:05:34 -07:00
|
|
|
}
|
2015-08-20 01:00:05 -07:00
|
|
|
|
|
|
|
mActivity.getSupportActionBar().setTitle(device.getName());
|
|
|
|
|
2015-09-07 00:11:46 -07:00
|
|
|
device.addPairingCallback(pairingCallback);
|
2015-08-20 00:59:21 -07:00
|
|
|
device.addPluginsChangedListener(pluginsChangedListener);
|
2015-09-07 00:11:46 -07:00
|
|
|
|
|
|
|
refreshUI();
|
2015-08-20 01:00:05 -07:00
|
|
|
|
2015-08-20 00:59:21 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-07-11 13:50:40 +02:00
|
|
|
final Button pairButton = (Button) rootView.findViewById(R.id.pair_button);
|
2015-09-07 00:11:46 -07:00
|
|
|
pairButton.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
pairButton.setVisibility(View.GONE);
|
|
|
|
((TextView) rootView.findViewById(R.id.pair_message)).setText("");
|
|
|
|
rootView.findViewById(R.id.pair_progress).setVisibility(View.VISIBLE);
|
|
|
|
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
|
|
|
|
@Override
|
|
|
|
public void onServiceStart(BackgroundService service) {
|
|
|
|
device = service.getDevice(deviceId);
|
|
|
|
if (device == null) return;
|
|
|
|
device.requestPairing();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
rootView.findViewById(R.id.accept_button).setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
|
|
|
|
@Override
|
|
|
|
public void onServiceStart(BackgroundService service) {
|
|
|
|
if (device != null) {
|
|
|
|
device.acceptPairing();
|
|
|
|
rootView.findViewById(R.id.pairing_buttons).setVisibility(View.GONE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2015-08-20 00:59:21 -07:00
|
|
|
|
2015-09-07 00:11:46 -07:00
|
|
|
rootView.findViewById(R.id.reject_button).setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View view) {
|
|
|
|
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
|
|
|
|
@Override
|
|
|
|
public void onServiceStart(BackgroundService service) {
|
|
|
|
if (device != null) {
|
|
|
|
//Remove listener so buttons don't show for a while before changing the view
|
|
|
|
device.removePluginsChangedListener(pluginsChangedListener);
|
|
|
|
device.removePairingCallback(pairingCallback);
|
|
|
|
device.rejectPairing();
|
|
|
|
}
|
|
|
|
mActivity.onDeviceSelected(null);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2015-08-20 00:59:21 -07:00
|
|
|
|
|
|
|
return rootView;
|
|
|
|
}
|
|
|
|
|
2017-02-05 15:42:42 +01:00
|
|
|
final Device.PluginsChangedListener pluginsChangedListener = new Device.PluginsChangedListener() {
|
2015-08-20 00:59:21 -07:00
|
|
|
@Override
|
|
|
|
public void onPluginsChanged(final Device device) {
|
2015-09-07 00:11:46 -07:00
|
|
|
refreshUI();
|
2015-08-20 00:59:21 -07:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroyView() {
|
|
|
|
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
|
|
|
|
@Override
|
|
|
|
public void onServiceStart(BackgroundService service) {
|
|
|
|
Device device = service.getDevice(mDeviceId);
|
|
|
|
if (device == null) return;
|
|
|
|
device.removePluginsChangedListener(pluginsChangedListener);
|
2015-09-07 00:11:46 -07:00
|
|
|
device.removePairingCallback(pairingCallback);
|
2015-08-20 00:59:21 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
super.onDestroyView();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onPrepareOptionsMenu(Menu menu) {
|
|
|
|
|
2015-09-08 05:18:57 -07:00
|
|
|
//Log.e("DeviceFragment", "onPrepareOptionsMenu");
|
2015-09-03 03:05:34 -07:00
|
|
|
|
2015-08-20 00:59:21 -07:00
|
|
|
super.onPrepareOptionsMenu(menu);
|
|
|
|
menu.clear();
|
|
|
|
|
2015-09-07 00:11:46 -07:00
|
|
|
if (device == null) {
|
2015-08-20 00:59:21 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Plugins button list
|
|
|
|
final Collection<Plugin> plugins = device.getLoadedPlugins().values();
|
|
|
|
for (final Plugin p : plugins) {
|
|
|
|
if (!p.displayInContextMenu()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
menu.add(p.getActionName()).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onMenuItemClick(MenuItem item) {
|
|
|
|
p.startMainActivity(mActivity);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
menu.add(R.string.device_menu_plugins).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onMenuItemClick(MenuItem menuItem) {
|
|
|
|
Intent intent = new Intent(mActivity, SettingsActivity.class);
|
|
|
|
intent.putExtra("deviceId", mDeviceId);
|
|
|
|
startActivity(intent);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
2015-09-07 00:11:46 -07:00
|
|
|
|
2018-02-26 19:38:35 +01:00
|
|
|
if (device.isReachable()) {
|
2015-09-11 09:24:35 -07:00
|
|
|
|
|
|
|
menu.add(R.string.encryption_info_title).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onMenuItemClick(MenuItem menuItem) {
|
|
|
|
Context context = mActivity;
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
|
|
|
builder.setTitle(context.getResources().getString(R.string.encryption_info_title));
|
|
|
|
builder.setPositiveButton(context.getResources().getString(R.string.ok), new DialogInterface.OnClickListener() {
|
|
|
|
public void onClick(DialogInterface dialog, int id) {
|
|
|
|
dialog.dismiss();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if (device.certificate == null) {
|
|
|
|
builder.setMessage(R.string.encryption_info_msg_no_ssl);
|
|
|
|
} else {
|
2016-06-04 02:21:28 +02:00
|
|
|
builder.setMessage(context.getResources().getString(R.string.my_device_fingerprint) + "\n" + SslHelper.getCertificateHash(SslHelper.certificate) + "\n\n"
|
|
|
|
+ context.getResources().getString(R.string.remote_device_fingerprint) + "\n" + SslHelper.getCertificateHash(device.certificate));
|
2015-09-11 09:24:35 -07:00
|
|
|
}
|
|
|
|
builder.create().show();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
2016-09-06 00:47:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (device.isPaired()) {
|
2015-09-11 09:24:35 -07:00
|
|
|
|
2015-09-07 00:11:46 -07:00
|
|
|
menu.add(R.string.device_menu_unpair).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onMenuItemClick(MenuItem menuItem) {
|
|
|
|
//Remove listener so buttons don't show for a while before changing the view
|
|
|
|
device.removePluginsChangedListener(pluginsChangedListener);
|
|
|
|
device.removePairingCallback(pairingCallback);
|
|
|
|
device.unpair();
|
|
|
|
mActivity.onDeviceSelected(null);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2015-08-20 00:59:21 -07:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-09-04 06:05:21 -07:00
|
|
|
@Override
|
|
|
|
public void onResume() {
|
|
|
|
super.onResume();
|
2016-07-06 17:45:01 +02:00
|
|
|
|
2015-09-07 00:11:46 -07:00
|
|
|
getView().setFocusableInTouchMode(true);
|
|
|
|
getView().requestFocus();
|
|
|
|
getView().setOnKeyListener(new View.OnKeyListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
|
|
|
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
|
2017-07-24 16:39:00 +02:00
|
|
|
boolean fromDeviceList = getArguments().getBoolean(ARG_FROM_DEVICE_LIST, false);
|
2015-09-07 00:11:46 -07:00
|
|
|
// Handle back button so we go to the list of devices in case we came from there
|
|
|
|
if (fromDeviceList) {
|
|
|
|
mActivity.onDeviceSelected(null);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void refreshUI() {
|
2015-09-08 05:18:57 -07:00
|
|
|
//Log.e("DeviceFragment", "refreshUI");
|
2015-09-07 00:11:46 -07:00
|
|
|
|
|
|
|
if (device == null || rootView == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-09-12 13:21:06 -07:00
|
|
|
//Once in-app, there is no point in keep displaying the notification if any
|
|
|
|
device.hidePairingNotification();
|
|
|
|
|
2015-09-07 00:11:46 -07:00
|
|
|
mActivity.runOnUiThread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
|
2016-01-10 03:16:14 -08:00
|
|
|
if (device.isPairRequestedByPeer()) {
|
2015-09-12 13:21:06 -07:00
|
|
|
((TextView) rootView.findViewById(R.id.pair_message)).setText(R.string.pair_requested);
|
|
|
|
rootView.findViewById(R.id.pair_progress).setVisibility(View.GONE);
|
|
|
|
rootView.findViewById(R.id.pair_button).setVisibility(View.GONE);
|
|
|
|
rootView.findViewById(R.id.pair_request).setVisibility(View.VISIBLE);
|
|
|
|
} else {
|
2015-09-07 00:11:46 -07:00
|
|
|
|
2015-09-12 13:21:06 -07:00
|
|
|
boolean paired = device.isPaired();
|
|
|
|
boolean reachable = device.isReachable();
|
2017-02-25 21:12:32 +01:00
|
|
|
boolean onData = NetworkHelper.isOnMobileNetwork(getContext());
|
2015-09-07 00:11:46 -07:00
|
|
|
|
2015-09-12 13:21:06 -07:00
|
|
|
rootView.findViewById(R.id.pairing_buttons).setVisibility(paired ? View.GONE : View.VISIBLE);
|
2017-02-25 21:12:32 +01:00
|
|
|
rootView.findViewById(R.id.not_reachable_message).setVisibility((paired && !reachable && !onData) ? View.VISIBLE : View.GONE);
|
|
|
|
rootView.findViewById(R.id.on_data_message).setVisibility((paired && !reachable && onData) ? View.VISIBLE : View.GONE);
|
2015-09-07 00:11:46 -07:00
|
|
|
|
2015-09-12 13:21:06 -07:00
|
|
|
try {
|
2017-07-11 13:50:40 +02:00
|
|
|
pluginListItems = new ArrayList<>();
|
2015-09-07 00:11:46 -07:00
|
|
|
|
2015-09-12 13:21:06 -07:00
|
|
|
//Plugins button list
|
|
|
|
final Collection<Plugin> plugins = device.getLoadedPlugins().values();
|
|
|
|
for (final Plugin p : plugins) {
|
|
|
|
if (!p.hasMainActivity()) continue;
|
|
|
|
if (p.displayInContextMenu()) continue;
|
2015-09-07 00:11:46 -07:00
|
|
|
|
2017-07-11 13:50:40 +02:00
|
|
|
pluginListItems.add(new PluginItem(p, new View.OnClickListener() {
|
2015-09-12 07:17:14 -07:00
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
2015-09-12 13:21:06 -07:00
|
|
|
p.startMainActivity(mActivity);
|
2015-09-12 07:17:14 -07:00
|
|
|
}
|
|
|
|
}));
|
2015-09-07 00:11:46 -07:00
|
|
|
}
|
|
|
|
|
2017-07-11 13:50:40 +02:00
|
|
|
createPluginsList(device.getFailedPlugins(), R.string.plugins_failed_to_load, new PluginClickListener() {
|
|
|
|
@Override
|
|
|
|
void action() {
|
|
|
|
plugin.getErrorDialog(mActivity).show();
|
2015-09-07 00:11:46 -07:00
|
|
|
}
|
2017-07-11 13:50:40 +02:00
|
|
|
});
|
|
|
|
createPluginsList(device.getPluginsWithoutPermissions(), R.string.plugins_need_permission, new PluginClickListener() {
|
|
|
|
@Override
|
|
|
|
void action() {
|
|
|
|
plugin.getPermissionExplanationDialog(mActivity).show();
|
2017-05-31 15:51:07 +02:00
|
|
|
}
|
2017-07-11 13:50:40 +02:00
|
|
|
});
|
|
|
|
createPluginsList(device.getPluginsWithoutOptionalPermissions(), R.string.plugins_need_optional_permission, new PluginClickListener() {
|
|
|
|
@Override
|
|
|
|
void action() {
|
|
|
|
plugin.getOptionalPermissionExplanationDialog(mActivity).show();
|
2017-05-31 15:51:07 +02:00
|
|
|
}
|
2017-07-11 13:50:40 +02:00
|
|
|
});
|
2017-05-31 15:51:07 +02:00
|
|
|
|
2015-09-12 13:21:06 -07:00
|
|
|
ListView buttonsList = (ListView) rootView.findViewById(R.id.buttons_list);
|
2017-07-11 13:50:40 +02:00
|
|
|
ListAdapter adapter = new ListAdapter(mActivity, pluginListItems);
|
2015-09-12 13:21:06 -07:00
|
|
|
buttonsList.setAdapter(adapter);
|
2015-09-07 00:11:46 -07:00
|
|
|
|
2015-09-12 13:21:06 -07:00
|
|
|
mActivity.invalidateOptionsMenu();
|
2015-09-07 00:11:46 -07:00
|
|
|
|
2015-09-12 13:21:06 -07:00
|
|
|
} catch (IllegalStateException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
//Ignore: The activity was closed while we were trying to update it
|
|
|
|
} catch (ConcurrentModificationException e) {
|
|
|
|
Log.e("DeviceActivity", "ConcurrentModificationException");
|
|
|
|
this.run(); //Try again
|
|
|
|
}
|
2015-09-07 00:11:46 -07:00
|
|
|
|
2015-09-12 13:21:06 -07:00
|
|
|
}
|
2015-09-04 06:05:21 -07:00
|
|
|
}
|
|
|
|
});
|
2015-09-07 00:11:46 -07:00
|
|
|
|
2015-09-04 06:05:21 -07:00
|
|
|
}
|
2015-09-07 00:11:46 -07:00
|
|
|
|
2017-02-05 15:42:42 +01:00
|
|
|
final Device.PairingCallback pairingCallback = new Device.PairingCallback() {
|
2015-09-07 00:11:46 -07:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void incomingRequest() {
|
2015-09-12 13:21:06 -07:00
|
|
|
refreshUI();
|
2015-09-07 00:11:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void pairingSuccessful() {
|
|
|
|
refreshUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void pairingFailed(final String error) {
|
|
|
|
mActivity.runOnUiThread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2017-02-05 15:34:16 +01:00
|
|
|
if (rootView == null) return;
|
2015-09-07 00:11:46 -07:00
|
|
|
((TextView) rootView.findViewById(R.id.pair_message)).setText(error);
|
|
|
|
rootView.findViewById(R.id.pair_progress).setVisibility(View.GONE);
|
|
|
|
rootView.findViewById(R.id.pair_button).setVisibility(View.VISIBLE);
|
|
|
|
rootView.findViewById(R.id.pair_request).setVisibility(View.GONE);
|
|
|
|
refreshUI();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void unpaired() {
|
|
|
|
mActivity.runOnUiThread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2017-02-05 15:34:16 +01:00
|
|
|
if (rootView == null) return;
|
2015-09-07 00:11:46 -07:00
|
|
|
((TextView) rootView.findViewById(R.id.pair_message)).setText(R.string.device_not_paired);
|
|
|
|
rootView.findViewById(R.id.pair_progress).setVisibility(View.GONE);
|
|
|
|
rootView.findViewById(R.id.pair_button).setVisibility(View.VISIBLE);
|
|
|
|
rootView.findViewById(R.id.pair_request).setVisibility(View.GONE);
|
|
|
|
refreshUI();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-07-11 13:50:40 +02:00
|
|
|
public static void acceptPairing(final String devId, final MaterialActivity activity) {
|
2017-02-05 15:19:46 +01:00
|
|
|
final DeviceFragment frag = new DeviceFragment(devId, activity);
|
|
|
|
BackgroundService.RunCommand(activity, new BackgroundService.InstanceCallback() {
|
|
|
|
public void onServiceStart(BackgroundService service) {
|
|
|
|
Device dev = service.getDevice(devId);
|
2017-05-24 00:21:45 +02:00
|
|
|
if (dev == null) {
|
2018-03-03 16:06:52 +01:00
|
|
|
Log.w("rejectPairing", "Device no longer exists: " + devId);
|
2017-05-24 00:21:45 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-02-05 15:19:46 +01:00
|
|
|
activity.getSupportActionBar().setTitle(dev.getName());
|
|
|
|
|
|
|
|
dev.addPairingCallback(frag.pairingCallback);
|
|
|
|
dev.addPluginsChangedListener(frag.pluginsChangedListener);
|
|
|
|
|
|
|
|
frag.device = dev;
|
|
|
|
frag.device.acceptPairing();
|
2017-02-05 15:42:03 +01:00
|
|
|
|
|
|
|
frag.refreshUI();
|
|
|
|
|
2017-02-05 15:19:46 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-07-11 13:50:40 +02:00
|
|
|
public static void rejectPairing(final String devId, final MaterialActivity activity) {
|
2017-02-05 15:19:46 +01:00
|
|
|
final DeviceFragment frag = new DeviceFragment(devId, activity);
|
|
|
|
BackgroundService.RunCommand(activity, new BackgroundService.InstanceCallback() {
|
|
|
|
public void onServiceStart(BackgroundService service) {
|
|
|
|
Device dev = service.getDevice(devId);
|
2017-05-24 00:21:45 +02:00
|
|
|
if (dev == null) {
|
2018-03-03 16:06:52 +01:00
|
|
|
Log.w("rejectPairing", "Device no longer exists: " + devId);
|
2017-05-24 00:21:45 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-02-05 15:19:46 +01:00
|
|
|
activity.getSupportActionBar().setTitle(dev.getName());
|
|
|
|
|
|
|
|
dev.addPairingCallback(frag.pairingCallback);
|
|
|
|
dev.addPluginsChangedListener(frag.pluginsChangedListener);
|
|
|
|
|
|
|
|
frag.device = dev;
|
2017-02-05 15:42:03 +01:00
|
|
|
|
2017-02-05 15:19:46 +01:00
|
|
|
//Remove listener so buttons don't show for a while before changing the view
|
|
|
|
frag.device.removePluginsChangedListener(frag.pluginsChangedListener);
|
|
|
|
frag.device.removePairingCallback(frag.pairingCallback);
|
|
|
|
frag.device.rejectPairing();
|
|
|
|
activity.onDeviceSelected(null);
|
2017-02-05 15:42:03 +01:00
|
|
|
|
|
|
|
frag.refreshUI();
|
2017-02-05 15:19:46 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2017-07-11 13:50:40 +02:00
|
|
|
|
2017-07-24 16:39:00 +02:00
|
|
|
void createPluginsList(ConcurrentHashMap<String, Plugin> plugins, int headerText, PluginClickListener onClickListener) {
|
2017-07-11 13:50:40 +02:00
|
|
|
if (!plugins.isEmpty()) {
|
|
|
|
|
|
|
|
TextView header = new TextView(mActivity);
|
|
|
|
header.setPadding(
|
|
|
|
0,
|
|
|
|
((int) (28 * getResources().getDisplayMetrics().density)),
|
|
|
|
0,
|
|
|
|
((int) (8 * getResources().getDisplayMetrics().density))
|
|
|
|
);
|
|
|
|
header.setOnClickListener(null);
|
|
|
|
header.setOnLongClickListener(null);
|
|
|
|
header.setText(headerText);
|
|
|
|
|
|
|
|
pluginListItems.add(new CustomItem(header));
|
|
|
|
for (Map.Entry<String, Plugin> entry : plugins.entrySet()) {
|
|
|
|
String pluginKey = entry.getKey();
|
|
|
|
final Plugin plugin = entry.getValue();
|
|
|
|
if (device.isPluginEnabled(pluginKey)) {
|
|
|
|
if (plugin == null) {
|
|
|
|
pluginListItems.add(new SmallEntryItem(pluginKey));
|
|
|
|
} else {
|
|
|
|
PluginClickListener listener = onClickListener.clone();
|
|
|
|
listener.plugin = plugin;
|
|
|
|
pluginListItems.add(new SmallEntryItem(plugin.getDisplayName(), listener));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private abstract class PluginClickListener implements View.OnClickListener, Cloneable {
|
|
|
|
|
|
|
|
Plugin plugin;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
action();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2018-03-03 16:06:52 +01:00
|
|
|
public PluginClickListener clone() {
|
2017-07-11 13:50:40 +02:00
|
|
|
try {
|
|
|
|
return (PluginClickListener) super.clone();
|
|
|
|
} catch (CloneNotSupportedException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
abstract void action();
|
|
|
|
}
|
|
|
|
|
2015-08-20 00:59:21 -07:00
|
|
|
}
|