1 /* 2 * Copyright (C) 2023 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 package com.android.customization.module.logging 17 18 import android.util.Log 19 import com.android.internal.logging.InstanceId 20 import com.android.internal.logging.InstanceIdSequence 21 import javax.inject.Inject 22 import javax.inject.Singleton 23 24 @Singleton 25 class AppSessionId @Inject constructor() { 26 27 private var idSequence: InstanceIdSequence? = null 28 29 private var sessionId: InstanceId? = null 30 createNewIdnull31 fun createNewId(): AppSessionId { 32 sessionId = newInstanceId() 33 return this 34 } 35 getIdnull36 fun getId(): Int { 37 val id = 38 sessionId 39 ?: newInstanceId().also { 40 Log.w( 41 TAG, 42 "Session ID should not be null. We should always call createNewId() before calling getId()." 43 ) 44 sessionId = it 45 } 46 return id.hashCode() 47 } 48 newInstanceIdnull49 private fun newInstanceId(): InstanceId = 50 (idSequence ?: InstanceIdSequence(INSTANCE_ID_MAX).also { idSequence = it }).newInstanceId() 51 52 companion object { 53 private const val TAG = "AppSessionId" 54 // At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values 55 private const val INSTANCE_ID_MAX = 1 shl 20 56 } 57 } 58