Merge "[SettingsProvider] add generation registry stats to dumpsys" into udc-dev

This commit is contained in:
TreeHugger Robot
2023-04-03 20:24:35 +00:00
committed by Android (Google) Code Review
5 changed files with 157 additions and 0 deletions

View File

@@ -21,6 +21,7 @@ option java_multiple_files = true;
option java_outer_classname = "SettingsServiceProto"; option java_outer_classname = "SettingsServiceProto";
import "frameworks/base/core/proto/android/providers/settings/config.proto"; import "frameworks/base/core/proto/android/providers/settings/config.proto";
import "frameworks/base/core/proto/android/providers/settings/generation.proto";
import "frameworks/base/core/proto/android/providers/settings/global.proto"; import "frameworks/base/core/proto/android/providers/settings/global.proto";
import "frameworks/base/core/proto/android/providers/settings/secure.proto"; import "frameworks/base/core/proto/android/providers/settings/secure.proto";
import "frameworks/base/core/proto/android/providers/settings/system.proto"; import "frameworks/base/core/proto/android/providers/settings/system.proto";
@@ -37,6 +38,9 @@ message SettingsServiceDumpProto {
// Config settings // Config settings
optional ConfigSettingsProto config_settings = 3; optional ConfigSettingsProto config_settings = 3;
// Generation registry stats
optional GenerationRegistryProto generation_registry = 4;
} }
message UserSettingsProto { message UserSettingsProto {

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
syntax = "proto2";
package android.providers.settings;
option java_multiple_files = true;
import "frameworks/base/core/proto/android/privacy.proto";
message GenerationRegistryProto {
option (android.msg_privacy).dest = DEST_EXPLICIT;
optional int32 num_backing_stores = 1;
optional int32 num_max_backing_stores = 2;
repeated BackingStoreProto backing_stores = 3;
}
message BackingStoreProto {
optional int32 key = 1;
optional int32 backing_store_size = 2;
optional int32 num_cached_entries = 3;
repeated CacheEntryProto cache_entries = 4;
}
message CacheEntryProto {
optional string name = 1;
optional int32 generation = 2;
}

View File

@@ -20,14 +20,19 @@ import android.annotation.NonNull;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.providers.settings.BackingStoreProto;
import android.providers.settings.CacheEntryProto;
import android.providers.settings.GenerationRegistryProto;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.MemoryIntArray; import android.util.MemoryIntArray;
import android.util.Slog; import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter;
/** /**
* This class tracks changes for config/global/secure/system tables * This class tracks changes for config/global/secure/system tables
@@ -292,4 +297,94 @@ final class GenerationRegistry {
int getMaxNumBackingStores() { int getMaxNumBackingStores() {
return mMaxNumBackingStore; return mMaxNumBackingStore;
} }
public void dumpProto(ProtoOutputStream proto) {
synchronized (mLock) {
final int numBackingStores = mKeyToBackingStoreMap.size();
proto.write(GenerationRegistryProto.NUM_BACKING_STORES, numBackingStores);
proto.write(GenerationRegistryProto.NUM_MAX_BACKING_STORES, getMaxNumBackingStores());
for (int i = 0; i < numBackingStores; i++) {
final long token = proto.start(GenerationRegistryProto.BACKING_STORES);
final int key = mKeyToBackingStoreMap.keyAt(i);
proto.write(BackingStoreProto.KEY, key);
try {
proto.write(BackingStoreProto.BACKING_STORE_SIZE,
mKeyToBackingStoreMap.valueAt(i).size());
} catch (IOException ignore) {
}
proto.write(BackingStoreProto.NUM_CACHED_ENTRIES,
mKeyToIndexMapMap.get(key).size());
final ArrayMap<String, Integer> indexMap = mKeyToIndexMapMap.get(key);
final MemoryIntArray backingStore = getBackingStoreLocked(key,
/* createIfNotExist= */ false);
if (indexMap == null || backingStore == null) {
continue;
}
for (String setting : indexMap.keySet()) {
try {
final int index = getKeyIndexLocked(key, setting, mKeyToIndexMapMap,
backingStore, /* createIfNotExist= */ false);
if (index < 0) {
continue;
}
final long cacheEntryToken = proto.start(
BackingStoreProto.CACHE_ENTRIES);
final int generation = backingStore.get(index);
proto.write(CacheEntryProto.NAME,
setting.equals(DEFAULT_MAP_KEY_FOR_UNSET_SETTINGS)
? "UNSET" : setting);
proto.write(CacheEntryProto.GENERATION, generation);
proto.end(cacheEntryToken);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
proto.end(token);
}
}
}
public void dump(PrintWriter pw) {
pw.println("GENERATION REGISTRY");
pw.println("Maximum number of backing stores:" + getMaxNumBackingStores());
synchronized (mLock) {
final int numBackingStores = mKeyToBackingStoreMap.size();
pw.println("Number of backing stores:" + numBackingStores);
for (int i = 0; i < numBackingStores; i++) {
final int key = mKeyToBackingStoreMap.keyAt(i);
pw.print("_Backing store for type:"); pw.print(SettingsState.settingTypeToString(
SettingsState.getTypeFromKey(key)));
pw.print(" user:"); pw.print(SettingsState.getUserIdFromKey(key));
try {
pw.print(" size:" + mKeyToBackingStoreMap.valueAt(i).size());
} catch (IOException ignore) {
}
pw.println(" cachedEntries:" + mKeyToIndexMapMap.get(key).size());
final ArrayMap<String, Integer> indexMap = mKeyToIndexMapMap.get(key);
final MemoryIntArray backingStore = getBackingStoreLocked(key,
/* createIfNotExist= */ false);
if (indexMap == null || backingStore == null) {
continue;
}
for (String setting : indexMap.keySet()) {
try {
final int index = getKeyIndexLocked(key, setting, mKeyToIndexMapMap,
backingStore, /* createIfNotExist= */ false);
if (index < 0) {
continue;
}
final int generation = backingStore.get(index);
pw.print(" setting: "); pw.print(
setting.equals(DEFAULT_MAP_KEY_FOR_UNSET_SETTINGS)
? "UNSET" : setting);
pw.println(" generation:" + generation);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
} }

View File

@@ -120,6 +120,17 @@ class SettingsProtoDumpUtil {
dumpProtoUserSettingsLocked(proto, SettingsServiceDumpProto.USER_SETTINGS, dumpProtoUserSettingsLocked(proto, SettingsServiceDumpProto.USER_SETTINGS,
settingsRegistry, UserHandle.of(users.keyAt(i))); settingsRegistry, UserHandle.of(users.keyAt(i)));
} }
// Generation registry
dumpProtoGenerationRegistryLocked(proto, SettingsServiceDumpProto.GENERATION_REGISTRY,
settingsRegistry);
}
private static void dumpProtoGenerationRegistryLocked(@NonNull ProtoOutputStream proto,
long fieldId, SettingsProvider.SettingsRegistry settingsRegistry) {
final long token = proto.start(fieldId);
settingsRegistry.getGenerationRegistry().dumpProto(proto);
proto.end(token);
} }
/** /**

View File

@@ -900,6 +900,7 @@ public class SettingsProvider extends ContentProvider {
} finally { } finally {
Binder.restoreCallingIdentity(identity); Binder.restoreCallingIdentity(identity);
} }
mSettingsRegistry.mGenerationRegistry.dump(pw);
} }
} }
@@ -6024,5 +6025,10 @@ public class SettingsProvider extends ContentProvider {
return !a11yButtonTargetsSettings.isNull() return !a11yButtonTargetsSettings.isNull()
&& !TextUtils.isEmpty(a11yButtonTargetsSettings.getValue()); && !TextUtils.isEmpty(a11yButtonTargetsSettings.getValue());
} }
@NonNull
public GenerationRegistry getGenerationRegistry() {
return mGenerationRegistry;
}
} }
} }