10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project 30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License. 60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at 70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software 110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and 140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License. 150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.cat; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 19d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccFileHandler; 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.graphics.Bitmap; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.graphics.Color; 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler; 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.HandlerThread; 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Looper; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message; 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.HashMap; 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Class for loading icons from the SIM card. Has two states: single, for loading 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * one icon. Multi, for loading icons list. 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleclass IconLoader extends Handler { 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // members 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int mState = STATE_SINGLE_ICON; 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private ImageDescriptor mId = null; 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private Bitmap mCurrentIcon = null; 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int mRecordNumber; 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private IccFileHandler mSimFH = null; 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private Message mEndMsg = null; 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private byte[] mIconData = null; 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // multi icons state members 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int[] mRecordNumbers = null; 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int mCurrentRecordIndex = 0; 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private Bitmap[] mIcons = null; 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private HashMap<Integer, Bitmap> mIconsCache = null; 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static IconLoader sLoader = null; 51eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta private static HandlerThread sThread = null; 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Loader state values. 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int STATE_SINGLE_ICON = 1; 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int STATE_MULTI_ICONS = 2; 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Finished loading single record from a linear-fixed EF-IMG. 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int EVENT_READ_EF_IMG_RECOED_DONE = 1; 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Finished loading single icon from a Transparent DF-Graphics. 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int EVENT_READ_ICON_DONE = 2; 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Finished loading single colour icon lookup table. 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int EVENT_READ_CLUT_DONE = 3; 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Color lookup table offset inside the EF. 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int CLUT_LOCATION_OFFSET = 4; 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // CLUT entry size, {Red, Green, Black} 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int CLUT_ENTRY_SIZE = 3; 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private IconLoader(Looper looper , IccFileHandler fh) { 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville super(looper); 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSimFH = fh; 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIconsCache = new HashMap<Integer, Bitmap>(50); 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static IconLoader getInstance(Handler caller, IccFileHandler fh) { 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (sLoader != null) { 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return sLoader; 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (fh != null) { 82eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta sThread = new HandlerThread("Cat Icon Loader"); 83eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta sThread.start(); 84eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta return new IconLoader(sThread.getLooper(), fh); 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void loadIcons(int[] recordNumbers, Message msg) { 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (recordNumbers == null || recordNumbers.length == 0 || msg == null) { 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEndMsg = msg; 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // initialize multi icons load variables. 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIcons = new Bitmap[recordNumbers.length]; 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRecordNumbers = recordNumbers; 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrentRecordIndex = 0; 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mState = STATE_MULTI_ICONS; 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville startLoadingIcon(recordNumbers[0]); 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void loadIcon(int recordNumber, Message msg) { 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (msg == null) { 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEndMsg = msg; 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mState = STATE_SINGLE_ICON; 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville startLoadingIcon(recordNumber); 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void startLoadingIcon(int recordNumber) { 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Reset the load variables. 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mId = null; 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIconData = null; 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrentIcon = null; 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRecordNumber = recordNumber; 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // make sure the icon was not already loaded and saved in the local cache. 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mIconsCache.containsKey(recordNumber)) { 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrentIcon = mIconsCache.get(recordNumber); 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville postIcon(); 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // start the first phase ==> loading Image Descriptor. 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville readId(); 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void handleMessage(Message msg) { 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville AsyncResult ar; 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (msg.what) { 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_READ_EF_IMG_RECOED_DONE: 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult) msg.obj; 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (handleImageDescriptor((byte[]) ar.result)) { 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville readIconData(); 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new Exception("Unable to parse image descriptor"); 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_READ_ICON_DONE: 1446bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville CatLog.d(this, "load icon done"); 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult) msg.obj; 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] rawData = ((byte[]) ar.result); 14722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mId.mCodingScheme == ImageDescriptor.CODING_SCHEME_BASIC) { 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrentIcon = parseToBnW(rawData, rawData.length); 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIconsCache.put(mRecordNumber, mCurrentIcon); 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville postIcon(); 15122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mId.mCodingScheme == ImageDescriptor.CODING_SCHEME_COLOUR) { 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIconData = rawData; 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville readClut(); 1546bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville } else { 1556bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville CatLog.d(this, "else /postIcon "); 1566bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville postIcon(); 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_READ_CLUT_DONE: 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult) msg.obj; 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte [] clut = ((byte[]) ar.result); 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrentIcon = parseToRGB(mIconData, mIconData.length, 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville false, clut); 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIconsCache.put(mRecordNumber, mCurrentIcon); 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville postIcon(); 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (Exception e) { 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "Icon load failed"); 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // post null icon back to the caller. 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville postIcon(); 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Handles Image descriptor parsing and required processing. This is the 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * first step required to handle retrieving icons from the SIM. 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 179cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * @param rawData byte [] containing Image Instance descriptor as defined in 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TS 51.011. 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean handleImageDescriptor(byte[] rawData) { 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mId = ImageDescriptor.parse(rawData, 1); 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mId == null) { 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 190cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville // Start reading color lookup table from SIM card. 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void readClut() { 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int length = mIconData[3] * CLUT_ENTRY_SIZE; 19322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville Message msg = obtainMessage(EVENT_READ_CLUT_DONE); 19422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mSimFH.loadEFImgTransparent(mId.mImageId, 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIconData[CLUT_LOCATION_OFFSET], 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIconData[CLUT_LOCATION_OFFSET + 1], length, msg); 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Start reading Image Descriptor from SIM card. 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void readId() { 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mRecordNumber < 0) { 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrentIcon = null; 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville postIcon(); 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 20622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville Message msg = obtainMessage(EVENT_READ_EF_IMG_RECOED_DONE); 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSimFH.loadEFImgLinearFixed(mRecordNumber, msg); 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Start reading icon bytes array from SIM card. 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void readIconData() { 21222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville Message msg = obtainMessage(EVENT_READ_ICON_DONE); 21322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mSimFH.loadEFImgTransparent(mId.mImageId, 0, 0, mId.mLength ,msg); 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // When all is done pass icon back to caller. 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void postIcon() { 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mState == STATE_SINGLE_ICON) { 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEndMsg.obj = mCurrentIcon; 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEndMsg.sendToTarget(); 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (mState == STATE_MULTI_ICONS) { 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIcons[mCurrentRecordIndex++] = mCurrentIcon; 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // If not all icons were loaded, start loading the next one. 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mCurrentRecordIndex < mRecordNumbers.length) { 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville startLoadingIcon(mRecordNumbers[mCurrentRecordIndex]); 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEndMsg.obj = mIcons; 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEndMsg.sendToTarget(); 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Convert a TS 131.102 image instance of code scheme '11' into Bitmap 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param data The raw data 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param length The length of image body 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return The bitmap 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static Bitmap parseToBnW(byte[] data, int length){ 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int valueIndex = 0; 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int width = data[valueIndex++] & 0xFF; 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int height = data[valueIndex++] & 0xFF; 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int numOfPixels = width*height; 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] pixels = new int[numOfPixels]; 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int pixelIndex = 0; 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bitIndex = 7; 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte currentByte = 0x00; 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville while (pixelIndex < numOfPixels) { 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // reassign data and index for every byte (8 bits). 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (pixelIndex % 8 == 0) { 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville currentByte = data[valueIndex++]; 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bitIndex = 7; 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pixels[pixelIndex++] = bitToBnW((currentByte >> bitIndex-- ) & 0x01); 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (pixelIndex != numOfPixels) { 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d("IconLoader", "parseToBnW; size error"); 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Decode one bit to a black and white color: 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 0 is black 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1 is white 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param bit to decode 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return RGB color 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static int bitToBnW(int bit){ 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if(bit == 1){ 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Color.WHITE; 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Color.BLACK; 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * a TS 131.102 image instance of code scheme '11' into color Bitmap 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param data The raw data 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param length the length of image body 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param transparency with or without transparency 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param clut coulor lookup table 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return The color bitmap 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static Bitmap parseToRGB(byte[] data, int length, 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean transparency, byte[] clut) { 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int valueIndex = 0; 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int width = data[valueIndex++] & 0xFF; 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int height = data[valueIndex++] & 0xFF; 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bitsPerImg = data[valueIndex++] & 0xFF; 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int numOfClutEntries = data[valueIndex++] & 0xFF; 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (true == transparency) { 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville clut[numOfClutEntries - 1] = Color.TRANSPARENT; 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int numOfPixels = width * height; 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int[] pixels = new int[numOfPixels]; 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville valueIndex = 6; 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int pixelIndex = 0; 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bitsStartOffset = 8 - bitsPerImg; 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bitIndex = bitsStartOffset; 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte currentByte = data[valueIndex++]; 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int mask = getMask(bitsPerImg); 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean bitsOverlaps = (8 % bitsPerImg == 0); 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville while (pixelIndex < numOfPixels) { 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // reassign data and index for every byte (8 bits). 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (bitIndex < 0) { 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville currentByte = data[valueIndex++]; 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bitIndex = bitsOverlaps ? (bitsStartOffset) : (bitIndex * -1); 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int clutEntry = ((currentByte >> bitIndex) & mask); 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int clutIndex = clutEntry * CLUT_ENTRY_SIZE; 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pixels[pixelIndex++] = Color.rgb(clut[clutIndex], 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville clut[clutIndex + 1], clut[clutIndex + 2]); 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bitIndex -= bitsPerImg; 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Bitmap.createBitmap(pixels, width, height, 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Bitmap.Config.ARGB_8888); 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Calculate bit mask for a given number of bits. The mask should enable to 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * make a bitwise and to the given number of bits. 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param numOfBits number of bits to calculate mask for. 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return bit mask 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static int getMask(int numOfBits) { 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int mask = 0x00; 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (numOfBits) { 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 1: 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0x01; 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 2: 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0x03; 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 3: 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0x07; 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 4: 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0x0F; 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 5: 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0x1F; 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 6: 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0x3F; 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 7: 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0x7F; 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 8: 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mask = 0xFF; 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mask; 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 365eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta public void dispose() { 366eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta mSimFH = null; 367eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta if (sThread != null) { 368eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta sThread.quit(); 369eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta sThread = null; 370eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta } 371eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta mIconsCache = null; 372eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta sLoader = null; 373eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta } 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 375