1 /* 2 * Copyright (C) 2011 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.internal.telephony.uicc; 18 19 import android.compat.annotation.UnsupportedAppUsage; 20 import android.os.Build; 21 22 import com.android.telephony.Rlog; 23 24 /** 25 * Wrapper class for an ICC EF containing a bit field of enabled services. 26 */ 27 public abstract class IccServiceTable { 28 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 29 protected final byte[] mServiceTable; 30 IccServiceTable(byte[] table)31 protected IccServiceTable(byte[] table) { 32 mServiceTable = table; 33 } 34 35 // Get the class name to use for log strings 36 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getTag()37 protected abstract String getTag(); 38 39 // Get the array of enums to use for toString getValues()40 protected abstract Object[] getValues(); 41 42 /** 43 * Returns if the specified service is available. 44 * @param service the service number as a zero-based offset (the enum ordinal) 45 * @return true if the service is available; false otherwise 46 */ isAvailable(int service)47 protected boolean isAvailable(int service) { 48 int offset = service / 8; 49 if (offset >= mServiceTable.length) { 50 // Note: Enums are zero-based, but the TS service numbering is one-based 51 Rlog.e(getTag(), "isAvailable for service " + (service + 1) + " fails, max service is " + 52 (mServiceTable.length * 8)); 53 return false; 54 } 55 int bit = service % 8; 56 return (mServiceTable[offset] & (1 << bit)) != 0; 57 } 58 59 @Override toString()60 public String toString() { 61 Object[] values = getValues(); 62 int numBytes = mServiceTable.length; 63 StringBuilder builder = new StringBuilder(getTag()).append('[') 64 .append(numBytes * 8).append("]={ "); 65 66 boolean addComma = false; 67 for (int i = 0; i < numBytes; i++) { 68 byte currentByte = mServiceTable[i]; 69 for (int bit = 0; bit < 8; bit++) { 70 if ((currentByte & (1 << bit)) != 0) { 71 if (addComma) { 72 builder.append(", "); 73 } else { 74 addComma = true; 75 } 76 int ordinal = (i * 8) + bit; 77 if (ordinal < values.length) { 78 builder.append(values[ordinal]); 79 } else { 80 builder.append('#').append(ordinal + 1); // service number (one-based) 81 } 82 } 83 } 84 } 85 return builder.append(" }").toString(); 86 } 87 } 88