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 }