1b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka/*
2b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * Copyright (C) 2017 The Android Open Source Project
3b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka *
4b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * Licensed under the Apache License, Version 2.0 (the "License");
5b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * you may not use this file except in compliance with the License.
6b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * You may obtain a copy of the License at
7b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka *
8b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka *      http://www.apache.org/licenses/LICENSE-2.0
9b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka *
10b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * Unless required by applicable law or agreed to in writing, software
11b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * distributed under the License is distributed on an "AS IS" BASIS,
12b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * See the License for the specific language governing permissions and
14b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka * limitations under the License.
15b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka */
16b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankapackage com.android.coretests.apps.bstatstestapp;
17b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
18b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.R;
19b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.app.Notification;
20b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.app.NotificationChannel;
21b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.app.NotificationManager;
22b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.app.Service;
23b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.content.Intent;
24b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.graphics.Color;
25b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.graphics.Point;
26b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.os.Handler;
27b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.os.IBinder;
28b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.os.Process;
29b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.os.RemoteException;
30b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.util.Log;
31b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.view.Gravity;
32b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.view.View;
33b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.view.ViewGroup;
34b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport android.view.WindowManager;
35b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
36b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport java.util.concurrent.CountDownLatch;
37b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankaimport java.util.concurrent.TimeUnit;
38b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
39b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shankapublic class TestService extends Service {
40b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    private static final String TAG = TestService.class.getSimpleName();
41b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
42b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    private static final int FLAG_START_FOREGROUND = 1;
43b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
44b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    private static final String NOTIFICATION_CHANNEL_ID = TAG;
45b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    private static final int NOTIFICATION_ID = 42;
46b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
47b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    private static final int TIMEOUT_OVERLAY_SEC = 2;
48b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
49b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    private View mOverlay;
50b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
51b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    @Override
52b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    public void onCreate() {
53b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        Log.d(TAG, "onCreate called. myUid=" + Process.myUid());
54b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    }
55b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
56b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    @Override
57b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    public int onStartCommand(Intent intent, int flags, int startId) {
58b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        Log.d(TAG, "onStartCommand called. myUid=" + Process.myUid());
59b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        if (intent != null && (intent.getFlags() & FLAG_START_FOREGROUND) != 0) {
60b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            startForeground();
61b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        }
62b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        notifyServiceLaunched(intent);
63b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        return START_STICKY;
64b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    }
65b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
66b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    @Override
67b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    public IBinder onBind(Intent intent) {
68b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        Log.d(TAG, "onBind called. myUid=" + Process.myUid());
69b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        return null;
70b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    }
71b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
72b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    @Override
73b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    public void onDestroy() {
74b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        Log.d(TAG, "onDestroy called. myUid=" + Process.myUid());
75b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        removeOverlays();
76b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    }
77b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
78b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    private void notifyServiceLaunched(Intent intent) {
79b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        Common.notifyLaunched(intent, mReceiver.asBinder(), TAG);
80b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    }
81b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
82b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    private void startForeground() {
83b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        final NotificationManager noMan = getSystemService(NotificationManager.class);
84b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        noMan.createNotificationChannel(new NotificationChannel(
85b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_ID,
86b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                NotificationManager.IMPORTANCE_DEFAULT));
87b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        Log.d(TAG, "Starting foreground. myUid=" + Process.myUid());
88b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        startForeground(NOTIFICATION_ID,
89b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
90b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                        .setSmallIcon(R.drawable.ic_dialog_alert)
91b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                        .build());
92b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    }
93b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
94b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    private void removeOverlays() {
95b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        if (mOverlay != null) {
96b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            final WindowManager wm = TestService.this.getSystemService(WindowManager.class);
97b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            wm.removeView(mOverlay);
98b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            mOverlay = null;
99b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        }
100b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    }
101b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
102b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    private BaseCmdReceiver mReceiver = new BaseCmdReceiver() {
103b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        @Override
104b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        public void doSomeWork(int durationMs) {
105b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            Common.doSomeWork(durationMs);
106b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        }
107b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
108b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        @Override
109b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        public void showApplicationOverlay() throws RemoteException {
110b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            final WindowManager wm = TestService.this.getSystemService(WindowManager.class);
111b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            final Point size = new Point();
112b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            wm.getDefaultDisplay().getSize(size);
113b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
114b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            final WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(
115b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
116b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
117b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                            | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
118b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                            | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
119b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            wmlp.width = size.x / 2;
120b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            wmlp.height = size.y / 2;
121b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            wmlp.gravity = Gravity.CENTER | Gravity.LEFT;
122b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            wmlp.setTitle(TAG);
123b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
124b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            final ViewGroup.LayoutParams vglp = new ViewGroup.LayoutParams(
125b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                    ViewGroup.LayoutParams.MATCH_PARENT,
126b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                    ViewGroup.LayoutParams.MATCH_PARENT);
127b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
128b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            mOverlay = new View(TestService.this);
129b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            mOverlay.setBackgroundColor(Color.GREEN);
130b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            mOverlay.setLayoutParams(vglp);
131b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
132b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            final CountDownLatch latch = new CountDownLatch(1);
133b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            final Handler handler = new Handler(TestService.this.getMainLooper());
134b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            handler.post(() -> {
135b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                wm.addView(mOverlay, wmlp);
136b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                latch.countDown();
137b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            });
138b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            try {
139b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                if (!latch.await(TIMEOUT_OVERLAY_SEC, TimeUnit.SECONDS)) {
140b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                    throw new RemoteException("Timed out waiting for the overlay");
141b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                }
142b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            } catch (InterruptedException e) {
143b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka                throw new RemoteException("Error while adding overlay: " + e.toString());
144b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            }
145b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            Log.d(TAG, "Overlay displayed, myUid=" + Process.myUid());
146b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        }
147b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka
148b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        @Override
149b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        public void finishHost() {
150b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            removeOverlays();
151b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka            stopSelf();
152b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka        }
153b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka    };
154b2f83c16d6669456b237970327ebb9c92a4789f0Sudheer Shanka}
155