• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 com.android.traceur;
18 
19 import com.google.android.collect.Sets;
20 
21 import android.app.IntentService;
22 import android.app.Notification;
23 import android.app.NotificationManager;
24 import android.app.PendingIntent;
25 import android.app.Service;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.preference.PreferenceManager;
29 
30 import java.io.File;
31 
32 public class AtraceService extends IntentService {
33 
34     private static String INTENT_ACTION_START_TRACING = "com.android.traceur.START_TRACING";
35     private static String INTENT_ACTION_STOP_TRACING = "com.android.traceur.STOP_TRACING";
36 
37     private static String INTENT_EXTRA_FILENAME = "filename";
38     private static String INTENT_EXTRA_TAGS= "tags";
39     private static String INTENT_EXTRA_BUFFER = "buffer";
40     private static String INTENT_EXTRA_APPS = "apps";
41 
42     private static int TRACE_NOTIFICATION = 1;
43     private static int SAVING_TRACE_NOTIFICATION = 2;
44 
startTracing(final Context context, String tags, int bufferSizeKb, boolean apps)45     public static void startTracing(final Context context,
46             String tags, int bufferSizeKb, boolean apps) {
47         Intent intent = new Intent(context, AtraceService.class);
48         intent.setAction(INTENT_ACTION_START_TRACING);
49         intent.putExtra(INTENT_EXTRA_TAGS, tags);
50         intent.putExtra(INTENT_EXTRA_BUFFER, bufferSizeKb);
51         intent.putExtra(INTENT_EXTRA_APPS, apps);
52         context.startService(intent);
53     }
54 
stopTracing(final Context context)55     public static void stopTracing(final Context context) {
56         Intent intent = new Intent(context, AtraceService.class);
57         intent.setAction(INTENT_ACTION_STOP_TRACING);
58         intent.putExtra(INTENT_EXTRA_FILENAME, AtraceUtils.getOutputFilename());
59         context.startService(intent);
60     }
61 
AtraceService()62     public AtraceService() {
63         super("AtraceService");
64         setIntentRedelivery(true);
65     }
66 
67     @Override
onHandleIntent(Intent intent)68     public void onHandleIntent(Intent intent) {
69         if (intent.getAction().equals(INTENT_ACTION_START_TRACING)) {
70             startTracingInternal(intent.getStringExtra(INTENT_EXTRA_TAGS),
71                 intent.getIntExtra(INTENT_EXTRA_BUFFER,
72                     Integer.parseInt(getApplicationContext()
73                         .getString(R.string.default_buffer_size))),
74                 intent.getBooleanExtra(INTENT_EXTRA_APPS, false));
75         } else if (intent.getAction().equals(INTENT_ACTION_STOP_TRACING)) {
76             stopTracingInternal(intent.getStringExtra(INTENT_EXTRA_FILENAME));
77         }
78     }
79 
startTracingInternal(String tags, int bufferSizeKb, boolean appTracing)80     private void startTracingInternal(String tags, int bufferSizeKb, boolean appTracing) {
81         Context context = getApplicationContext();
82         Intent stopIntent = new Intent(Receiver.STOP_ACTION,
83             null, context, Receiver.class);
84 
85         String title = context.getString(R.string.trace_is_being_recorded);
86         String msg = context.getString(R.string.tap_to_stop_tracing);
87 
88         Notification notification =
89             new Notification.Builder(context, Receiver.NOTIFICATION_CHANNEL)
90                 .setSmallIcon(R.drawable.stat_sys_adb)
91                 .setContentTitle(title)
92                 .setTicker(title)
93                 .setContentText(msg)
94                 .setContentIntent(
95                     PendingIntent.getBroadcast(context, 0, stopIntent, 0))
96                 .setOngoing(true)
97                 .setLocalOnly(true)
98                 .setColor(getColor(
99                     com.android.internal.R.color.system_notification_accent_color))
100                 .build();
101 
102         startForeground(TRACE_NOTIFICATION, notification);
103 
104         if (AtraceUtils.atraceStart(tags, bufferSizeKb, appTracing)) {
105             stopForeground(Service.STOP_FOREGROUND_DETACH);
106         } else {
107             // Starting the trace was unsuccessful, so ensure that tracing
108             // is stopped and the preference is reset.
109             AtraceUtils.atraceStop();
110             PreferenceManager.getDefaultSharedPreferences(context)
111                 .edit().putBoolean(context.getString(R.string.pref_key_tracing_on),
112                         false).apply();
113             QsService.updateTile();
114             stopForeground(Service.STOP_FOREGROUND_REMOVE);
115         }
116     }
117 
stopTracingInternal(String outputFilename)118     private void stopTracingInternal(String outputFilename) {
119         NotificationManager notificationManager =
120             getSystemService(NotificationManager.class);
121 
122         Notification notification =
123             new Notification.Builder(this, Receiver.NOTIFICATION_CHANNEL)
124                 .setSmallIcon(R.drawable.stat_sys_adb)
125                 .setContentTitle(getString(R.string.saving_trace))
126                 .setTicker(getString(R.string.saving_trace))
127                 .setLocalOnly(true)
128                 .setProgress(1, 0, true)
129                 .setColor(getColor(
130                     com.android.internal.R.color.system_notification_accent_color))
131                 .build();
132 
133         startForeground(SAVING_TRACE_NOTIFICATION, notification);
134 
135         notificationManager.cancel(TRACE_NOTIFICATION);
136 
137         File file = AtraceUtils.getOutputFile(outputFilename);
138 
139         if (AtraceUtils.atraceDump(file)) {
140             FileSender.postNotification(getApplicationContext(), file);
141         }
142 
143         stopForeground(Service.STOP_FOREGROUND_REMOVE);
144     }
145 }
146