Loading core/proto/android/providers/settings.proto +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ option java_multiple_files = true; option java_outer_classname = "SettingsServiceProto"; 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/secure.proto"; import "frameworks/base/core/proto/android/providers/settings/system.proto"; Loading @@ -37,6 +38,9 @@ message SettingsServiceDumpProto { // Config settings optional ConfigSettingsProto config_settings = 3; // Generation registry stats optional GenerationRegistryProto generation_registry = 4; } message UserSettingsProto { Loading core/proto/android/providers/settings/generation.proto 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * 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; } No newline at end of file packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java +95 −0 Original line number Diff line number Diff line Loading @@ -20,14 +20,19 @@ import android.annotation.NonNull; import android.os.Bundle; import android.os.UserHandle; 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.MemoryIntArray; import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.io.IOException; import java.io.PrintWriter; /** * This class tracks changes for config/global/secure/system tables Loading Loading @@ -292,4 +297,94 @@ final class GenerationRegistry { int getMaxNumBackingStores() { 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); } } } } } } No newline at end of file packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +11 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,17 @@ class SettingsProtoDumpUtil { dumpProtoUserSettingsLocked(proto, SettingsServiceDumpProto.USER_SETTINGS, 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); } /** Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +6 −0 Original line number Diff line number Diff line Loading @@ -900,6 +900,7 @@ public class SettingsProvider extends ContentProvider { } finally { Binder.restoreCallingIdentity(identity); } mSettingsRegistry.mGenerationRegistry.dump(pw); } } Loading Loading @@ -6024,5 +6025,10 @@ public class SettingsProvider extends ContentProvider { return !a11yButtonTargetsSettings.isNull() && !TextUtils.isEmpty(a11yButtonTargetsSettings.getValue()); } @NonNull public GenerationRegistry getGenerationRegistry() { return mGenerationRegistry; } } } Loading
core/proto/android/providers/settings.proto +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ option java_multiple_files = true; option java_outer_classname = "SettingsServiceProto"; 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/secure.proto"; import "frameworks/base/core/proto/android/providers/settings/system.proto"; Loading @@ -37,6 +38,9 @@ message SettingsServiceDumpProto { // Config settings optional ConfigSettingsProto config_settings = 3; // Generation registry stats optional GenerationRegistryProto generation_registry = 4; } message UserSettingsProto { Loading
core/proto/android/providers/settings/generation.proto 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * 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; } No newline at end of file
packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java +95 −0 Original line number Diff line number Diff line Loading @@ -20,14 +20,19 @@ import android.annotation.NonNull; import android.os.Bundle; import android.os.UserHandle; 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.MemoryIntArray; import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.io.IOException; import java.io.PrintWriter; /** * This class tracks changes for config/global/secure/system tables Loading Loading @@ -292,4 +297,94 @@ final class GenerationRegistry { int getMaxNumBackingStores() { 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); } } } } } } No newline at end of file
packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +11 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,17 @@ class SettingsProtoDumpUtil { dumpProtoUserSettingsLocked(proto, SettingsServiceDumpProto.USER_SETTINGS, 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); } /** Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +6 −0 Original line number Diff line number Diff line Loading @@ -900,6 +900,7 @@ public class SettingsProvider extends ContentProvider { } finally { Binder.restoreCallingIdentity(identity); } mSettingsRegistry.mGenerationRegistry.dump(pw); } } Loading Loading @@ -6024,5 +6025,10 @@ public class SettingsProvider extends ContentProvider { return !a11yButtonTargetsSettings.isNull() && !TextUtils.isEmpty(a11yButtonTargetsSettings.getValue()); } @NonNull public GenerationRegistry getGenerationRegistry() { return mGenerationRegistry; } } }