| /* |
| * Copyright (C) 2012 The Android Open Source Project |
| * |
| * 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. |
| */ |
| |
| package android.bordeaux.services; |
| |
| import android.app.Activity; |
| import android.app.Notification; |
| import android.app.NotificationManager; |
| import android.app.PendingIntent; |
| import android.app.Service; |
| import android.content.ComponentName; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.pm.PackageManager; |
| import android.content.ServiceConnection; |
| import android.os.Bundle; |
| import android.os.Handler; |
| import android.os.IBinder; |
| import android.os.Message; |
| import android.os.Process; |
| import android.os.RemoteCallbackList; |
| import android.os.RemoteException; |
| import android.view.View; |
| import android.view.View.OnClickListener; |
| import android.widget.Button; |
| import android.widget.TextView; |
| import android.widget.Toast; |
| |
| import android.bordeaux.R; |
| import android.util.Log; |
| |
| import java.io.*; |
| |
| /** |
| * Machine Learning service that runs in a remote process. |
| * The application doesn't use this class directly. |
| * |
| */ |
| public class BordeauxService extends Service { |
| private final String TAG = "BordeauxService"; |
| /** |
| * This is a list of callbacks that have been registered with the |
| * service. |
| * It's a place holder for future communications with all registered |
| * clients. |
| */ |
| final RemoteCallbackList<IBordeauxServiceCallback> mCallbacks = |
| new RemoteCallbackList<IBordeauxServiceCallback>(); |
| |
| int mValue = 0; |
| NotificationManager mNotificationManager; |
| |
| BordeauxSessionManager mSessionManager; |
| AggregatorManager mAggregatorManager; |
| TimeStatsAggregator mTimeStatsAggregator; |
| LocationStatsAggregator mLocationStatsAggregator; |
| MotionStatsAggregator mMotionStatsAggregator; |
| |
| @Override |
| public void onCreate() { |
| Log.i(TAG, "Bordeaux service created."); |
| mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); |
| mSessionManager = new BordeauxSessionManager(this); |
| mMotionStatsAggregator = new MotionStatsAggregator(); |
| mLocationStatsAggregator = new LocationStatsAggregator(); |
| mTimeStatsAggregator = new TimeStatsAggregator(); |
| mAggregatorManager = AggregatorManager.getInstance(); |
| mAggregatorManager.registerAggregator(mMotionStatsAggregator, mAggregatorManager); |
| mAggregatorManager.registerAggregator(mLocationStatsAggregator, mAggregatorManager); |
| mAggregatorManager.registerAggregator(mTimeStatsAggregator, mAggregatorManager); |
| //Log.i(TAG, "Bordeaux aggregators were registered"); |
| |
| // Display a notification about us starting. |
| // TODO: don't display the notification after the service is |
| // automatically started by the system, currently it's useful for |
| // debugging. |
| showNotification(); |
| } |
| |
| @Override |
| public void onDestroy() { |
| // Save the sessions |
| mSessionManager.saveSessions(); |
| |
| // Cancel the persistent notification. |
| mNotificationManager.cancel(R.string.remote_service_started); |
| |
| // Tell the user we stopped. |
| Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show(); |
| |
| // Unregister all callbacks. |
| mCallbacks.kill(); |
| |
| Log.i(TAG, "Bordeaux service stopped."); |
| } |
| |
| @Override |
| public IBinder onBind(Intent intent) { |
| // Return the requested interface. |
| if (IBordeauxService.class.getName().equals(intent.getAction())) { |
| return mBinder; |
| } |
| return null; |
| } |
| |
| |
| // The main interface implemented by the service. |
| private final IBordeauxService.Stub mBinder = new IBordeauxService.Stub() { |
| private IBinder getLearningSession(Class learnerClass, String name) { |
| PackageManager pm = getPackageManager(); |
| String uidname = pm.getNameForUid(getCallingUid()); |
| Log.i(TAG,"Name for uid: " + uidname); |
| BordeauxSessionManager.SessionKey key = |
| mSessionManager.getSessionKey(uidname, learnerClass, name); |
| Log.i(TAG, "request learning session: " + key.value); |
| try { |
| IBinder iLearner = mSessionManager.getSessionBinder(learnerClass, key); |
| return iLearner; |
| } catch (RuntimeException e) { |
| Log.e(TAG, "Error getting learning interface" + e); |
| return null; |
| } |
| } |
| |
| public IBinder getClassifier(String name) { |
| return getLearningSession(Learning_MulticlassPA.class, name); |
| } |
| |
| public IBinder getRanker(String name) { |
| return getLearningSession(Learning_StochasticLinearRanker.class, name); |
| } |
| |
| public IBinder getPredictor(String name) { |
| return getLearningSession(Predictor.class, name); |
| } |
| |
| public IBinder getAggregatorManager() { |
| return (IBinder) mAggregatorManager; |
| } |
| |
| public void registerCallback(IBordeauxServiceCallback cb) { |
| if (cb != null) mCallbacks.register(cb); |
| } |
| |
| public void unregisterCallback(IBordeauxServiceCallback cb) { |
| if (cb != null) mCallbacks.unregister(cb); |
| } |
| }; |
| |
| @Override |
| public void onTaskRemoved(Intent rootIntent) { |
| Toast.makeText(this, "Task removed: " + rootIntent, Toast.LENGTH_LONG).show(); |
| } |
| |
| /** |
| * Show a notification while this service is running. |
| * TODO: remove the code after production (when service is loaded |
| * automatically by the system). |
| */ |
| private void showNotification() { |
| // In this sample, we'll use the same text for the ticker and the expanded notification |
| CharSequence text = getText(R.string.remote_service_started); |
| |
| // The PendingIntent to launch our activity if the user selects this notification |
| PendingIntent contentIntent = |
| PendingIntent.getActivity(this, 0, |
| new Intent("android.bordeaux.DEBUG_CONTROLLER"), 0); |
| |
| // // Set the info for the views that show in the notification panel. |
| |
| Notification.Builder builder = new Notification.Builder(this); |
| builder.setSmallIcon(R.drawable.ic_bordeaux); |
| builder.setWhen(System.currentTimeMillis()); |
| builder.setTicker(text); |
| builder.setContentTitle(text); |
| builder.setContentIntent(contentIntent); |
| Notification notification = builder.getNotification(); |
| // Send the notification. |
| // We use a string id because it is a unique number. We use it later to cancel. |
| mNotificationManager.notify(R.string.remote_service_started, notification); |
| } |
| |
| } |