BordeauxService.java revision 7b5b77b038b846e8e2d3aaf0d94c206723a83ccf
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
17package android.bordeaux.services;
18
19import android.app.Activity;
20import android.app.Notification;
21import android.app.NotificationManager;
22import android.app.PendingIntent;
23import android.app.Service;
24import android.content.ComponentName;
25import android.content.Context;
26import android.content.Intent;
27import android.content.pm.PackageManager;
28import android.content.ServiceConnection;
29import android.os.Bundle;
30import android.os.Handler;
31import android.os.IBinder;
32import android.os.Message;
33import android.os.Process;
34import android.os.RemoteCallbackList;
35import android.os.RemoteException;
36import android.view.View;
37import android.view.View.OnClickListener;
38import android.widget.Button;
39import android.widget.TextView;
40import android.widget.Toast;
41
42import android.bordeaux.R;
43import android.util.Log;
44
45import java.io.*;
46
47/**
48 * Machine Learning service that runs in a remote process.
49 * The application doesn't use this class directly.
50 *
51 */
52public 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
66    BordeauxSessionManager mSessionManager;
67    AggregatorManager mAggregatorManager;
68    TimeStatsAggregator mTimeStatsAggregator;
69    LocationStatsAggregator mLocationStatsAggregator;
70    MotionStatsAggregator mMotionStatsAggregator;
71
72    @Override
73    public void onCreate() {
74        Log.i(TAG, "Bordeaux service created.");
75        mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
76        mSessionManager = new BordeauxSessionManager(this);
77        mMotionStatsAggregator = new MotionStatsAggregator();
78        mLocationStatsAggregator = new LocationStatsAggregator();
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");
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() {
95        // Save the sessions
96        mSessionManager.saveSessions();
97
98        // Cancel the persistent notification.
99        mNotificationManager.cancel(R.string.remote_service_started);
100
101        // Tell the user we stopped.
102        Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show();
103
104        // Unregister all callbacks.
105        mCallbacks.kill();
106
107        Log.i(TAG, "Bordeaux service stopped.");
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
119
120    // The main interface implemented by the service.
121    private final IBordeauxService.Stub mBinder = new IBordeauxService.Stub() {
122        private IBinder getLearningSession(Class learnerClass, String name) {
123            PackageManager pm = getPackageManager();
124            String uidname = pm.getNameForUid(getCallingUid());
125            Log.i(TAG,"Name for uid: " + uidname);
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;
135            }
136        }
137
138        public IBinder getClassifier(String name) {
139            return getLearningSession(Learning_MulticlassPA.class, name);
140        }
141
142        public IBinder getRanker(String name) {
143            return getLearningSession(Learning_StochasticLinearRanker.class, name);
144        }
145
146        public IBinder getPredictor(String name) {
147            return getLearningSession(Predictor.class, name);
148        }
149
150        public IBinder getAggregatorManager() {
151            return (IBinder) mAggregatorManager;
152        }
153
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
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() {
174        // In this sample, we'll use the same text for the ticker and the expanded notification
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.
193        mNotificationManager.notify(R.string.remote_service_started, notification);
194    }
195
196}
197