/* HostKeyEventProfile.java Copyright (c) 2015 NTT DOCOMO,INC. Released under the MIT license http://opensource.org/licenses/mit-license.php */ package org.deviceconnect.android.deviceplugin.host.profile; import android.app.ActivityManager; import android.app.Service; import android.content.Intent; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import org.deviceconnect.android.deviceplugin.host.HostDeviceApplication; import org.deviceconnect.android.deviceplugin.host.HostDeviceService; import org.deviceconnect.android.deviceplugin.host.activity.KeyEventProfileActivity; import org.deviceconnect.android.event.EventError; import org.deviceconnect.android.event.EventManager; import org.deviceconnect.android.message.MessageUtils; import org.deviceconnect.android.profile.KeyEventProfile; import org.deviceconnect.android.profile.api.DConnectApi; import org.deviceconnect.android.profile.api.DeleteApi; import org.deviceconnect.android.profile.api.GetApi; import org.deviceconnect.android.profile.api.PutApi; import org.deviceconnect.message.DConnectMessage; import org.deviceconnect.message.intent.message.IntentDConnectMessage; /** * Key Event Profile. * * @author NTT DOCOMO, INC. */ public class HostKeyEventProfile extends KeyEventProfile { /** Key Event profile event management flag. */ private static int sFlagKeyEventEventManage = 0; /** Key Event profile event flag. (ondown) */ private static final int FLAG_ON_DOWN = 0x0001; /** Key Event profile event flag. (onup) */ private static final int FLAG_ON_UP = 0x0002; /** Key Event profile event flag. (onkeychange) */ private static final int FLAG_ON_KEY_CHANGE = 0x0004; /** Finish key event profile activity action. */ public static final String ACTION_FINISH_KEYEVENT_ACTIVITY = "org.deviceconnect.android.deviceplugin.host.keyevent.FINISH"; /** * Attribute: {@value} . */ public static final String ATTRIBUTE_ON_KEY_CHANGE = "onKeyChange"; private final DConnectApi mGetOnKeyChangeApi = new GetApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_KEY_CHANGE; } @Override public boolean onRequest(final Intent request, final Intent response) { Bundle keyEvent = getApp().getKeyEventCache(ATTRIBUTE_ON_KEY_CHANGE); if (keyEvent == null) { response.putExtra(KeyEventProfile.PARAM_KEYEVENT, ""); } else { response.putExtra(KeyEventProfile.PARAM_KEYEVENT, keyEvent); } setResult(response, IntentDConnectMessage.RESULT_OK); return true; } }; private final DConnectApi mPutOnKeyChangeApi = new PutApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_KEY_CHANGE; } @Override public boolean onRequest(final Intent request, final Intent response) { String serviceId = getServiceID(request); // Event registration. EventError error = EventManager.INSTANCE.addEvent(request); if (error == EventError.NONE) { execKeyEventActivity(serviceId); setKeyEventEventFlag(FLAG_ON_KEY_CHANGE); setResult(response, DConnectMessage.RESULT_OK); } else { MessageUtils.setInvalidRequestParameterError(response, "Can not register event."); } return true; } }; private final DConnectApi mDeleteOnKeyChangeApi = new DeleteApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_KEY_CHANGE; } @Override public boolean onRequest(final Intent request, final Intent response) { // Event release. EventError error = EventManager.INSTANCE.removeEvent(request); if (error == EventError.NONE) { resetKeyEventEventFlag(FLAG_ON_KEY_CHANGE); setResult(response, DConnectMessage.RESULT_OK); } else { MessageUtils.setInvalidRequestParameterError(response, "Can not unregister event."); } return true; } }; private final DConnectApi mGetOnDownApi = new GetApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_DOWN; } @Override public boolean onRequest(final Intent request, final Intent response) { Bundle keyEvent = getApp().getKeyEventCache(KeyEventProfile.ATTRIBUTE_ON_DOWN); if (keyEvent == null) { response.putExtra(KeyEventProfile.PARAM_KEYEVENT, ""); } else { response.putExtra(KeyEventProfile.PARAM_KEYEVENT, keyEvent); } setResult(response, IntentDConnectMessage.RESULT_OK); return true; } }; private final DConnectApi mPutOnDownApi = new PutApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_DOWN; } @Override public boolean onRequest(final Intent request, final Intent response) { String serviceId = getServiceID(request); // Event registration. EventError error = EventManager.INSTANCE.addEvent(request); if (error == EventError.NONE) { execKeyEventActivity(serviceId); setKeyEventEventFlag(FLAG_ON_DOWN); setResult(response, DConnectMessage.RESULT_OK); } else { MessageUtils.setInvalidRequestParameterError(response, "Can not register event."); } return true; } }; private final DConnectApi mDeleteOnDownApi = new DeleteApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_DOWN; } @Override public boolean onRequest(final Intent request, final Intent response) { // Event release. EventError error = EventManager.INSTANCE.removeEvent(request); if (error == EventError.NONE) { resetKeyEventEventFlag(FLAG_ON_DOWN); setResult(response, DConnectMessage.RESULT_OK); } else { MessageUtils.setInvalidRequestParameterError(response, "Can not unregister event."); } return true; } }; private final DConnectApi mGetOnUpApi = new GetApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_UP; } @Override public boolean onRequest(final Intent request, final Intent response) { Bundle keyEvent = getApp().getKeyEventCache(KeyEventProfile.ATTRIBUTE_ON_UP); if (keyEvent == null) { response.putExtra(KeyEventProfile.PARAM_KEYEVENT, ""); } else { response.putExtra(KeyEventProfile.PARAM_KEYEVENT, keyEvent); } setResult(response, IntentDConnectMessage.RESULT_OK); return true; } }; private final DConnectApi mPutOnUpApi = new PutApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_UP; } @Override public boolean onRequest(final Intent request, final Intent response) { String serviceId = getServiceID(request); // Event registration. EventError error = EventManager.INSTANCE.addEvent(request); if (error == EventError.NONE) { execKeyEventActivity(serviceId); setKeyEventEventFlag(FLAG_ON_UP); setResult(response, DConnectMessage.RESULT_OK); } else { MessageUtils.setInvalidRequestParameterError(response, "Can not register event."); } return true; } }; private final DConnectApi mDeleteOnUpApi = new DeleteApi() { @Override public String getAttribute() { return ATTRIBUTE_ON_UP; } @Override public boolean onRequest(final Intent request, final Intent response) { // Event release. EventError error = EventManager.INSTANCE.removeEvent(request); if (error == EventError.NONE) { resetKeyEventEventFlag(FLAG_ON_UP); setResult(response, DConnectMessage.RESULT_OK); } else { MessageUtils.setInvalidRequestParameterError(response, "Can not unregister event."); } return true; } }; public HostKeyEventProfile() { addApi(mGetOnKeyChangeApi); addApi(mPutOnKeyChangeApi); addApi(mDeleteOnKeyChangeApi); addApi(mGetOnDownApi); addApi(mPutOnDownApi); addApi(mDeleteOnDownApi); addApi(mGetOnUpApi); addApi(mPutOnUpApi); addApi(mDeleteOnUpApi); } /** * Execute Key Event Activity. * * @param serviceId service ID. * @return Always true. */ private boolean execKeyEventActivity(final String serviceId) { ActivityManager mActivityManager = (ActivityManager) getContext().getSystemService(Service.ACTIVITY_SERVICE); String mClassName = mActivityManager.getRunningTasks(1).get(0).topActivity.getClassName(); if (!(KeyEventProfileActivity.class.getName().equals(mClassName))) { Intent mIntent = new Intent(); mIntent.setClass(getContext(), KeyEventProfileActivity.class); mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mIntent.putExtra(DConnectMessage.EXTRA_SERVICE_ID, serviceId); this.getContext().startActivity(mIntent); } return true; } /** * Finish Key Event Profile Activity. * * @return Always true. */ private boolean finishKeyEventProfileActivity() { String className = getClassnameOfTopActivity(); if (KeyEventProfileActivity.class.getName().equals(className)) { Intent intent = new Intent(HostKeyEventProfile.ACTION_FINISH_KEYEVENT_ACTIVITY); LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent); } return true; } /** * Set key event event flag. * * @param flag Set flag. */ private void setKeyEventEventFlag(final int flag) { sFlagKeyEventEventManage |= flag; } /** * Reset key event event flag. * * @param flag Reset flag. */ private void resetKeyEventEventFlag(final int flag) { sFlagKeyEventEventManage &= ~(flag); if (sFlagKeyEventEventManage == 0) { finishKeyEventProfileActivity(); } } /** * Get the class name of the Activity being displayed at the top of the screen. * * @return class name. */ private String getClassnameOfTopActivity() { ActivityManager activityMgr = (ActivityManager) getContext().getSystemService(Service.ACTIVITY_SERVICE); return activityMgr.getRunningTasks(1).get(0).topActivity.getClassName(); } /** * Check set KeyEvent event manage flag. * * @return set flag is true, otherwise false. */ private boolean isSetKeyEventManageFlag() { return sFlagKeyEventEventManage != 0; } /** * Reset KeyEvent profile. */ public void resetKeyEventProfile() { if (isSetKeyEventManageFlag()) { resetKeyEventEventFlag(FLAG_ON_DOWN | FLAG_ON_UP | FLAG_ON_KEY_CHANGE); } } private HostDeviceApplication getApp() { return (HostDeviceApplication) ((HostDeviceService) getContext()).getApplication(); } }