org.deviceconnect.android.manager.setting.DevicePluginInfoFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.deviceconnect.android.manager.setting.DevicePluginInfoFragment.java

Source

/*
 DevicePluginInfoFragment.java
 Copyright (c) 2015 NTT DOCOMO,INC.
 Released under the MIT license
 http://opensource.org/licenses/mit-license.php
 */
package org.deviceconnect.android.manager.setting;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import org.deviceconnect.android.localoauth.DevicePluginXmlProfile;
import org.deviceconnect.android.localoauth.DevicePluginXmlProfileLocale;
import org.deviceconnect.android.manager.BuildConfig;
import org.deviceconnect.android.manager.DConnectService;
import org.deviceconnect.android.manager.R;
import org.deviceconnect.android.manager.core.plugin.CommunicationHistory;
import org.deviceconnect.android.manager.core.plugin.ConnectionError;
import org.deviceconnect.android.manager.core.plugin.ConnectionState;
import org.deviceconnect.android.manager.core.plugin.DevicePlugin;
import org.deviceconnect.android.manager.core.plugin.DevicePluginManager;
import org.deviceconnect.android.manager.core.plugin.MessagingException;
import org.deviceconnect.android.manager.core.util.DConnectUtil;
import org.deviceconnect.message.intent.message.IntentDConnectMessage;

import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * Device plug-in information fragment.
 *
 * @author NTT DOCOMO, INC.
 */
public class DevicePluginInfoFragment extends BaseSettingFragment {

    /** ???. */
    private static final int REQUEST_CODE = 101;

    /** ?. */
    private DevicePlugin.Info mPluginInfo;

    /** . */
    private ConnectionErrorView mErrorView;

    /** ??????. */
    private final DevicePluginManager.DevicePluginEventListener mEventListener = new DevicePluginManager.DevicePluginEventListener() {
        @Override
        public void onConnectionStateChanged(final DevicePlugin plugin, final ConnectionState state) {
            runOnUiThread(() -> {
                ConnectionErrorView errorView = mErrorView;
                if (errorView != null) {
                    errorView.showErrorMessage(plugin);
                }
            });
        }

        @Override
        public void onDeviceFound(final DevicePlugin plugin) {
            // NOP.
        }

        @Override
        public void onDeviceLost(final DevicePlugin plugin) {
            // NOP.
        }
    };

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
            final Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_deviceplugin_info, container, false);
    }

    /**
     * ?.
     * @param plugin ?
     */
    public void updateInfo(final DevicePlugin plugin) {
        View view = getView();
        if (view == null) {
            return;
        }

        mPluginInfo = plugin.getInfo();

        boolean isEnabled = plugin.isEnabled();

        String packageName = mPluginInfo.getPackageName();
        Integer iconId = mPluginInfo.getPluginIconId();
        String name = mPluginInfo.getDeviceName();
        Drawable icon = DConnectUtil.loadPluginIcon(getActivity(), packageName, iconId);
        String versionName = mPluginInfo.getVersionName();
        String managerPackageName = getActivity().getPackageName();

        TextView nameView = view.findViewById(R.id.plugin_package_name);
        nameView.setText(name);
        if (icon != null) {
            ImageView iconView = view.findViewById(R.id.plugin_icon);
            iconView.setImageDrawable(icon);
        }

        TextView versionView = view.findViewById(R.id.plugin_version);
        versionView.setText(getString(R.string.activity_deviceplugin_info_version, versionName));

        Button settingBtn = view.findViewById(R.id.plugin_settings_btn);
        settingBtn.setEnabled(isEnabled);
        settingBtn.setOnClickListener((v) -> {
            openSettings();
        });

        Button deleteBtn = view.findViewById(R.id.plugin_delete_btn);
        deleteBtn.setOnClickListener((v) -> {
            openUninstall();
        });
        deleteBtn.setEnabled(!packageName.equals(managerPackageName));

        Button restartBtn = view.findViewById(R.id.plugin_restart_btn);
        restartBtn.setEnabled(isEnabled);
        restartBtn.setOnClickListener((v) -> {
            restartDevicePlugin();
        });

        TextView connectionTypeView = view.findViewById(R.id.plugin_connection_type);
        int resId;
        switch (mPluginInfo.getConnectionType()) {
        case BINDER:
            resId = R.string.activity_deviceplugin_info_connection_type_binder;
            break;
        case BROADCAST:
            resId = R.string.activity_deviceplugin_info_connection_type_broadcast;
            break;
        case INTERNAL:
            resId = R.string.activity_deviceplugin_info_connection_type_included_with_manager;
            break;
        default:
            resId = R.string.activity_deviceplugin_info_connection_type_unknown;
            break;
        }
        connectionTypeView.setText(getString(resId));

        LinearLayout mainLayout = view.findViewById(R.id.plugin_support_profiles);

        Map<String, DevicePluginXmlProfile> profiles = mPluginInfo.getSupportedProfiles();
        if (profiles != null) {
            String locale = Locale.getDefault().getLanguage();
            for (String key : profiles.keySet()) {
                String profileName = key;
                DevicePluginXmlProfile p = profiles.get(key);
                if (p != null) {
                    Map<String, DevicePluginXmlProfileLocale> locales = p.getXmlProfileLocales();
                    if (locales != null) {
                        DevicePluginXmlProfileLocale xmlLocale = locales.get(locale);
                        if (xmlLocale != null) {
                            profileName = xmlLocale.getName();
                        }
                    }
                }
                TextView tv = new TextView(getActivity());
                tv.setText(getString(R.string.activity_deviceplugin_info_profile_name, profileName));
                mainLayout.addView(tv);
            }
        }

        mErrorView = view.findViewById(R.id.plugin_connection_error_view);
        mErrorView.showErrorMessage(plugin);

        if (BuildConfig.DEBUG) {
            CommunicationHistory history = plugin.getHistory();

            View baud = view.findViewById(R.id.activity_deviceplugin_info_baud_rate);
            baud.setVisibility(View.VISIBLE);

            TextView average = baud.findViewById(R.id.activity_deviceplugin_info_average_baud_rate);
            average.setText(
                    getString(R.string.activity_deviceplugin_info_baud_rate_unit, history.getAverageBaudRate()));

            TextView request = baud.findViewById(R.id.activity_deviceplugin_info_worst_request);
            request.setText(history.getWorstBaudRateRequest());

            TextView worst = baud.findViewById(R.id.activity_deviceplugin_info_worst_baud_rate);
            worst.setText(
                    getString(R.string.activity_deviceplugin_info_baud_rate_unit, history.getWorstBaudRate()));

            LayoutInflater inflater = getLayoutInflater();

            LinearLayout baudRateListLayout = baud.findViewById(R.id.activity_deviceplugin_info_baud_rate_list);
            baudRateListLayout.removeAllViews();
            List<CommunicationHistory.Info> baudRateList = history.getRespondedCommunications();
            for (int i = baudRateList.size() - 1; i >= 0; i--) {
                CommunicationHistory.Info b = baudRateList.get(i);

                View v = inflater.inflate(R.layout.item_baud_rate_list, null);
                TextView br = v.findViewById(R.id.activity_deviceplugin_info_request);
                br.setText(b.getRequestPath());

                TextView bb = v.findViewById(R.id.activity_deviceplugin_info_baud_rate);
                bb.setText(getString(R.string.activity_deviceplugin_info_baud_rate_unit, b.getRoundTripTime()));

                TextView d = v.findViewById(R.id.activity_deviceplugin_info_date);
                d.setText(b.getDateString());

                baudRateListLayout.addView(v);
            }

            LinearLayout timeoutListLayout = baud.findViewById(R.id.activity_deviceplugin_info_timeout_list);
            timeoutListLayout.removeAllViews();
            List<CommunicationHistory.Info> timeoutList = history.getNotRespondedCommunications();
            for (int i = timeoutList.size() - 1; i >= 0; i--) {
                CommunicationHistory.Info t = timeoutList.get(i);

                View v = inflater.inflate(R.layout.item_timeout_list, null);
                TextView br = v.findViewById(R.id.activity_deviceplugin_info_request);
                br.setText(t.getRequestPath());

                TextView d = v.findViewById(R.id.activity_deviceplugin_info_date);
                d.setText(t.getDateString());

                timeoutListLayout.addView(v);
            }
        }
    }

    /**
     * ??.
     * @param error 
     */
    public void updateErrorState(final ConnectionError error) {
        mErrorView.showErrorMessage(error);
    }

    /**
     * ??RunnableUI???.
     * @param r ?Runnable
     */
    private void runOnUiThread(final Runnable r) {
        Activity activity = getActivity();
        if (activity != null) {
            activity.runOnUiThread(r);
        }
    }

    /**
     * ??.
     * @param isEnabled ???true????false
     */
    void onEnabled(final boolean isEnabled) {
        runOnUiThread(() -> {
            View view = getView();
            if (view != null) {
                Button settingBtn = (Button) view.findViewById(R.id.plugin_settings_btn);
                settingBtn.setEnabled(isEnabled);
                Button restartBtn = (Button) view.findViewById(R.id.plugin_restart_btn);
                restartBtn.setEnabled(isEnabled);
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        if (android.R.id.home == item.getItemId()) {
            getActivity().finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE) {
            if (!existApplicationFromPackageName(mPluginInfo.getPackageName())) {
                getActivity().finish();
            }
        }
    }

    @Override
    protected void onManagerBonded(final DConnectService manager) {
        DevicePluginManager mgr = getPluginManager();
        if (mgr != null) {
            mgr.addEventListener(mEventListener);
            String pluginId = getArguments().getString(DevicePluginInfoActivity.EXTRA_PLUGIN_ID);
            if (pluginId != null) {
                DevicePlugin plugin = mgr.getDevicePlugin(pluginId);
                if (plugin != null) {
                    updateInfo(plugin);
                }
            }
        }
    }

    @Override
    protected void beforeManagerDisconnected() {
        DevicePluginManager mgr = getPluginManager();
        if (mgr != null) {
            mgr.removeEventListener(mEventListener);
        }
    }

    /**
     * Open device plug-in's settings.
     */
    private void openSettings() {
        BaseSettingActivity activity = (BaseSettingActivity) getActivity();
        if (activity == null) {
            return;
        }

        DConnectService service = activity.getManagerService();
        if (service != null) {
            service.openPluginSettings(mPluginInfo.getPluginId());
        }
    }

    /**
     * ?.
     * @param e ???
     */
    private void showMessagingErrorDialog(final MessagingException e) {
        Activity activity = getActivity();
        if (activity != null && activity instanceof BaseSettingActivity) {
            ((BaseSettingActivity) activity).showMessagingErrorDialog(e);
        }
    }

    /**
     * Open uninstall dialog.
     */
    private void openUninstall() {
        Uri uri = Uri.fromParts("package", mPluginInfo.getPackageName(), null);
        Intent intent = new Intent(Intent.ACTION_DELETE, uri);
        startActivityForResult(intent, REQUEST_CODE);
    }

    /**
     * Restart device plug-in.
     */
    private void restartDevicePlugin() {
        AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            private StartingDialogFragment mDialog;

            @Override
            protected void onPreExecute() {
                if (getActivity() != null) {
                    mDialog = new StartingDialogFragment();
                    mDialog.show(getFragmentManager(), "dialog");
                }
            }

            @Override
            protected Void doInBackground(final Void... params) {
                DevicePluginManager mgr = getPluginManager();
                if (mgr == null) {
                    return null;
                }
                List<DevicePlugin> plugins = mgr.getDevicePlugins();
                for (DevicePlugin plugin : plugins) {
                    if (plugin.isEnabled() && plugin.getPackageName().equals(mPluginInfo.getPackageName())
                            && plugin.getPluginId() != null) {
                        restartDevicePlugin(plugin);
                        break;
                    }
                }
                return null;
            }

            @Override
            protected void onPostExecute(final Void o) {
                if (mDialog != null) {
                    mDialog.dismiss();
                }
            }
        };
        task.execute();
    }

    /**
     * Start a device plugin.
     *
     * @param plugin device plugin to be started
     */
    private void restartDevicePlugin(final DevicePlugin plugin) {
        Intent request = new Intent();
        request.setComponent(plugin.getComponentName());
        request.setAction(IntentDConnectMessage.ACTION_DEVICEPLUGIN_RESET);
        request.putExtra("pluginId", plugin.getPluginId());
        try {
            plugin.send(request);
        } catch (MessagingException e) {
            showMessagingErrorDialog(e);
        }
    }

    /**
     * Tests whether packageName exists in application list.
     *
     * @param packageName package name
     * @return true if packageName exists, false otherwise
     */
    private boolean existApplicationFromPackageName(final String packageName) {
        if (packageName == null) {
            return false;
        }

        final PackageManager pm = getActivity().getPackageManager();
        final int flags = PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.MATCH_DISABLED_COMPONENTS;
        final List<ApplicationInfo> installedAppList = pm.getInstalledApplications(flags);
        for (ApplicationInfo app : installedAppList) {
            if (app.packageName.equals(packageName)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Show a dialog of restart a device plugin.
     */
    public static class StartingDialogFragment extends DialogFragment {
        @Override
        public Dialog onCreateDialog(final Bundle savedInstanceState) {
            String title = getString(R.string.activity_settings_restart_device_plugin_title);
            String msg = getString(R.string.activity_settings_restart_device_plugin_message);
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            LayoutInflater inflater = getActivity().getLayoutInflater();
            View v = inflater.inflate(R.layout.dialog_progress, null);
            TextView titleView = v.findViewById(R.id.title);
            TextView messageView = v.findViewById(R.id.message);
            titleView.setText(title);
            messageView.setText(msg);
            builder.setView(v);

            return builder.create();
        }

        @Override
        public void onPause() {
            dismiss();
            super.onPause();
        }
    }
}