Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2012 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package android.bordeaux.services; |
| 18 | |
| 19 | import android.app.Activity; |
| 20 | import android.app.Notification; |
| 21 | import android.app.NotificationManager; |
| 22 | import android.app.PendingIntent; |
| 23 | import android.app.Service; |
| 24 | import android.content.ComponentName; |
| 25 | import android.content.Context; |
| 26 | import android.content.Intent; |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 27 | import android.content.pm.PackageManager; |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 28 | import android.content.ServiceConnection; |
| 29 | import android.os.Bundle; |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 30 | import android.os.Handler; |
| 31 | import android.os.IBinder; |
| 32 | import android.os.Message; |
| 33 | import android.os.Process; |
| 34 | import android.os.RemoteCallbackList; |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 35 | import android.os.RemoteException; |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 36 | import android.view.View; |
| 37 | import android.view.View.OnClickListener; |
| 38 | import android.widget.Button; |
| 39 | import android.widget.TextView; |
| 40 | import android.widget.Toast; |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 41 | |
saberian | 984e52f | 2012-06-05 18:23:53 -0700 | [diff] [blame] | 42 | //import android.bordeaux.R; |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 43 | import android.util.Log; |
| 44 | |
| 45 | import java.io.*; |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 46 | |
| 47 | /** |
| 48 | * Machine Learning service that runs in a remote process. |
| 49 | * The application doesn't use this class directly. |
| 50 | * |
| 51 | */ |
| 52 | public class BordeauxService extends Service { |
| 53 | private final String TAG = "BordeauxService"; |
| 54 | /** |
| 55 | * This is a list of callbacks that have been registered with the |
| 56 | * service. |
| 57 | * It's a place holder for future communications with all registered |
| 58 | * clients. |
| 59 | */ |
| 60 | final RemoteCallbackList<IBordeauxServiceCallback> mCallbacks = |
| 61 | new RemoteCallbackList<IBordeauxServiceCallback>(); |
| 62 | |
| 63 | int mValue = 0; |
| 64 | NotificationManager mNotificationManager; |
| 65 | |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 66 | BordeauxSessionManager mSessionManager; |
saberian | 984e52f | 2012-06-05 18:23:53 -0700 | [diff] [blame] | 67 | AggregatorManager mAggregatorManager; |
| 68 | TimeStatsAggregator mTimeStatsAggregator; |
| 69 | LocationStatsAggregator mLocationStatsAggregator; |
| 70 | MotionStatsAggregator mMotionStatsAggregator; |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 71 | |
| 72 | @Override |
| 73 | public void onCreate() { |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 74 | Log.i(TAG, "Bordeaux service created."); |
saberian | 984e52f | 2012-06-05 18:23:53 -0700 | [diff] [blame] | 75 | //mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 76 | mSessionManager = new BordeauxSessionManager(this); |
saberian | 984e52f | 2012-06-05 18:23:53 -0700 | [diff] [blame] | 77 | mMotionStatsAggregator = new MotionStatsAggregator(); |
Ruei-sung Lin | f0f7844 | 2012-08-13 19:04:29 -0700 | [diff] [blame^] | 78 | mLocationStatsAggregator = new LocationStatsAggregator(this); |
saberian | 984e52f | 2012-06-05 18:23:53 -0700 | [diff] [blame] | 79 | mTimeStatsAggregator = new TimeStatsAggregator(); |
| 80 | mAggregatorManager = AggregatorManager.getInstance(); |
| 81 | mAggregatorManager.registerAggregator(mMotionStatsAggregator, mAggregatorManager); |
| 82 | mAggregatorManager.registerAggregator(mLocationStatsAggregator, mAggregatorManager); |
| 83 | mAggregatorManager.registerAggregator(mTimeStatsAggregator, mAggregatorManager); |
| 84 | //Log.i(TAG, "Bordeaux aggregators were registered"); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 85 | |
| 86 | // Display a notification about us starting. |
| 87 | // TODO: don't display the notification after the service is |
| 88 | // automatically started by the system, currently it's useful for |
| 89 | // debugging. |
| 90 | showNotification(); |
| 91 | } |
| 92 | |
| 93 | @Override |
| 94 | public void onDestroy() { |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 95 | // Save the sessions |
| 96 | mSessionManager.saveSessions(); |
| 97 | |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 98 | // Cancel the persistent notification. |
saberian | 984e52f | 2012-06-05 18:23:53 -0700 | [diff] [blame] | 99 | //mNotificationManager.cancel(R.string.remote_service_started); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 100 | |
| 101 | // Tell the user we stopped. |
saberian | 984e52f | 2012-06-05 18:23:53 -0700 | [diff] [blame] | 102 | //Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show(); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 103 | |
| 104 | // Unregister all callbacks. |
| 105 | mCallbacks.kill(); |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 106 | |
| 107 | Log.i(TAG, "Bordeaux service stopped."); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 108 | } |
| 109 | |
| 110 | @Override |
| 111 | public IBinder onBind(Intent intent) { |
| 112 | // Return the requested interface. |
| 113 | if (IBordeauxService.class.getName().equals(intent.getAction())) { |
| 114 | return mBinder; |
| 115 | } |
| 116 | return null; |
| 117 | } |
| 118 | |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 119 | |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 120 | // The main interface implemented by the service. |
| 121 | private final IBordeauxService.Stub mBinder = new IBordeauxService.Stub() { |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 122 | private IBinder getLearningSession(Class learnerClass, String name) { |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 123 | PackageManager pm = getPackageManager(); |
| 124 | String uidname = pm.getNameForUid(getCallingUid()); |
| 125 | Log.i(TAG,"Name for uid: " + uidname); |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 126 | BordeauxSessionManager.SessionKey key = |
| 127 | mSessionManager.getSessionKey(uidname, learnerClass, name); |
| 128 | Log.i(TAG, "request learning session: " + key.value); |
| 129 | try { |
| 130 | IBinder iLearner = mSessionManager.getSessionBinder(learnerClass, key); |
| 131 | return iLearner; |
| 132 | } catch (RuntimeException e) { |
| 133 | Log.e(TAG, "Error getting learning interface" + e); |
| 134 | return null; |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 135 | } |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 136 | } |
| 137 | |
| 138 | public IBinder getClassifier(String name) { |
| 139 | return getLearningSession(Learning_MulticlassPA.class, name); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | public IBinder getRanker(String name) { |
Wei Hua | 1dd8ef5 | 2012-03-30 15:15:12 -0700 | [diff] [blame] | 143 | return getLearningSession(Learning_StochasticLinearRanker.class, name); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 144 | } |
| 145 | |
saberian | 984e52f | 2012-06-05 18:23:53 -0700 | [diff] [blame] | 146 | public IBinder getPredictor(String name) { |
| 147 | return getLearningSession(Predictor.class, name); |
| 148 | } |
| 149 | |
| 150 | public IBinder getAggregatorManager() { |
| 151 | return (IBinder) mAggregatorManager; |
| 152 | } |
| 153 | |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 154 | public void registerCallback(IBordeauxServiceCallback cb) { |
| 155 | if (cb != null) mCallbacks.register(cb); |
| 156 | } |
| 157 | |
| 158 | public void unregisterCallback(IBordeauxServiceCallback cb) { |
| 159 | if (cb != null) mCallbacks.unregister(cb); |
| 160 | } |
| 161 | }; |
| 162 | |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 163 | @Override |
| 164 | public void onTaskRemoved(Intent rootIntent) { |
| 165 | Toast.makeText(this, "Task removed: " + rootIntent, Toast.LENGTH_LONG).show(); |
| 166 | } |
| 167 | |
| 168 | /** |
| 169 | * Show a notification while this service is running. |
| 170 | * TODO: remove the code after production (when service is loaded |
| 171 | * automatically by the system). |
| 172 | */ |
| 173 | private void showNotification() { |
saberian | 984e52f | 2012-06-05 18:23:53 -0700 | [diff] [blame] | 174 | /*// In this sample, we'll use the same text for the ticker and the expanded notification |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 175 | CharSequence text = getText(R.string.remote_service_started); |
| 176 | |
| 177 | // The PendingIntent to launch our activity if the user selects this notification |
| 178 | PendingIntent contentIntent = |
| 179 | PendingIntent.getActivity(this, 0, |
| 180 | new Intent("android.bordeaux.DEBUG_CONTROLLER"), 0); |
| 181 | |
| 182 | // // Set the info for the views that show in the notification panel. |
| 183 | |
| 184 | Notification.Builder builder = new Notification.Builder(this); |
| 185 | builder.setSmallIcon(R.drawable.ic_bordeaux); |
| 186 | builder.setWhen(System.currentTimeMillis()); |
| 187 | builder.setTicker(text); |
| 188 | builder.setContentTitle(text); |
| 189 | builder.setContentIntent(contentIntent); |
| 190 | Notification notification = builder.getNotification(); |
| 191 | // Send the notification. |
| 192 | // We use a string id because it is a unique number. We use it later to cancel. |
saberian | 984e52f | 2012-06-05 18:23:53 -0700 | [diff] [blame] | 193 | mNotificationManager.notify(R.string.remote_service_started, notification); */ |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 194 | } |
| 195 | |
| 196 | } |