blob: c41e0aaca3d229a710024e2970d27c042c4623ef [file] [log] [blame]
David Chende701692017-10-05 13:16:02 -07001/*
yro0feae942017-11-15 14:38:48 -08002 * Copyright (C) 2017 The Android Open Source Project
David Chende701692017-10-05 13:16:02 -07003 *
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
Yangster9df9a7f2017-12-18 13:33:05 -080017#pragma once
David Chende701692017-10-05 13:16:02 -070018
David Chend6896892017-10-25 11:49:03 -070019#include "config/ConfigKey.h"
20#include "config/ConfigListener.h"
Yao Chen9c1debe2018-02-19 14:39:19 -080021#include "frameworks/base/cmds/statsd/src/stats_log_common.pb.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070022#include "packages/PackageInfoListener.h"
David Chende701692017-10-05 13:16:02 -070023
24#include <binder/IResultReceiver.h>
25#include <binder/IShellCallback.h>
David Chend6896892017-10-25 11:49:03 -070026#include <gtest/gtest_prod.h>
David Chende701692017-10-05 13:16:02 -070027#include <log/logprint.h>
David Chende701692017-10-05 13:16:02 -070028#include <stdio.h>
David Chende701692017-10-05 13:16:02 -070029#include <utils/RefBase.h>
Joe Onorato9fc9edf2017-10-15 20:08:52 -070030#include <mutex>
31#include <set>
32#include <string>
33#include <unordered_map>
David Chende701692017-10-05 13:16:02 -070034
35using namespace std;
36
37namespace android {
38namespace os {
39namespace statsd {
40
41struct AppData {
42 const string packageName;
Dianne Hackborn3accca02013-09-20 09:32:11 -070043 int64_t versionCode;
David Chende701692017-10-05 13:16:02 -070044
Dianne Hackborn3accca02013-09-20 09:32:11 -070045 AppData(const string& a, const int64_t v) : packageName(a), versionCode(v){};
David Chende701692017-10-05 13:16:02 -070046};
47
48// UidMap keeps track of what the corresponding app name (APK name) and version code for every uid
49// at any given moment. This map must be updated by StatsCompanionService.
Joe Onorato9fc9edf2017-10-15 20:08:52 -070050class UidMap : public virtual android::RefBase {
David Chende701692017-10-05 13:16:02 -070051public:
David Chenc136f452017-11-27 11:52:26 -080052 UidMap();
53 ~UidMap();
Yao Chen147ce602017-12-22 14:35:34 -080054 static const std::map<std::string, uint32_t> sAidToUidMapping;
David Chende701692017-10-05 13:16:02 -070055 /*
56 * All three inputs must be the same size, and the jth element in each array refers to the same
57 * tuple, ie. uid[j] corresponds to packageName[j] with versionCode[j].
58 */
Dianne Hackborn3accca02013-09-20 09:32:11 -070059 void updateMap(const vector<int32_t>& uid, const vector<int64_t>& versionCode,
David Chende701692017-10-05 13:16:02 -070060 const vector<String16>& packageName);
61
Dianne Hackborn3accca02013-09-20 09:32:11 -070062 void updateApp(const String16& packageName, const int32_t& uid, const int64_t& versionCode);
David Chend6896892017-10-25 11:49:03 -070063 void removeApp(const String16& packageName, const int32_t& uid);
64
David Chende701692017-10-05 13:16:02 -070065 // Returns true if the given uid contains the specified app (eg. com.google.android.gms).
66 bool hasApp(int uid, const string& packageName) const;
67
Yangster9df9a7f2017-12-18 13:33:05 -080068 // Returns the app names from uid.
69 std::set<string> getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const;
70
Dianne Hackborn3accca02013-09-20 09:32:11 -070071 int64_t getAppVersion(int uid, const string& packageName) const;
David Chende701692017-10-05 13:16:02 -070072
David Chende701692017-10-05 13:16:02 -070073 // Helper for debugging contents of this uid map. Can be triggered with:
74 // adb shell cmd stats print-uid-map
Yao Chend10f7b12017-12-18 12:53:50 -080075 void printUidMap(FILE* out) const;
David Chende701692017-10-05 13:16:02 -070076
77 // Commands for indicating to the map that a producer should be notified if an app is updated.
78 // This allows the metric producer to distinguish when the same uid or app represents a
79 // different version of an app.
Yao Chend10f7b12017-12-18 12:53:50 -080080 void addListener(wp<PackageInfoListener> producer);
David Chende701692017-10-05 13:16:02 -070081 // Remove the listener from the set of metric producers that subscribe to updates.
Yao Chend10f7b12017-12-18 12:53:50 -080082 void removeListener(wp<PackageInfoListener> producer);
David Chende701692017-10-05 13:16:02 -070083
David Chend6896892017-10-25 11:49:03 -070084 // Informs uid map that a config is added/updated. Used for keeping mConfigKeys up to date.
85 void OnConfigUpdated(const ConfigKey& key);
86
87 // Informs uid map that a config is removed. Used for keeping mConfigKeys up to date.
88 void OnConfigRemoved(const ConfigKey& key);
89
David Chen21582962017-11-01 17:32:46 -070090 void assignIsolatedUid(int isolatedUid, int parentUid);
91 void removeIsolatedUid(int isolatedUid, int parentUid);
92
Yangster-macd40053e2018-01-09 16:29:22 -080093 // Returns the host uid if it exists. Otherwise, returns the same uid that was passed-in.
Chenjie Yu80f91122018-01-31 20:24:50 -080094 virtual int getHostUidOrSelf(int uid) const;
David Chen21582962017-11-01 17:32:46 -070095
David Chend6896892017-10-25 11:49:03 -070096 // Gets the output. If every config key has received the output, then the output is cleared.
97 UidMapping getOutput(const ConfigKey& key);
98
99 // Forces the output to be cleared. We still generate a snapshot based on the current state.
100 // This results in extra data uploaded but helps us reconstruct the uid mapping on the server
101 // in case we lose a previous upload.
102 void clearOutput();
David Chende701692017-10-05 13:16:02 -0700103
David Chenc136f452017-11-27 11:52:26 -0800104 // Get currently cached value of memory used by UID map.
Yao Chend10f7b12017-12-18 12:53:50 -0800105 size_t getBytesUsed() const;
106
107 std::set<int32_t> getAppUid(const string& package) const;
David Chenc136f452017-11-27 11:52:26 -0800108
David Chende701692017-10-05 13:16:02 -0700109private:
Yangster9df9a7f2017-12-18 13:33:05 -0800110 std::set<string> getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const;
111 string normalizeAppName(const string& appName) const;
112
David Chend6896892017-10-25 11:49:03 -0700113 void updateMap(const int64_t& timestamp, const vector<int32_t>& uid,
Dianne Hackborn3accca02013-09-20 09:32:11 -0700114 const vector<int64_t>& versionCode, const vector<String16>& packageName);
David Chend6896892017-10-25 11:49:03 -0700115
David Chend6896892017-10-25 11:49:03 -0700116 void updateApp(const int64_t& timestamp, const String16& packageName, const int32_t& uid,
Dianne Hackborn3accca02013-09-20 09:32:11 -0700117 const int64_t& versionCode);
David Chend6896892017-10-25 11:49:03 -0700118 void removeApp(const int64_t& timestamp, const String16& packageName, const int32_t& uid);
119
120 UidMapping getOutput(const int64_t& timestamp, const ConfigKey& key);
121
Yao Chend10f7b12017-12-18 12:53:50 -0800122 void getListenerListCopyLocked(std::vector<wp<PackageInfoListener>>* output);
123
David Chende701692017-10-05 13:16:02 -0700124 // TODO: Use shared_mutex for improved read-locking if a library can be found in Android.
125 mutable mutex mMutex;
David Chen21582962017-11-01 17:32:46 -0700126 mutable mutex mIsolatedMutex;
David Chende701692017-10-05 13:16:02 -0700127
David Chend6896892017-10-25 11:49:03 -0700128 // Maps uid to application data. This must be multimap since there is a feature in Android for
129 // multiple apps to share the same uid.
David Chende701692017-10-05 13:16:02 -0700130 std::unordered_multimap<int, AppData> mMap;
131
David Chen21582962017-11-01 17:32:46 -0700132 // Maps isolated uid to the parent uid. Any metrics for an isolated uid will instead contribute
133 // to the parent uid.
134 std::unordered_map<int, int> mIsolatedUidMap;
135
David Chende701692017-10-05 13:16:02 -0700136 // We prepare the output proto as apps are updated, so that we can grab the current output.
137 UidMapping mOutput;
138
139 // Metric producers that should be notified if there's an upgrade in any app.
Yao Chend10f7b12017-12-18 12:53:50 -0800140 set<wp<PackageInfoListener>> mSubscribers;
David Chend6896892017-10-25 11:49:03 -0700141
142 // Mapping of config keys we're aware of to the epoch time they last received an update. This
143 // lets us know it's safe to delete events older than the oldest update. The value is nanosec.
144 // Value of -1 denotes this config key has never received an upload.
145 std::unordered_map<ConfigKey, int64_t> mLastUpdatePerConfigKey;
146
147 // Returns the minimum value from mConfigKeys.
148 int64_t getMinimumTimestampNs();
149
David Chenc136f452017-11-27 11:52:26 -0800150 // If our current used bytes is above the limit, then we clear out the earliest snapshot. If
151 // there are no more snapshots, then we clear out the earliest delta. We repeat the deletions
152 // until the memory consumed by mOutput is below the specified limit.
153 void ensureBytesUsedBelowLimit();
154
David Chenc0f6f632018-01-18 16:02:42 -0800155 // Override used for testing the max memory allowed by uid map. 0 means we use the value
David Chenc136f452017-11-27 11:52:26 -0800156 // specified in StatsdStats.h with the rest of the guardrails.
David Chenc0f6f632018-01-18 16:02:42 -0800157 size_t maxBytesOverride = 0;
David Chenc136f452017-11-27 11:52:26 -0800158
159 // Cache the size of mOutput;
160 size_t mBytesUsed;
161
David Chend6896892017-10-25 11:49:03 -0700162 // Allows unit-test to access private methods.
163 FRIEND_TEST(UidMapTest, TestClearingOutput);
David Chenc136f452017-11-27 11:52:26 -0800164 FRIEND_TEST(UidMapTest, TestMemoryComputed);
165 FRIEND_TEST(UidMapTest, TestMemoryGuardrail);
David Chende701692017-10-05 13:16:02 -0700166};
167
168} // namespace statsd
169} // namespace os
170} // namespace android