/*
* Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright (c) 2010 Sony Ericsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
*
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.liato.bankdroid.liveview;
import com.liato.bankdroid.MainActivity;
import com.liato.bankdroid.R;
import com.sonyericsson.extras.liveview.IPluginServiceCallbackV1;
import com.sonyericsson.extras.liveview.IPluginServiceV1;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import timber.log.Timber;
/**
* Implementation of the Live View plug-in service.
*
* @author firetech
*/
public class LiveViewService extends Service {
// Announce intent information keys
public static final String INTENT_EXTRA_ANNOUNCE = "isAnnounce";
public static final String INTENT_EXTRA_TITLE = "title";
public static final String INTENT_EXTRA_TEXT = "text";
// Template menu icon file name.
private static final String MENU_ICON_FILENAME = "plugin_icon.png";
// There should only be one instance of the service
protected static boolean alreadyRunning = false;
// Plugin name
protected String mPluginName = null;
// Current plugin Id
protected int mPluginId = 0;
// Menu icon that will be shown in LiveView unit
protected String mMenuIcon = null;
// Reference to LiveView application stub
private IPluginServiceV1 mLiveView = null;
/**
* The service connection that is used to bind the plugin to the LiveView
* service.
*
* When connected to the service, the plugin is registered. When
* disconnected to the service, the plugin is unregistered.
*/
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(final ComponentName className, IBinder service) {
Timber.d("Enter LiveViewService.ServiceConnection.onServiceConnected.");
mLiveView = IPluginServiceV1.Stub.asInterface(service);
// Init adapter
LiveViewCallback lvCallback = new LiveViewCallback();
// Install plugin
try {
if (mLiveView != null) {
// Register
mPluginId = mLiveView
.register(lvCallback, mMenuIcon, mPluginName, false, getPackageName());
Timber.d("Plugin registered with id: %d", mPluginId);
}
} catch (RemoteException re) {
Timber.e("Failed to install plugin. Stop self.");
stopSelf();
}
Timber.d("Plugin registered. mPluginId: %d", mPluginId);
}
@Override
public void onServiceDisconnected(ComponentName className) {
Timber.d("Enter LiveViewService.ServiceConnection.onServiceDisconnected.");
stopSelf();
}
};
/**
* Check if service is already running.
*
* @return running?
*/
public static boolean isAlreadyRunning() {
return alreadyRunning;
}
public void onCreate() {
super.onCreate();
Timber.d("Enter LiveViewService.onCreate.");
// Load menu icon
int iconId = R.drawable.ic_launcher;
mMenuIcon = PluginUtils.storeIconToFile(this, getResources(), iconId, MENU_ICON_FILENAME);
}
public void onDestroy() {
Timber.d("Enter LiveViewService.onDestroy.");
// Unbind from LiveView service
if (mServiceConnection != null) {
unbindService(mServiceConnection);
}
// No longer a running service
alreadyRunning = false;
super.onDestroy();
}
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Timber.d("Enter LiveViewService.onStart.");
if (intent == null) {
return;
}
if (intent.getBooleanExtra(INTENT_EXTRA_ANNOUNCE, false)) {
Bundle extras = intent.getExtras();
if (extras != null) {
try {
if (mLiveView != null) {
mLiveView.sendAnnounce(mPluginId, mMenuIcon,
extras.getString(INTENT_EXTRA_TITLE),
extras.getString(INTENT_EXTRA_TEXT), System.currentTimeMillis(),
"");
Timber.d("Announce sent to LiveView Application");
} else {
Timber.d("LiveView Application not reachable");
}
} catch (Exception e) {
Timber.e(e, "Failed to send announce");
}
}
} else {
// We end up here when LiveView Application probes the plugin
if (isAlreadyRunning()) {
Timber.d("Already started.");
} else {
// Init
mPluginName = getResources().getString(R.string.app_name);
// Bind to LiveView
connectToLiveView();
// Singleton
alreadyRunning = true;
}
}
}
@Override
public IBinder onBind(final Intent intent) {
Timber.d("Enter LiveViewService.onBind.");
return null;
}
/**
* Connects to the LiveView service.
*/
private void connectToLiveView() {
boolean result = bindService(new Intent(PluginConstants.LIVEVIEW_SERVICE_BIND_INTENT),
mServiceConnection, 0);
if (result) {
Timber.d("Bound to LiveView.");
} else {
Timber.d("No bind.");
stopSelf();
}
}
/**
* When a user presses the "open in phone" button on the LiveView device, this method is
* called.
*
* Opens the MainActivity on the phone.
*/
protected void openInPhone(String openInPhoneAction) {
Timber.d("openInPhone");
Intent i = new Intent(this, MainActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
/**
* LiveView callback interface method.
*/
private class LiveViewCallback extends IPluginServiceCallbackV1.Stub {
Handler mCallbackHandler = new Handler();
public String getPluginName() throws RemoteException {
return mPluginName;
}
public void openInPhone(final String openInPhoneAction) throws RemoteException {
mCallbackHandler.post(new Runnable() {
public void run() {
LiveViewService.this.openInPhone(openInPhoneAction);
}
});
}
//Unused methods required by API.
public void startPlugin() throws RemoteException {
}
public void stopPlugin() throws RemoteException {
}
public void onUnregistered() throws RemoteException {
}
public void displayCaps(int displayWidthPixels, int displayHeigthPixels)
throws RemoteException {
}
public void button(String buttonType, boolean doublepress,
boolean longpress) throws RemoteException {
}
public void screenMode(int screenMode) throws RemoteException {
}
}
}