• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.server.am;
18 
19 import android.content.Context;
20 import android.os.SystemClock;
21 import android.util.Pair;
22 import android.util.Slog;
23 import android.util.SparseArray;
24 
25 /**
26  * While starting activity, WindowManager posts a runnable to DisplayThread to updateOomAdj.
27  * The latency of the thread switch could cause client app failure when the app is checking
28  * {@link ActivityManagerService#isUidActive} before updateOomAdj is done.
29  *
30  * Use PendingStartActivityUids to save uid after WindowManager start activity and before
31  * updateOomAdj is done.
32  *
33  * <p>NOTE: This object is protected by its own lock, NOT the global activity manager lock!
34  */
35 final class PendingStartActivityUids {
36     static final String TAG = ActivityManagerService.TAG;
37 
38     // Key is uid, value is Pair of pid and SystemClock.elapsedRealtime() when the
39     // uid is added.
40     private final SparseArray<Pair<Integer, Long>> mPendingUids = new SparseArray();
41     private Context mContext;
42 
PendingStartActivityUids(Context context)43     PendingStartActivityUids(Context context) {
44         mContext = context;
45     }
46 
add(int uid, int pid)47     synchronized void add(int uid, int pid) {
48         if (mPendingUids.get(uid) == null) {
49             mPendingUids.put(uid, new Pair<>(pid, SystemClock.elapsedRealtime()));
50         }
51     }
52 
delete(int uid)53     synchronized void delete(int uid) {
54         final Pair<Integer, Long> pendingPid = mPendingUids.get(uid);
55         if (pendingPid != null) {
56             final long delay = SystemClock.elapsedRealtime() - pendingPid.second;
57             if (delay >= 1000 /*ms*/) {
58                 Slog.i(TAG,
59                         "PendingStartActivityUids startActivity to updateOomAdj delay:"
60                                 + delay + "ms," + " uid:" + uid);
61             }
62             mPendingUids.delete(uid);
63         }
64     }
65 
isPendingTopPid(int uid, int pid)66     synchronized boolean isPendingTopPid(int uid, int pid) {
67         final Pair<Integer, Long> pendingPid = mPendingUids.get(uid);
68         if (pendingPid != null) {
69             return pendingPid.first == pid;
70         } else {
71             return false;
72         }
73     }
74 
isPendingTopUid(int uid)75     synchronized boolean isPendingTopUid(int uid) {
76         return mPendingUids.get(uid) != null;
77     }
78 }