blob: 4194701327f0038c45dd2f6d0f44743b91f41bf9 [file] [log] [blame]
Matthew Ng13dbf872017-10-27 11:02:14 -07001/*
2 * Copyright (C) 2017 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 com.android.systemui;
18
19import android.content.ComponentName;
20import android.content.Context;
21import android.content.Intent;
22import android.content.ServiceConnection;
23import android.os.Handler;
24import android.os.IBinder;
25import android.os.RemoteException;
26import android.os.UserHandle;
27import android.util.Log;
28import com.android.systemui.shared.recents.model.IOverviewProxy;
29import com.android.systemui.statusbar.policy.DeviceProvisionedController;
30import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
31
32/**
33 * Class to send information from overview to launcher with a binder.
34 */
35public class OverviewProxyService {
36
37 private static final String TAG = "OverviewProxyService";
38 private static final long BACKOFF_MILLIS = 5000;
39
40 private final Context mContext;
41 private final Handler mHandler;
42 private final Runnable mConnectionRunnable = this::startConnectionToCurrentUser;
43 private final DeviceProvisionedController mDeviceProvisionedController
44 = Dependency.get(DeviceProvisionedController.class);
45
46 private IOverviewProxy mOverviewProxy;
47 private int mConnectionBackoffAttempts;
48
49 private final ServiceConnection mOverviewServiceConnection = new ServiceConnection() {
50 @Override
51 public void onServiceConnected(ComponentName name, IBinder service) {
52 if (service != null) {
53 mConnectionBackoffAttempts = 0;
54 mOverviewProxy = IOverviewProxy.Stub.asInterface(service);
55 // Listen for launcher's death
56 try {
57 service.linkToDeath(mOverviewServiceDeathRcpt, 0);
58 } catch (RemoteException e) {
59 Log.e(TAG, "Lost connection to launcher service", e);
60 }
61 }
62 }
63
64 @Override
65 public void onServiceDisconnected(ComponentName name) {
66 // Do nothing
67 }
68 };
69
70 private final DeviceProvisionedListener mDeviceProvisionedCallback =
71 new DeviceProvisionedListener() {
72 @Override
73 public void onDeviceProvisionedChanged() {
74 if (mDeviceProvisionedController.isCurrentUserSetup()) {
75 startConnectionToCurrentUser();
76 }
77 }
78
79 @Override
80 public void onUserSwitched() {
Matthew Ng13dbf872017-10-27 11:02:14 -070081 mConnectionBackoffAttempts = 0;
82 startConnectionToCurrentUser();
83 }
84 };
85
86 // This is the death handler for the binder from the launcher service
87 private final IBinder.DeathRecipient mOverviewServiceDeathRcpt = new IBinder.DeathRecipient() {
88 @Override
89 public void binderDied() {
90 mOverviewProxy = null;
91 }
92 };
93
94 public OverviewProxyService(Context context) {
95 mContext = context;
96 mHandler = new Handler();
97 mConnectionBackoffAttempts = 0;
98 mDeviceProvisionedController.addCallback(mDeviceProvisionedCallback);
99 }
100
101 public void startConnectionToCurrentUser() {
Matthew Ng1fa3f7e2017-11-07 11:50:36 -0800102 disconnectFromLauncherService();
103
Matthew Ng13dbf872017-10-27 11:02:14 -0700104 // If user has not setup yet or already connected, do not try to connect
Matthew Ng1fa3f7e2017-11-07 11:50:36 -0800105 if (!mDeviceProvisionedController.isCurrentUserSetup()) {
Matthew Ng13dbf872017-10-27 11:02:14 -0700106 return;
107 }
108 mHandler.removeCallbacks(mConnectionRunnable);
109 Intent launcherServiceIntent = new Intent();
110 launcherServiceIntent.setComponent(ComponentName.unflattenFromString(
111 mContext.getString(R.string.config_overviewServiceComponent)));
112 boolean bound = mContext.bindServiceAsUser(launcherServiceIntent,
113 mOverviewServiceConnection, Context.BIND_AUTO_CREATE,
114 UserHandle.getUserHandleForUid(mDeviceProvisionedController.getCurrentUser()));
115 if (!bound) {
116 // Retry after exponential backoff timeout
117 final long timeoutMs = (long) Math.scalb(BACKOFF_MILLIS, mConnectionBackoffAttempts);
118 mHandler.postDelayed(mConnectionRunnable, timeoutMs);
119 mConnectionBackoffAttempts++;
120 }
121 }
122
123 public IOverviewProxy getProxy() {
124 return mOverviewProxy;
125 }
126
127 private void disconnectFromLauncherService() {
Matthew Ng1fa3f7e2017-11-07 11:50:36 -0800128 if (mOverviewProxy != null) {
129 mContext.unbindService(mOverviewServiceConnection);
130 mOverviewProxy = null;
131 }
Matthew Ng13dbf872017-10-27 11:02:14 -0700132 }
133}