BufferItem.cpp revision ff95aabbcc6e8606acbd7933c90eeb9b8b382a21
1289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza/* 2289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * Copyright 2014 The Android Open Source Project 3289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * 4289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * Licensed under the Apache License, Version 2.0 (the "License"); 5289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * you may not use this file except in compliance with the License. 6289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * You may obtain a copy of the License at 7289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * 8289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * http://www.apache.org/licenses/LICENSE-2.0 9289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * 10289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * Unless required by applicable law or agreed to in writing, software 11289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * distributed under the License is distributed on an "AS IS" BASIS, 12289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * See the License for the specific language governing permissions and 14289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza * limitations under the License. 15289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza */ 16289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 17289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <gui/BufferItem.h> 18289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 19289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <ui/Fence.h> 20289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <ui/GraphicBuffer.h> 21289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 22289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza#include <system/window.h> 23289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 24289ade165e60b5f71734d30e535f16eb1f4313adDan Stozanamespace android { 25289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 26289ade165e60b5f71734d30e535f16eb1f4313adDan StozaBufferItem::BufferItem() : 27ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mGraphicBuffer(NULL), 28ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mFence(NULL), 2960d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos mCrop(Rect::INVALID_RECT), 30289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mTransform(0), 31289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 32289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mTimestamp(0), 33289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mIsAutoTimestamp(false), 3482c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala mDataSpace(HAL_DATASPACE_UNKNOWN), 35289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mFrameNumber(0), 36289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mSlot(INVALID_BUFFER_SLOT), 37289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mIsDroppable(false), 38289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mAcquireCalled(false), 39ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mTransformToDisplayInverse(false), 40063121849890da78b1ad7fb96c54c795de5d1fd6Pablo Ceballos mSurfaceDamage(), 41ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos mAutoRefresh(false), 4223b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mQueuedBuffer(true), 4323b4abe024ea88c45e0b94c80e1fb537a573b143Pablo Ceballos mIsStale(false) { 44289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 45289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 468dc55396fc9bc425b5e2c82e76a38080f2a655ffDan StozaBufferItem::~BufferItem() {} 478dc55396fc9bc425b5e2c82e76a38080f2a655ffDan Stoza 48eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stozatemplate <typename T> 49eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stozastatic void addAligned(size_t& size, T /* value */) { 50eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza size = FlattenableUtils::align<sizeof(T)>(size); 51eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza size += sizeof(T); 52eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza} 53eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza 54289ade165e60b5f71734d30e535f16eb1f4313adDan Stozasize_t BufferItem::getPodSize() const { 55eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza size_t size = 0; 56eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza addAligned(size, mCrop); 57eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza addAligned(size, mTransform); 58eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza addAligned(size, mScalingMode); 5947f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang addAligned(size, mTimestampLo); 6047f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang addAligned(size, mTimestampHi); 61eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza addAligned(size, mIsAutoTimestamp); 62eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza addAligned(size, mDataSpace); 6347f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang addAligned(size, mFrameNumberLo); 6447f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang addAligned(size, mFrameNumberHi); 65eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza addAligned(size, mSlot); 66eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza addAligned(size, mIsDroppable); 67eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza addAligned(size, mAcquireCalled); 68eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza addAligned(size, mTransformToDisplayInverse); 69eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza return size; 70289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 71289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 72289ade165e60b5f71734d30e535f16eb1f4313adDan Stozasize_t BufferItem::getFlattenedSize() const { 73eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza size_t size = sizeof(uint32_t); // Flags 74289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mGraphicBuffer != 0) { 75eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza size += mGraphicBuffer->getFlattenedSize(); 76eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza FlattenableUtils::align<4>(size); 77289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 78289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mFence != 0) { 79eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza size += mFence->getFlattenedSize(); 80eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza FlattenableUtils::align<4>(size); 81289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 82eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza size += mSurfaceDamage.getFlattenedSize(); 83eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza size = FlattenableUtils::align<8>(size); 84eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza return size + getPodSize(); 85289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 86289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 87289ade165e60b5f71734d30e535f16eb1f4313adDan Stozasize_t BufferItem::getFdCount() const { 88eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza size_t count = 0; 89289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mGraphicBuffer != 0) { 90eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza count += mGraphicBuffer->getFdCount(); 91289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 92289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mFence != 0) { 93eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza count += mFence->getFdCount(); 94289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 95eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza return count; 96eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza} 97eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza 98eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stozatemplate <typename T> 99eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stozastatic void writeAligned(void*& buffer, size_t& size, T value) { 100eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza size -= FlattenableUtils::align<alignof(T)>(buffer); 101eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza FlattenableUtils::write(buffer, size, value); 102289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 103289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 104289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferItem::flatten( 105289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza void*& buffer, size_t& size, int*& fds, size_t& count) const { 106289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 107289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // make sure we have enough space 108eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza if (size < BufferItem::getFlattenedSize()) { 109289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_MEMORY; 110289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 111289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 112289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // content flags are stored first 113289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza uint32_t& flags = *static_cast<uint32_t*>(buffer); 114289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 115289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza // advance the pointer 116289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza FlattenableUtils::advance(buffer, size, sizeof(uint32_t)); 117289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 118289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza flags = 0; 119289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mGraphicBuffer != 0) { 120289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t err = mGraphicBuffer->flatten(buffer, size, fds, count); 121289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (err) return err; 122289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza size -= FlattenableUtils::align<4>(buffer); 123289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza flags |= 1; 124289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 125289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (mFence != 0) { 126289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t err = mFence->flatten(buffer, size, fds, count); 127289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (err) return err; 128289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza size -= FlattenableUtils::align<4>(buffer); 129289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza flags |= 2; 130289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 131eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza 1325065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza status_t err = mSurfaceDamage.flatten(buffer, size); 1335065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza if (err) return err; 134eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize()); 135eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza 136eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza // Check we still have enough space 137289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (size < getPodSize()) { 138289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_MEMORY; 139289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 140289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 141eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza writeAligned(buffer, size, mCrop); 142eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza writeAligned(buffer, size, mTransform); 143eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza writeAligned(buffer, size, mScalingMode); 14447f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang writeAligned(buffer, size, mTimestampLo); 14547f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang writeAligned(buffer, size, mTimestampHi); 146eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza writeAligned(buffer, size, mIsAutoTimestamp); 147eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza writeAligned(buffer, size, mDataSpace); 14847f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang writeAligned(buffer, size, mFrameNumberLo); 14947f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang writeAligned(buffer, size, mFrameNumberHi); 150eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza writeAligned(buffer, size, mSlot); 151eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza writeAligned(buffer, size, mIsDroppable); 152eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza writeAligned(buffer, size, mAcquireCalled); 153eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza writeAligned(buffer, size, mTransformToDisplayInverse); 154289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 155289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 156289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 157289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 158eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stozatemplate <typename T> 159eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stozastatic void readAligned(const void*& buffer, size_t& size, T& value) { 160eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza size -= FlattenableUtils::align<alignof(T)>(buffer); 161eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza FlattenableUtils::read(buffer, size, value); 162eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza} 163eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza 164289ade165e60b5f71734d30e535f16eb1f4313adDan Stozastatus_t BufferItem::unflatten( 165289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza void const*& buffer, size_t& size, int const*& fds, size_t& count) { 166289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 167eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza if (size < sizeof(uint32_t)) { 168289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_MEMORY; 169eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza } 170289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 171289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza uint32_t flags = 0; 172289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza FlattenableUtils::read(buffer, size, flags); 173289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 174289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (flags & 1) { 175289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mGraphicBuffer = new GraphicBuffer(); 176289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count); 177289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (err) return err; 178289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza size -= FlattenableUtils::align<4>(buffer); 179289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 180289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 181289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (flags & 2) { 182289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza mFence = new Fence(); 183289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza status_t err = mFence->unflatten(buffer, size, fds, count); 184289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (err) return err; 185289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza size -= FlattenableUtils::align<4>(buffer); 186289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 187eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza 1885065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza status_t err = mSurfaceDamage.unflatten(buffer, size); 1895065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza if (err) return err; 190eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize()); 191eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza 192eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza // Check we still have enough space 193289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza if (size < getPodSize()) { 194289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_MEMORY; 195289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 196289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 197eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza readAligned(buffer, size, mCrop); 198eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza readAligned(buffer, size, mTransform); 199eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza readAligned(buffer, size, mScalingMode); 20047f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang readAligned(buffer, size, mTimestampLo); 20147f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang readAligned(buffer, size, mTimestampHi); 202eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza readAligned(buffer, size, mIsAutoTimestamp); 203eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza readAligned(buffer, size, mDataSpace); 20447f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang readAligned(buffer, size, mFrameNumberLo); 20547f674dfeca31b29810ecb90f1277918b67c4cf8Chong Zhang readAligned(buffer, size, mFrameNumberHi); 206eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza readAligned(buffer, size, mSlot); 207eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza readAligned(buffer, size, mIsDroppable); 208eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza readAligned(buffer, size, mAcquireCalled); 209eea6d682b8b0f7081f0fe8fab8feadb16e22b30bDan Stoza readAligned(buffer, size, mTransformToDisplayInverse); 210289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 211289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza return NO_ERROR; 212289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 213289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 214289ade165e60b5f71734d30e535f16eb1f4313adDan Stozaconst char* BufferItem::scalingModeName(uint32_t scalingMode) { 215289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza switch (scalingMode) { 216289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE"; 217289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW"; 218289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP"; 219289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza default: return "Unknown"; 220289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza } 221289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} 222289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza 223289ade165e60b5f71734d30e535f16eb1f4313adDan Stoza} // namespace android 224