1*90c8c64dSAndroid Build Coastguard Worker /*
2*90c8c64dSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*90c8c64dSAndroid Build Coastguard Worker  *
4*90c8c64dSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*90c8c64dSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*90c8c64dSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*90c8c64dSAndroid Build Coastguard Worker  *
8*90c8c64dSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*90c8c64dSAndroid Build Coastguard Worker  *
10*90c8c64dSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*90c8c64dSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*90c8c64dSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*90c8c64dSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*90c8c64dSAndroid Build Coastguard Worker  * limitations under the License.
15*90c8c64dSAndroid Build Coastguard Worker  */
16*90c8c64dSAndroid Build Coastguard Worker 
17*90c8c64dSAndroid Build Coastguard Worker package com.example.android.wearable.elizachat;
18*90c8c64dSAndroid Build Coastguard Worker 
19*90c8c64dSAndroid Build Coastguard Worker import android.app.Notification;
20*90c8c64dSAndroid Build Coastguard Worker import android.app.PendingIntent;
21*90c8c64dSAndroid Build Coastguard Worker import android.app.Service;
22*90c8c64dSAndroid Build Coastguard Worker import android.content.Intent;
23*90c8c64dSAndroid Build Coastguard Worker import android.graphics.BitmapFactory;
24*90c8c64dSAndroid Build Coastguard Worker import android.os.Bundle;
25*90c8c64dSAndroid Build Coastguard Worker import android.os.IBinder;
26*90c8c64dSAndroid Build Coastguard Worker import android.support.v4.app.NotificationCompat;
27*90c8c64dSAndroid Build Coastguard Worker import android.support.v4.app.RemoteInput;
28*90c8c64dSAndroid Build Coastguard Worker import android.support.v4.content.LocalBroadcastManager;
29*90c8c64dSAndroid Build Coastguard Worker import android.support.v4.app.NotificationManagerCompat;
30*90c8c64dSAndroid Build Coastguard Worker import android.text.TextUtils;
31*90c8c64dSAndroid Build Coastguard Worker import android.util.Log;
32*90c8c64dSAndroid Build Coastguard Worker 
33*90c8c64dSAndroid Build Coastguard Worker /**
34*90c8c64dSAndroid Build Coastguard Worker  * A service that runs in the background and provides responses to the incoming messages from the
35*90c8c64dSAndroid Build Coastguard Worker  * wearable. It also keeps a record of the chat session history, which it can provide upon request.
36*90c8c64dSAndroid Build Coastguard Worker  */
37*90c8c64dSAndroid Build Coastguard Worker public class ResponderService extends Service {
38*90c8c64dSAndroid Build Coastguard Worker 
39*90c8c64dSAndroid Build Coastguard Worker     public static final String ACTION_INCOMING = "com.example.android.wearable.elizachat.INCOMING";
40*90c8c64dSAndroid Build Coastguard Worker 
41*90c8c64dSAndroid Build Coastguard Worker     public static final String ACTION_RESPONSE = "com.example.android.wearable.elizachat.REPLY";
42*90c8c64dSAndroid Build Coastguard Worker 
43*90c8c64dSAndroid Build Coastguard Worker     public static final String EXTRA_REPLY = "reply";
44*90c8c64dSAndroid Build Coastguard Worker 
45*90c8c64dSAndroid Build Coastguard Worker     private static final String TAG = "ResponderService";
46*90c8c64dSAndroid Build Coastguard Worker 
47*90c8c64dSAndroid Build Coastguard Worker     private ElizaResponder mResponder;
48*90c8c64dSAndroid Build Coastguard Worker 
49*90c8c64dSAndroid Build Coastguard Worker     private String mLastResponse = null;
50*90c8c64dSAndroid Build Coastguard Worker 
51*90c8c64dSAndroid Build Coastguard Worker     private StringBuffer mCompleteConversation = new StringBuffer();
52*90c8c64dSAndroid Build Coastguard Worker 
53*90c8c64dSAndroid Build Coastguard Worker     private LocalBroadcastManager mBroadcastManager;
54*90c8c64dSAndroid Build Coastguard Worker 
55*90c8c64dSAndroid Build Coastguard Worker     @Override
onCreate()56*90c8c64dSAndroid Build Coastguard Worker     public void onCreate() {
57*90c8c64dSAndroid Build Coastguard Worker         super.onCreate();
58*90c8c64dSAndroid Build Coastguard Worker         if (Log.isLoggable(TAG, Log.DEBUG)) {
59*90c8c64dSAndroid Build Coastguard Worker             Log.d(TAG, "Chat Service started");
60*90c8c64dSAndroid Build Coastguard Worker         }
61*90c8c64dSAndroid Build Coastguard Worker         mResponder = new ElizaResponder();
62*90c8c64dSAndroid Build Coastguard Worker         mBroadcastManager = LocalBroadcastManager.getInstance(this);
63*90c8c64dSAndroid Build Coastguard Worker         processIncoming(null);
64*90c8c64dSAndroid Build Coastguard Worker     }
65*90c8c64dSAndroid Build Coastguard Worker 
66*90c8c64dSAndroid Build Coastguard Worker     @Override
onBind(Intent intent)67*90c8c64dSAndroid Build Coastguard Worker     public IBinder onBind(Intent intent) {
68*90c8c64dSAndroid Build Coastguard Worker         return null;
69*90c8c64dSAndroid Build Coastguard Worker     }
70*90c8c64dSAndroid Build Coastguard Worker 
71*90c8c64dSAndroid Build Coastguard Worker     @Override
onStartCommand(Intent intent, int flags, int startId)72*90c8c64dSAndroid Build Coastguard Worker     public int onStartCommand(Intent intent, int flags, int startId) {
73*90c8c64dSAndroid Build Coastguard Worker         if (null == intent || null == intent.getAction()) {
74*90c8c64dSAndroid Build Coastguard Worker             return Service.START_STICKY;
75*90c8c64dSAndroid Build Coastguard Worker         }
76*90c8c64dSAndroid Build Coastguard Worker         String action = intent.getAction();
77*90c8c64dSAndroid Build Coastguard Worker         if (action.equals(ACTION_RESPONSE)) {
78*90c8c64dSAndroid Build Coastguard Worker             Bundle remoteInputResults = RemoteInput.getResultsFromIntent(intent);
79*90c8c64dSAndroid Build Coastguard Worker             CharSequence replyMessage = "";
80*90c8c64dSAndroid Build Coastguard Worker             if (remoteInputResults != null) {
81*90c8c64dSAndroid Build Coastguard Worker                 replyMessage = remoteInputResults.getCharSequence(EXTRA_REPLY);
82*90c8c64dSAndroid Build Coastguard Worker             }
83*90c8c64dSAndroid Build Coastguard Worker             processIncoming(replyMessage.toString());
84*90c8c64dSAndroid Build Coastguard Worker         } else if (action.equals(MainActivity.ACTION_GET_CONVERSATION)) {
85*90c8c64dSAndroid Build Coastguard Worker             broadcastMessage(mCompleteConversation.toString());
86*90c8c64dSAndroid Build Coastguard Worker         }
87*90c8c64dSAndroid Build Coastguard Worker         return Service.START_STICKY;
88*90c8c64dSAndroid Build Coastguard Worker     }
89*90c8c64dSAndroid Build Coastguard Worker 
showNotification()90*90c8c64dSAndroid Build Coastguard Worker     private void showNotification() {
91*90c8c64dSAndroid Build Coastguard Worker         if (Log.isLoggable(TAG, Log.DEBUG)) {
92*90c8c64dSAndroid Build Coastguard Worker             Log.d(TAG, "Sent: " + mLastResponse);
93*90c8c64dSAndroid Build Coastguard Worker         }
94*90c8c64dSAndroid Build Coastguard Worker         NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
95*90c8c64dSAndroid Build Coastguard Worker                 .setContentTitle(getString(R.string.eliza))
96*90c8c64dSAndroid Build Coastguard Worker                 .setContentText(mLastResponse)
97*90c8c64dSAndroid Build Coastguard Worker                 .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.bg_eliza))
98*90c8c64dSAndroid Build Coastguard Worker                 .setSmallIcon(R.drawable.bg_eliza)
99*90c8c64dSAndroid Build Coastguard Worker                 .setPriority(NotificationCompat.PRIORITY_DEFAULT);
100*90c8c64dSAndroid Build Coastguard Worker 
101*90c8c64dSAndroid Build Coastguard Worker         Intent intent = new Intent(ACTION_RESPONSE);
102*90c8c64dSAndroid Build Coastguard Worker         PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent,
103*90c8c64dSAndroid Build Coastguard Worker                 PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT);
104*90c8c64dSAndroid Build Coastguard Worker         Notification notification = builder
105*90c8c64dSAndroid Build Coastguard Worker                 .extend(new NotificationCompat.WearableExtender()
106*90c8c64dSAndroid Build Coastguard Worker                         .addAction(new NotificationCompat.Action.Builder(
107*90c8c64dSAndroid Build Coastguard Worker                                 R.drawable.ic_full_reply, getString(R.string.reply), pendingIntent)
108*90c8c64dSAndroid Build Coastguard Worker                                 .addRemoteInput(new RemoteInput.Builder(EXTRA_REPLY)
109*90c8c64dSAndroid Build Coastguard Worker                                         .setLabel(getString(R.string.reply))
110*90c8c64dSAndroid Build Coastguard Worker                                         .build())
111*90c8c64dSAndroid Build Coastguard Worker                                 .build()))
112*90c8c64dSAndroid Build Coastguard Worker                 .build();
113*90c8c64dSAndroid Build Coastguard Worker         NotificationManagerCompat.from(this).notify(0, notification);
114*90c8c64dSAndroid Build Coastguard Worker     }
115*90c8c64dSAndroid Build Coastguard Worker 
processIncoming(String text)116*90c8c64dSAndroid Build Coastguard Worker     private void processIncoming(String text) {
117*90c8c64dSAndroid Build Coastguard Worker         if (Log.isLoggable(TAG, Log.DEBUG)) {
118*90c8c64dSAndroid Build Coastguard Worker             Log.d(TAG, "Received: " + text);
119*90c8c64dSAndroid Build Coastguard Worker         }
120*90c8c64dSAndroid Build Coastguard Worker         mLastResponse = mResponder.elzTalk(text);
121*90c8c64dSAndroid Build Coastguard Worker         String line = TextUtils.isEmpty(text) ? mLastResponse : text + "\n" + mLastResponse;
122*90c8c64dSAndroid Build Coastguard Worker 
123*90c8c64dSAndroid Build Coastguard Worker         // Send a new line of conversation to update the Activity, unless the incoming text was
124*90c8c64dSAndroid Build Coastguard Worker         // empty.
125*90c8c64dSAndroid Build Coastguard Worker         if (!TextUtils.isEmpty(text)) {
126*90c8c64dSAndroid Build Coastguard Worker             broadcastMessage(line);
127*90c8c64dSAndroid Build Coastguard Worker         }
128*90c8c64dSAndroid Build Coastguard Worker         NotificationManagerCompat.from(this).cancelAll();
129*90c8c64dSAndroid Build Coastguard Worker         showNotification();
130*90c8c64dSAndroid Build Coastguard Worker         mCompleteConversation.append("\n" + line);
131*90c8c64dSAndroid Build Coastguard Worker     }
132*90c8c64dSAndroid Build Coastguard Worker 
broadcastMessage(String message)133*90c8c64dSAndroid Build Coastguard Worker     private void broadcastMessage(String message) {
134*90c8c64dSAndroid Build Coastguard Worker         Intent intent = new Intent(MainActivity.ACTION_NOTIFY);
135*90c8c64dSAndroid Build Coastguard Worker         intent.putExtra(MainActivity.EXTRA_MESSAGE, message);
136*90c8c64dSAndroid Build Coastguard Worker         mBroadcastManager.sendBroadcast(intent);
137*90c8c64dSAndroid Build Coastguard Worker     }
138*90c8c64dSAndroid Build Coastguard Worker 
139*90c8c64dSAndroid Build Coastguard Worker     @Override
onDestroy()140*90c8c64dSAndroid Build Coastguard Worker     public void onDestroy() {
141*90c8c64dSAndroid Build Coastguard Worker         if (Log.isLoggable(TAG, Log.DEBUG)) {
142*90c8c64dSAndroid Build Coastguard Worker             Log.d(TAG, "Chat Service stopped");
143*90c8c64dSAndroid Build Coastguard Worker         }
144*90c8c64dSAndroid Build Coastguard Worker         NotificationManagerCompat.from(this).cancel(0);
145*90c8c64dSAndroid Build Coastguard Worker         mBroadcastManager = null;
146*90c8c64dSAndroid Build Coastguard Worker         super.onDestroy();
147*90c8c64dSAndroid Build Coastguard Worker     }
148*90c8c64dSAndroid Build Coastguard Worker }
149