blob: ad4624875d0635e9bf1e68d75ae4cece34ed29d8 [file] [log] [blame]
Wale Ogunwalec4e63a42018-10-02 13:19:54 -07001/*
2 * Copyright (C) 2018 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
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Wale Ogunwalec4e63a42018-10-02 13:19:54 -070018
Wale Ogunwale59507092018-10-29 09:00:30 -070019import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
20import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
Wale Ogunwalec4e63a42018-10-02 13:19:54 -070021
22import java.io.PrintWriter;
23import java.util.HashSet;
24import java.util.Iterator;
25import java.util.function.Consumer;
26
27/**
28 * Class for tracking the connections to services on the AM side that activities on the
29 * WM side (in the future) bind with for things like oom score adjustment. Would normally be one
30 * instance of this per activity for tracking all services connected to that activity. AM will
31 * sometimes query this to bump the OOM score for the processes with services connected to visible
32 * activities.
33 */
34public class ActivityServiceConnectionsHolder<T> {
35
36 private final ActivityTaskManagerService mService;
37
38 /** The activity the owns this service connection object. */
39 private final ActivityRecord mActivity;
40
41 /**
42 * The service connection object bounded with the owning activity. They represent
43 * ConnectionRecord on the AM side, however we don't need to know their object representation
44 * on the WM side since we don't perform operations on the object. Mainly here for communication
45 * and booking with the AM side.
46 */
47 private HashSet<T> mConnections;
48
49 ActivityServiceConnectionsHolder(ActivityTaskManagerService service, ActivityRecord activity) {
50 mService = service;
51 mActivity = activity;
52 }
53
54 /** Adds a connection record that the activity has bound to a specific service. */
55 public void addConnection(T c) {
56 synchronized (mService.mGlobalLock) {
57 if (mConnections == null) {
58 mConnections = new HashSet<>();
59 }
60 mConnections.add(c);
61 }
62 }
63
64 /** Removed a connection record between the activity and a specific service. */
65 public void removeConnection(T c) {
66 synchronized (mService.mGlobalLock) {
67 if (mConnections == null) {
68 return;
69 }
70 mConnections.remove(c);
71 }
72 }
73
74 public boolean isActivityVisible() {
75 synchronized (mService.mGlobalLock) {
76 return mActivity.visible || mActivity.isState(RESUMED, PAUSING);
77 }
78 }
79
80 public int getActivityPid() {
81 synchronized (mService.mGlobalLock) {
82 return mActivity.hasProcess() ? mActivity.app.getPid() : -1;
83 }
84 }
85
86 public void forEachConnection(Consumer<T> consumer) {
87 synchronized (mService.mGlobalLock) {
88 if (mConnections == null || mConnections.isEmpty()) {
89 return;
90 }
91 final Iterator<T> it = mConnections.iterator();
92 while (it.hasNext()) {
93 T c = it.next();
94 consumer.accept(c);
95 }
96 }
97 }
98
99 /** Removes the connection between the activity and all services that were connected to it. */
100 void disconnectActivityFromServices() {
101 if (mConnections == null || mConnections.isEmpty()) {
102 return;
103 }
104 mService.mH.post(() -> mService.mAmInternal.disconnectActivityFromServices(this));
105 }
106
107 public void dump(PrintWriter pw, String prefix) {
108 synchronized (mService.mGlobalLock) {
109 pw.println(prefix + "activity=" + mActivity);
110 }
111 }
112
113}