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

Java tutorial

Introduction

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

Source

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

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.AbstractContentBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.deviceconnect.android.cipher.signature.AuthSignature;
import org.deviceconnect.android.manager.DConnectSettings;
import org.deviceconnect.android.manager.R;
import org.deviceconnect.android.manager.profile.AuthorizationProfile;
import org.deviceconnect.android.profile.NetworkServiceDiscoveryProfile;
import org.deviceconnect.message.DConnectMessage;
import org.deviceconnect.message.DConnectMessage.ErrorCode;
import org.deviceconnect.profile.AuthorizationProfileConstants;
import org.deviceconnect.profile.BatteryProfileConstants;
import org.deviceconnect.profile.ConnectProfileConstants;
import org.deviceconnect.profile.DeviceOrientationProfileConstants;
import org.deviceconnect.profile.FileDescriptorProfileConstants;
import org.deviceconnect.profile.FileProfileConstants;
import org.deviceconnect.profile.MediaPlayerProfileConstants;
import org.deviceconnect.profile.MediaStreamRecordingProfileConstants;
import org.deviceconnect.profile.NetworkServiceDiscoveryProfileConstants;
import org.deviceconnect.profile.NotificationProfileConstants;
import org.deviceconnect.profile.PhoneProfileConstants;
import org.deviceconnect.profile.ProximityProfileConstants;
import org.deviceconnect.profile.SettingsProfileConstants;
import org.deviceconnect.profile.SystemProfileConstants;
import org.deviceconnect.profile.VibrationProfileConstants;
import org.deviceconnect.utils.AuthProcesser;
import org.deviceconnect.utils.AuthProcesser.AuthorizationHandler;
import org.deviceconnect.utils.URIBuilder;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.ToggleButton;

/**
 * d-Connect RESTfulAPI?????????Activity.
 * @author NTT DOCOMO, INC.
 */
public class ReqResDebugActivity extends Activity implements View.OnClickListener, OnItemSelectedListener {
    /**
     * ???????ListView.
     */
    private ArrayAdapter<String> mListAdapter;
    /**
     * Http Method??Spinner.
     */
    private Spinner mHM;
    /**
     * Profile??Spinner.
     */
    private Spinner mProf;
    /**
     * Interfaces??Spinner.
     */
    private Spinner mInter;
    /**
     * Attribute??Spinner.
     */
    private Spinner mAttrib;
    /**
     * deviceId??Spineer.
     */
    private Spinner mDI;

    /** Websocket?On/Off?. */
    private ToggleButton mWebsocketBtn;

    /** ??. */
    private EditText mTextPath;

    /**
     * Spinner????URL????CheckBox.
     */
    private CheckBox mSelectUrl;
    /**
     * WebSocket?.
     */
    private WebSocketClient mWebsocketClient;

    /** ?. */
    private ProgressDialog mProgressDialog;

    /** dConnect?. */
    private DConnectSettings mSettings;

    /** SharedPrefernce??????. */
    private static final String PREF_KEY = "debug_localoauth.txt";
    /** ID?. */
    private static final String KEY_CLIENT_ID = "client_id";
    /** ?. */
    private static final String KEY_CLIENT_SECRET = "client_secret";
    /** ?. */
    private static final String KEY_ACCESS_TOKEN = "access_token";

    /** SharedPreferences?. */
    private SharedPreferences mPref;
    /** SharedPreferences?. */
    private SharedPreferences.Editor mEditor;

    /**
     * ???.
     */
    private String[] mScopes = { AuthorizationProfileConstants.PROFILE_NAME, BatteryProfileConstants.PROFILE_NAME,
            ConnectProfileConstants.PROFILE_NAME, DeviceOrientationProfileConstants.PROFILE_NAME,
            FileDescriptorProfileConstants.PROFILE_NAME, FileProfileConstants.PROFILE_NAME,
            MediaPlayerProfileConstants.PROFILE_NAME, MediaStreamRecordingProfileConstants.PROFILE_NAME,
            NetworkServiceDiscoveryProfileConstants.PROFILE_NAME, NotificationProfileConstants.PROFILE_NAME,
            PhoneProfileConstants.PROFILE_NAME, ProximityProfileConstants.PROFILE_NAME,
            SettingsProfileConstants.PROFILE_NAME, SystemProfileConstants.PROFILE_NAME,
            VibrationProfileConstants.PROFILE_NAME,

            // 
            "light", "camera", "temperature", "dice", "sphero", "drive_controller", "remote_controller", "mhealth",

            // 
            "*" };

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPref = getSharedPreferences(PREF_KEY, Activity.MODE_PRIVATE);
        mEditor = mPref.edit();
        getActionBar().setTitle(R.string.app_name);
        setContentView(R.layout.activity_debug_main);
        findViewById(R.id.reqSend).setOnClickListener(this);
        initUI();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // websocket??????????

        // DConnect
        mSettings = DConnectSettings.getInstance();
        mSettings.load(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // websocket??????????
    }

    @Override
    public boolean onCreateOptionsMenu(final Menu menu) {
        getMenuInflater().inflate(R.menu.activity_debug_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            Intent intent = new Intent(this, SettingActivity.class);
            startActivity(intent);
        } else if (id == R.id.action_search) {
            mListAdapter.clear();
            executeNetworkServiceDiscovery();
        } else if (id == R.id.action_access_token) {
            String clientId = mPref.getString(KEY_CLIENT_ID, null);
            String clientSecret = mPref.getString(KEY_CLIENT_SECRET, null);
            if (clientId == null || clientSecret == null) {
                checkAuthorization(null);
            } else {
                requestAccessToken(clientId, clientSecret, null);
            }
        } else if (id == R.id.action_session_key) {
            inputSessionKey();
        }
        return true;
    }

    @Override
    public void onClick(final View v) {
        mListAdapter.clear();

        int id = v.getId();
        if (id == R.id.reqSend) {
            executeHttpRequest();
        } else if (id == R.id.reqWesocket) {
            if (mWebsocketBtn.isChecked()) {
                execWebsocket();
            } else {
                closeWebsocket();
            }
        }
    }

    /**
     * UI??.
     */
    private void initUI() {
        // ?
        mListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);

        // 
        ListView listView = (ListView) findViewById(R.id.reqResList);
        listView.setAdapter(mListAdapter);
        initSpinner();

        // ?
        mTextPath = (EditText) findViewById(R.id.reqPath);

        // URL?
        mSelectUrl = (CheckBox) findViewById(R.id.isUrl);
        mSelectUrl.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
                enableSetting(buttonView.isChecked());
            }
        });

        mWebsocketBtn = (ToggleButton) findViewById(R.id.reqWesocket);
        mWebsocketBtn.setOnClickListener(this);
    }

    /**
     * Spinner??.
     */
    private void initSpinner() {
        ArrayAdapter<CharSequence> adapterHttpMethod = ArrayAdapter.createFromResource(this, R.array.http_methods,
                android.R.layout.simple_spinner_item);
        adapterHttpMethod.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        ArrayAdapter<CharSequence> adapterProfile = ArrayAdapter.createFromResource(this,
                R.array.dconnect_profile_list, android.R.layout.simple_spinner_item);
        adapterProfile.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.string_empty,
                android.R.layout.simple_spinner_item);
        mHM = (Spinner) findViewById(R.id.reqMethod);
        mHM.setAdapter(adapterHttpMethod);
        mHM.setOnItemSelectedListener(this);
        mProf = (Spinner) findViewById(R.id.reqProfile);
        mProf.setAdapter(adapterProfile);
        mProf.setOnItemSelectedListener(this);
        mInter = (Spinner) findViewById(R.id.reqInterfaces);
        mInter.setOnItemSelectedListener(this);
        mInter.setAdapter(adapter);
        mAttrib = (Spinner) findViewById(R.id.reqAttribute);
        mAttrib.setOnItemSelectedListener(this);
        mAttrib.setAdapter(adapter);
        mDI = (Spinner) findViewById(R.id.reqDeviceid);
        mDI.setOnItemSelectedListener(this);
        mDI.setAdapter(adapter);
    }

    /**
     * profile,interfaces,attributeUI??.
     * @param enabled true???????????
     */
    private void enableSetting(final boolean enabled) {
        mProf.setEnabled(enabled);
        mInter.setEnabled(enabled);
        mAttrib.setEnabled(enabled);
        if (enabled) {
            mTextPath.setHint(R.string.url_hint1);
        } else {
            mTextPath.setHint(R.string.url_hint2);
        }
    }

    /**
     * ?.
     */
    private void openErrorDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("?");
        builder.setMessage("???????");
        builder.create().show();
    }

    /**
     * ?.
     */
    private void inputSessionKey() {
        String clientId = mPref.getString(KEY_CLIENT_ID, null);
        if (clientId != null) {
            mTextPath.setText("sessionKey=" + clientId);
        }
    }

    /**
     * WebSocket?.
     */
    private void execWebsocket() {
        // ID?????????
        final String clientId = mPref.getString(KEY_CLIENT_ID, null);
        if (clientId == null) {
            openErrorDialog();
            return;
        }

        if (mWebsocketClient != null && mWebsocketClient.isConnecting()) {
            mWebsocketClient.close();
            mWebsocketClient = null;
        }

        StringBuilder sb = new StringBuilder();
        if (mSettings.isSSL()) {
            sb.append("wss://");
        } else {
            sb.append("ws://");
        }
        sb.append(mSettings.getHost());
        sb.append(":");
        sb.append(mSettings.getPort());
        sb.append("/websocket");

        URI uri = URI.create(sb.toString());
        mWebsocketClient = new WebSocketClient(uri) {
            @Override
            public void onOpen(final ServerHandshake handshake) {
                try {
                    JSONObject root = new JSONObject();
                    root.put(DConnectMessage.EXTRA_SESSION_KEY, clientId);
                    mWebsocketClient.send(root.toString());
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mListAdapter.add("Websocket open:\n");
                            mListAdapter.notifyDataSetChanged();
                        }
                    });
                } catch (JSONException e) {
                    return; // do nothing.
                }
            }

            @Override
            public void onMessage(final String message) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mListAdapter.add("Event:\n" + message);
                        mListAdapter.notifyDataSetChanged();
                    }
                });
            }

            @Override
            public void onError(final Exception ex) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mListAdapter.add("Websocket ERROR:\n" + ex.getMessage());
                        mListAdapter.notifyDataSetChanged();
                        mWebsocketBtn.setChecked(false);
                    }
                });
            }

            @Override
            public void onClose(final int code, final String reason, final boolean remote) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mListAdapter.add("Websocket close:\n");
                        mListAdapter.notifyDataSetChanged();
                        mWebsocketBtn.setChecked(false);
                    }
                });
            }
        };
        mWebsocketClient.connect();
    }

    /**
     * WebSocket?.
     */
    private void closeWebsocket() {
        if (mWebsocketClient != null) {
            mWebsocketClient.close();
            mWebsocketClient = null;
        }
    }

    /**
     * ?null????????.
     * @param text ??
     * @return null???????true????false
     */
    private boolean isEmpty(final String text) {
        return (text == null || text.trim().isEmpty() || text.trim().equals(""));
    }

    /**
     * ??query??.
     * @return query
     */
    private List<NameValuePair> createQuery() {
        String deviceId = mDI.getSelectedItem().toString();
        String path = mTextPath.getText().toString();

        List<NameValuePair> params = new ArrayList<NameValuePair>();

        // deviceid??????
        if (!isEmpty(deviceId)) {
            params.add(new BasicNameValuePair(DConnectMessage.EXTRA_DEVICE_ID, deviceId));
        }

        // 
        if (mSettings.isUseALocalOAuth()) {
            String accessToken = mPref.getString(KEY_ACCESS_TOKEN, null);
            if (accessToken != null) {
                params.add(new BasicNameValuePair(DConnectMessage.EXTRA_ACCESS_TOKEN, accessToken));
            }
        }

        if (!isEmpty(path)) {
            String[] keyvalues = path.split("&");
            for (int i = 0; i < keyvalues.length; i++) {
                String[] kv = keyvalues[i].split("=");
                if (kv.length == 1) {
                    params.add(new BasicNameValuePair(kv[0], ""));
                } else if (kv.length == 2) {
                    params.add(new BasicNameValuePair(kv[0], kv[1]));
                }
            }
        }

        return params;
    }

    /**
     * ??.
     * ????????
     * @return ?????true??????false
     */
    private synchronized boolean showProgressDialog() {
        if (mProgressDialog != null) {
            return false;
        }
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setTitle("dConnect?");
        mProgressDialog.setMessage("????????.");
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        mProgressDialog.setCancelable(false);
        mProgressDialog.show();
        return true;
    }

    /**
     * ????.
     */
    private synchronized void hideProgressDialog() {
        if (mProgressDialog != null) {
            mProgressDialog.dismiss();
            mProgressDialog = null;
        }
    }

    /**
     * LocalOAuth????.
     * @param listener ??
     */
    private void authorizateLocalOAuth(final AuthorizationHandler listener) {
        AuthProcesser.asyncAuthorize(mSettings.getHost(), mSettings.getPort(), mSettings.isSSL(), getPackageName(),
                this.getClass().getSimpleName(), mScopes, listener);
    }

    /**
     * Local OAuth?????.
     * ?????????????.
     * @param run ???
     * @return ????????true????false
     */
    private boolean checkAuthorization(final Runnable run) {
        String clientId = mPref.getString(KEY_CLIENT_ID, null);
        String clientSecret = mPref.getString(KEY_CLIENT_SECRET, null);
        if (clientId == null || clientSecret == null) {
            authorizateLocalOAuth(new AuthorizationHandler() {
                @Override
                public void onAuthorized(final String clientId, final String clientSecret,
                        final String accessToken) {
                    mEditor.putString(KEY_CLIENT_ID, clientId);
                    mEditor.putString(KEY_CLIENT_SECRET, clientSecret);
                    mEditor.putString(KEY_ACCESS_TOKEN, accessToken);
                    mEditor.commit();
                    if (run != null) {
                        run.run();
                    }
                }

                @Override
                public void onAuthFailed(final ErrorCode error) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(ReqResDebugActivity.this, "Failed to get a accessToken.",
                                    Toast.LENGTH_LONG).show();
                        }
                    });
                }
            });
            return true;
        }
        return false;
    }

    /**
     * ??.
     * @param clientId ID
     * @param clientSecret 
     * @param listener 
     */
    private void requestAccessToken(final String clientId, final String clientSecret,
            final AccessTokenListener listener) {
        String signature = createSignature(clientId, mScopes, clientSecret);

        URIBuilder builder = createURIBuilder();
        builder.setProfile(AuthorizationProfileConstants.PROFILE_NAME);
        builder.setAttribute(AuthorizationProfileConstants.ATTRIBUTE_REQUEST_ACCESS_TOKEN);
        builder.addParameter(AuthorizationProfileConstants.PARAM_CLIENT_ID, clientId);
        builder.addParameter(AuthorizationProfileConstants.PARAM_SCOPE, combineStr(mScopes));
        builder.addParameter(AuthorizationProfileConstants.PARAM_APPLICATION_NAME, getPackageName());
        builder.addParameter(AuthorizationProfileConstants.PARAM_GRANT_TYPE,
                AuthorizationProfileConstants.GrantType.AUTHORIZATION_CODE.getValue());
        builder.addParameter(AuthorizationProfile.PARAM_SIGNATURE, signature);

        executeHttpRequest(HttpGet.METHOD_NAME, builder, new HttpListener() {
            @Override
            public void onReceivedResponse(final String response) {
                try {
                    parseRequestAccessToken(new JSONObject(response), listener);
                } catch (JSONException e) {
                    if (listener != null) {
                        listener.onReceivedError();
                    }
                }
            }
        });
    }

    /**
     * ????.
     * @param root ??JSON
     * @param listener 
     * @throws JSONException JSON???????
     */
    private void parseRequestAccessToken(final JSONObject root, final AccessTokenListener listener)
            throws JSONException {
        int result = root.getInt(DConnectMessage.EXTRA_RESULT);
        if (result != DConnectMessage.RESULT_OK) {
            if (listener != null) {
                listener.onReceivedError();
            }
            return;
        }
        String accessToken = root.getString(AuthorizationProfileConstants.PARAM_ACCESS_TOKEN);
        String signature = root.getString(AuthorizationProfileConstants.PARAM_SIGNATURE);
        if (checkSignature(signature, accessToken, mPref.getString(KEY_CLIENT_SECRET, null))) {
            if (listener != null) {
                listener.onReceivedAccessToken(accessToken);
            }
            mEditor.putString(KEY_ACCESS_TOKEN, accessToken);
            mEditor.commit();
        } else {
            if (listener != null) {
                listener.onReceivedError();
            }
        }
    }

    /**
     * ?????????.
     * @param signature ??
     * @param accessToken 
     * @param clinetSecret 
     * @return ??????true????false
     */
    private boolean checkSignature(final String signature, final String accessToken, final String clinetSecret) {
        if (signature == null || accessToken == null) {
            return false;
        }
        try {
            String sig = AuthSignature.generateSignature(accessToken, clinetSecret);
            return signature.equals(sig);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * accessToken????????.
     * @param clientId ID
     * @param scopes 
     * @param clientSecret 
     * @return ??
     */
    private String createSignature(final String clientId, final String[] scopes, final String clientSecret) {
        String signature = null;
        try {
            signature = AuthSignature.generateSignature(clientId,
                    AuthorizationProfileConstants.GrantType.AUTHORIZATION_CODE.getValue(), null, scopes,
                    clientSecret);
            signature = URLEncoder.encode(signature, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return null;
        }
        return signature;
    }

    /**
     * ?????.
     * @param scopes 
     * @return ???
     */
    private String combineStr(final String[] scopes) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < scopes.length; i++) {
            if (i > 0) {
                builder.append(",");
            }
            builder.append(scopes[i].trim());
        }
        return builder.toString();
    }

    /**
     * Network Service Discovery?.
     * ?????????ID??
     */
    private void executeNetworkServiceDiscovery() {
        if (mSettings.isUseALocalOAuth()) {
            boolean result = checkAuthorization(new Runnable() {
                @Override
                public void run() {
                    executeNetworkServiceDiscovery();
                }
            });
            if (result) {
                return;
            }
        }

        URIBuilder builder = createURIBuilder();
        builder.setProfile(NetworkServiceDiscoveryProfile.PROFILE_NAME);
        builder.setAttribute(NetworkServiceDiscoveryProfile.ATTRIBUTE_GET_NETWORK_SERVICES);
        if (mSettings.isUseALocalOAuth()) {
            String accessToken = mPref.getString(KEY_ACCESS_TOKEN, null);
            builder.addParameter(DConnectMessage.EXTRA_ACCESS_TOKEN, accessToken);
        }

        URI uri = null;
        try {
            uri = builder.build();
        } catch (URISyntaxException e) {
            // URI???
            return;
        }

        executeHttpRequest(HttpGet.METHOD_NAME, uri, new HttpListener() {
            @Override
            public void onReceivedResponse(final String response) {
                parseNetworkServieDiscovery(response);
            }
        });
    }

    /**
     * UI?????HTTP????.
     */
    private void executeHttpRequest() {
        if (mSettings.isUseALocalOAuth()) {
            boolean result = checkAuthorization(new Runnable() {
                @Override
                public void run() {
                    executeHttpRequest();
                }
            });
            if (result) {
                return;
            }
        }

        URIBuilder builder = createURIBuilder();
        if (!mSelectUrl.isChecked()) {
            builder.setPath(mTextPath.getText().toString());
        } else {
            String profile = mProf.getSelectedItem().toString();
            String inter = mInter.getSelectedItem().toString();
            String attr = mAttrib.getSelectedItem().toString();
            if (!isEmpty(profile)) {
                builder.setProfile(profile);
            }
            if (!isEmpty(inter)) {
                builder.setInterface(inter);
            }
            if (!isEmpty(attr)) {
                builder.setAttribute(attr);
            }
            builder.setParameters(createQuery());
        }

        String method = mHM.getSelectedItem().toString();
        URI uri = null;
        try {
            uri = builder.build();
        } catch (URISyntaxException e) {
            // URI???
            return;
        }
        executeHttpRequest(method, uri, null);
    }

    /**
     * ??URIBuilder??.
     * @return URIBuilder?
     */
    private URIBuilder createURIBuilder() {
        URIBuilder builder = new URIBuilder();
        if (mSettings.isSSL()) {
            builder.setScheme("https");
        } else {
            builder.setScheme("http");
        }
        builder.setHost(mSettings.getHost());
        builder.setPort(mSettings.getPort());
        return builder;
    }

    /**
     * Http?.
     * @param method HTTP
     * @param builder ?URI
     * @param listener Http????
     */
    private void executeHttpRequest(final String method, final URIBuilder builder, final HttpListener listener) {
        URI uri = null;
        try {
            uri = builder.build();
        } catch (URISyntaxException e) {
            // URI???
            return;
        }
        executeHttpRequest(method, uri, listener);
    }

    /**
     * Http?.
     * @param method HTTP
     * @param uri ?URI
     * @param listener Http????
     */
    private void executeHttpRequest(final String method, final URI uri, final HttpListener listener) {
        HttpUriRequest req = null;
        if (HttpGet.METHOD_NAME.equals(method)) {
            req = new HttpGet(uri.toString());
        } else if (HttpPost.METHOD_NAME.equals(method)) {
            req = new HttpPost(uri.toString());
        } else if (HttpPut.METHOD_NAME.equals(method)) {
            req = new HttpPut(uri.toString());
        } else if (HttpDelete.METHOD_NAME.equals(method)) {
            req = new HttpDelete(uri.toString());
        } else if ("?".equals(method)) {
            AssetManager manager = getAssets();
            try {
                // TODO ??????
                String name = "test.png";

                MultipartEntity entity = new MultipartEntity();
                InputStream in = manager.open(name);
                // ??
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int len;
                byte[] buf = new byte[4096];
                while ((len = in.read(buf)) > 0) {
                    baos.write(buf, 0, len);
                }
                // ?
                entity.addPart(FileProfileConstants.PARAM_DATA, new BinaryBody(baos.toByteArray(), name));

                req = new HttpPost(uri.toString());
                ((HttpPost) req).setEntity(entity);
            } catch (UnsupportedEncodingException e) {
                return;
            } catch (IOException e) {
                return;
            }
        } else {
            return;
        }

        if (req != null) {
            executeHttpRequest(req, listener);
        }
    }

    /**
     * Http?.
     * @param request 
     * @param listener Http????
     */
    private void executeHttpRequest(final HttpUriRequest request, final HttpListener listener) {
        if (!showProgressDialog()) {
            return;
        }
        AsyncTask<HttpUriRequest, HttpUriRequest, String> task = new AsyncTask<HttpUriRequest, HttpUriRequest, String>() {
            @Override
            protected String doInBackground(final HttpUriRequest... params) {
                if (params == null || params.length < 1) {
                    return "Illegal Parameter.";
                }

                HttpUriRequest request = params[0];
                DefaultHttpClient client = new DefaultHttpClient();
                try {
                    HttpResponse response = client.execute(request);
                    switch (response.getStatusLine().getStatusCode()) {
                    case HttpStatus.SC_OK:
                        try {
                            return EntityUtils.toString(response.getEntity(), "UTF-8");
                        } catch (ParseException e) {
                            return e.getMessage();
                        } catch (IOException e) {
                            return e.getMessage();
                        }
                    case HttpStatus.SC_NOT_FOUND:
                        return "Not found. 404";
                    default:
                        return "Http connect error.";
                    }
                } catch (ClientProtocolException e) {
                    return e.getMessage();
                } catch (IOException e) {
                    return e.getMessage();
                } finally {
                    client.getConnectionManager().shutdown();
                }
            }

            @Override
            protected void onPostExecute(final String response) {
                super.onPostExecute(response);

                hideProgressDialog();

                if (response == null) {
                    return;
                }

                StringBuilder sb = new StringBuilder();
                sb.append("Request:\n");
                sb.append(request.getMethod() + " " + request.getURI() + "\n");
                mListAdapter.add(sb.toString());
                mListAdapter.add("Response:\n" + response);
                mListAdapter.notifyDataSetChanged();
                if (listener != null) {
                    listener.onReceivedResponse(response);
                }
            }
        };
        task.execute(request);
    }

    /**
     * Network Service Discovery???.
     * @param res ?JSON
     */
    private void parseNetworkServieDiscovery(final String res) {
        try {
            JSONObject root = new JSONObject(res);
            JSONArray services = root.getJSONArray(NetworkServiceDiscoveryProfile.PARAM_SERVICES);
            if (services == null) {
                return;
            }
            String[] data = new String[services.length() + 1];
            data[0] = " "; // ?????????
            for (int i = 1; i < services.length() + 1; i++) {
                data[i] = services.getJSONObject(i - 1).getString(NetworkServiceDiscoveryProfile.PARAM_ID);
            }
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                    android.R.layout.simple_spinner_dropdown_item, data);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            mDI.setAdapter(adapter);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onItemSelected(final AdapterView<?> parent, final View v, final int position, final long pos) {
        int id = parent.getId();
        Spinner spinner = (Spinner) parent;
        if (id == R.id.reqProfile) {
            String profileName = spinner.getSelectedItem().toString();
            if (!profileName.equals("")) {
                int resInterfacesId = getResources().getIdentifier(profileName + "_interface_list", "array",
                        getPackageName());
                ArrayAdapter<CharSequence> adapterInterfaces = ArrayAdapter.createFromResource(this,
                        resInterfacesId, android.R.layout.simple_spinner_item);
                adapterInterfaces.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                mInter.setAdapter(adapterInterfaces);
                int resAttributeId = getResources().getIdentifier(profileName + "_attrib_list", "array",
                        getPackageName());
                ArrayAdapter<CharSequence> adapterAttribute = ArrayAdapter.createFromResource(this, resAttributeId,
                        android.R.layout.simple_spinner_item);
                adapterInterfaces.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                mAttrib.setAdapter(adapterAttribute);
            }
        }
    }

    @Override
    public void onNothingSelected(final AdapterView<?> parent) {
    }

    /**
     * HTTP?????.
     * @author NTT DOCOMO, INC.
     */
    private interface HttpListener {
        /**
         * HTTP??.
         * @param response HTTP?
         */
        void onReceivedResponse(final String response);
    }

    /**
     * ??.
     * @author NTT DOCOMO, INC.
     */
    private interface AccessTokenListener {
        /**
         * ????????.
         * @param accessToken 
         */
        void onReceivedAccessToken(final String accessToken);

        /**
         * ?????????.
         */
        void onReceivedError();
    }

    /**
     * ??????.
     * @author NTT DOCOMO, INC.
     */
    protected class BinaryBody extends AbstractContentBody {
        /** ??. */
        private String mFileName;
        /** ???. */
        private byte[] mBuffer;

        /**
         * .
         * @param buf ?
         * @param fileName ??
         */
        public BinaryBody(final byte[] buf, final String fileName) {
            super(fileName);
            mBuffer = buf;
            mFileName = fileName;
        }

        @Override
        public String getFilename() {
            return mFileName;
        }

        @Override
        public String getCharset() {
            return "UTF-8";
        }

        @Override
        public long getContentLength() {
            return mBuffer.length;
        }

        @Override
        public String getTransferEncoding() {
            return "UTF-8";
        }

        @Override
        public void writeTo(final OutputStream out) throws IOException {
            out.write(mBuffer);
        }
    }
}