FileChannelImpl.java revision f6c387128427e121477c1b32ad35cdcaa5101ba3
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Android Notice 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In this class the address length was changed from long to int. 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is due to performance optimizations for the device. 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Also this class was copied from a newer version of harmony. 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.apache.harmony.nio.internal; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.Closeable; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.FileDescriptor; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.ByteBuffer; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.MappedByteBuffer; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.channels.ClosedChannelException; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.channels.FileChannel; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.channels.FileLock; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.channels.NonWritableChannelException; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.channels.ReadableByteChannel; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.channels.WritableByteChannel; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.platform.IFileSystem; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.platform.Platform; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.platform.PlatformAddress; 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.platform.PlatformAddressFactory; 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.nio.internal.nls.Messages; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The file channel impl class is the bridge between the logical channels 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * described by the NIO channel framework, and the file system implementation 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * provided by the port layer. 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class is non-API, but implements the API of the FileChannel interface. 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic abstract class FileChannelImpl extends FileChannel { 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Reference to the portable file system code. 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final IFileSystem fileSystem = Platform.getFileSystem(); 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int ALLOC_GRANULARITY; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static { 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ALLOC_GRANULARITY = fileSystem.getAllocGranularity(); 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new Error(e); 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Handle to the open file 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int handle; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The object that will track all outstanding locks on this channel. 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final LockManager lockManager = new LockManager(); 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private class RepositioningLock {} 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final Object repositioningLock = new RepositioningLock(); 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final Object stream; 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new file channel implementation class that wraps the given file 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * handle and operates in the specified mode. 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public FileChannelImpl(Object stream, int handle) { 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(); 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.handle = handle; 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.stream = stream; 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to throw an exception if the channel is already closed. 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that we don't bother to synchronize on this test since the file may 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * be closed by operations beyond our control anyways. 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final void openCheck() throws ClosedChannelException { 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isOpen()) { 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new ClosedChannelException(); 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (non-Javadoc) 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.nio.channels.spi.AbstractInterruptibleChannel#implCloseChannel() 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void implCloseChannel() throws IOException { 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (stream instanceof Closeable) { 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((Closeable) stream).close(); 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected FileLock basicLock(long position, long size, boolean shared, 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean wait) throws IOException { 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((position < 0) || (size < 0)) { 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // nio.0A=Lock position and size must be non-negative. 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException( 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Messages.getString("nio.0A")); //$NON-NLS-1$ 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int lockType = shared ? IFileSystem.SHARED_LOCK_TYPE 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project : IFileSystem.EXCLUSIVE_LOCK_TYPE; 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FileLock pendingLock = new FileLockImpl(this, position, size, shared); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lockManager.addLock(pendingLock); 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fileSystem.lock(handle, position, size, lockType, wait)) { 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pendingLock; 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Lock acquisition failed 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lockManager.removeLock(pendingLock); 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Acquire a lock on the receiver, blocks if the lock cannot be obtained 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * immediately. 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.nio.channels.FileChannel#lock(long, long, boolean) 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final FileLock lock(long position, long size, boolean shared) 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FileLock resultLock = null; 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean completed = false; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project begin(); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resultLock = basicLock(position, size, shared, true); 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project completed = true; 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end(completed); 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return resultLock; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Attempts to acquire the given lock, but does not block. If the lock 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * cannot be acquired the method returns null. 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.nio.channels.FileChannel#tryLock(long, long, boolean) 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final FileLock tryLock(long position, long size, boolean shared) 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return basicLock(position, size, shared, false); 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Non-API method to release a given lock on a file channel. Assumes that 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the lock will mark itself invalid after successful unlocking. 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void release(FileLock lock) throws IOException { 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileSystem.unlock(handle, lock.position(), lock.size()); 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lockManager.removeLock(lock); 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Flush the contents of the file to disk, and the metadata if asked. 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void force(boolean metadata) throws IOException { 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Forcing data-only on a read-only file is a no-op. 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (metadata) { 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileSystem.fflush(handle, metadata); 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public abstract MappedByteBuffer map(MapMode mode, long position, long size) 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException; 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final MappedByteBuffer mapImpl(int mapMode, long position, 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long size) throws IOException { 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (position + size > size()) { 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileSystem.truncate(handle, position + size); 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long alignment = position - position % ALLOC_GRANULARITY; 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset = (int) (position - alignment); 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PlatformAddress address = PlatformAddressFactory.allocMap(handle, alignment, size 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + offset, mapMode); 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MappedByteBuffer buffer = null; 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer = MappedByteBufferFactory.getBuffer(address, mapMode, size, 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset); 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (Exception e) { 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IOException(e.getMessage()); 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return buffer; 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the current file position. 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public long position() throws IOException { 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return fileSystem.seek(handle, 0L, IFileSystem.SEEK_CUR); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets the file pointer. 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public FileChannel position(long newPosition) throws IOException { 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newPosition < 0) { 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // nio.0B=New position must be non-negative. 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException( 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Messages.getString("nio.0B")); //$NON-NLS-1$ 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project synchronized (repositioningLock) { 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileSystem.seek(handle, newPosition, IFileSystem.SEEK_SET); 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int read(ByteBuffer buffer, long position) throws IOException { 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null == buffer){ 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException(); 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (position < 0){ 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException(); 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!buffer.hasRemaining()){ 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project synchronized (repositioningLock) { 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int bytesRead = 0; 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long preReadPosition = position(); 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project position(position); 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesRead = read(buffer); 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project position(preReadPosition); 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytesRead; 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int read(ByteBuffer buffer) throws IOException { 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!buffer.hasRemaining()){ 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean completed = false; 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int bytesRead = 0; 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project synchronized (repositioningLock) { 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (buffer.isDirect()) { 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DirectBuffer directBuffer = (DirectBuffer) buffer; 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int address = directBuffer.getEffectiveAddress().toInt(); 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project begin(); 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if (bytesRead <= EOF) delt by read completed = false; 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesRead = (int) fileSystem.readDirect(handle, address, 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.position(), buffer.remaining()); 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project completed = true; 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end(completed && bytesRead >= 0); 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project begin(); 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if (bytesRead <= EOF) delt by read completed = false; 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesRead = (int) fileSystem.read(handle, buffer.array(), 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.arrayOffset() + buffer.position(), buffer 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .remaining()); 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project completed = true; 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end(completed && bytesRead >= 0); 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bytesRead > 0) { 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.position(buffer.position() + bytesRead); 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytesRead; 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public long read(ByteBuffer[] buffers, int offset, int length) 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = 0; 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0 || length < 0 || offset + length > buffers.length) { 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IndexOutOfBoundsException(); 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = offset; i < offset + length; i++) { 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count += buffers[i].remaining(); 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (0 == count) { 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size() == 0) { 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteBuffer[] directBuffers = new ByteBuffer[length]; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int[] handles = new int[length]; 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int[] offsets = new int[length]; 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int[] lengths = new int[length]; 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < length; i++) { 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteBuffer buffer = buffers[i + offset]; 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!buffer.isDirect()) { 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer = ByteBuffer.allocateDirect(buffer.remaining()); 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project directBuffers[i] = buffer; 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offsets[i] = 0; 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offsets[i] = buffer.position(); 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handles[i] = ((DirectBuffer) buffer).getEffectiveAddress().toInt(); 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lengths[i] = buffer.remaining(); 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long bytesRead = 0; 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean completed = false; 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project begin(); 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project synchronized (repositioningLock) { 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesRead = fileSystem.readv(handle, handles, offsets, 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lengths, length); 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project completed = true; 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if (bytesRead < EOF) //delt by readv? completed = false; 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end(completed); 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int end = offset + length; 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long bytesRemaining = bytesRead; 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = offset; i < end && bytesRemaining > 0; i++) { 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (buffers[i].isDirect()) { 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (lengths[i] < bytesRemaining) { 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int pos = buffers[i].limit(); 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffers[i].position(pos); 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesRemaining -= lengths[i]; 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int pos = (int) bytesRemaining; 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffers[i].position(pos); 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteBuffer buf = directBuffers[i - offset]; 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bytesRemaining < buf.remaining()){ 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // this is the last step. 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int pos = buf.position(); 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffers[i].put(buf); 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffers[i].position(pos + (int)bytesRemaining); 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesRemaining = 0; 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesRemaining -= buf.remaining(); 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffers[i].put(buf); 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytesRead; 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the current file size, as an integer number of bytes. 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public long size() throws IOException { 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project synchronized (repositioningLock) { 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long currentPosition = fileSystem.seek(handle, 0L, 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IFileSystem.SEEK_CUR); 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long endOfFilePosition = fileSystem.seek(handle, 0L, 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IFileSystem.SEEK_END); 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileSystem.seek(handle, currentPosition, IFileSystem.SEEK_SET); 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return endOfFilePosition; 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public long transferFrom(ReadableByteChannel src, long position, long count) 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!src.isOpen()) { 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new ClosedChannelException(); 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (position < 0 || count < 0 || position > Integer.MAX_VALUE 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || count > Integer.MAX_VALUE) { 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException(); 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if(position > size()) { 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteBuffer buffer = null; 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-changed 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (src instanceof FileChannel) { 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FileChannel fileSrc = (FileChannel) src; 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long size = fileSrc.size(); 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long filePosition = fileSrc.position(); 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = Math.min(count, size - filePosition); 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer = fileSrc.map(MapMode.READ_ONLY, filePosition, count); 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileSrc.position(filePosition + count); 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer = ByteBuffer.allocateDirect((int) count); 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project src.read(buffer); 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.flip(); 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return write(buffer, position); 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // unmap the buffer 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (buffer != null) { 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // all children of FileChannelImpl currently returns 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // an instance of DirectBuffer from map() method 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((DirectBuffer) buffer).free(); 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-changed 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public long transferTo(long position, long count, WritableByteChannel target) 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!target.isOpen()) { 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new ClosedChannelException(); 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (target instanceof ReadOnlyFileChannel) { 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NonWritableChannelException(); 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (position < 0 || count < 0 || position > Integer.MAX_VALUE 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || count > Integer.MAX_VALUE) { 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException(); 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count == 0 || position >= size()) { 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteBuffer buffer = null; 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = Math.min(count, size() - position); 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (target instanceof SocketChannelImpl) { 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // only socket can be transfered by system call 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return kernelTransfer(handle, ((SocketChannelImpl) target).getFD(), 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project position, count); 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-changed 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer = map(MapMode.READ_ONLY, position, count); 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return target.write(buffer); 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // unmap the buffer 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (buffer != null) { 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // all children of FileChannelImpl currently returns 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // an instance of DirectBuffer from map() method 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((DirectBuffer) buffer).free(); 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-changed 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private long kernelTransfer(int l, FileDescriptor fd, long position, 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long count) throws IOException { 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean completed = false; 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project begin(); 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long ret = fileSystem.transfer(l, fd, position, count); 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project completed = true; 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ret; 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end(completed); 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public FileChannel truncate(long size) throws IOException { 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size < 0) { 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException(); 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size < size()) { 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project synchronized (repositioningLock) { 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long position = position(); 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fileSystem.truncate(handle, size); 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * FIXME: currently the port library always modifies the 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * position to given size. not sure it is a bug or intended 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * behaviour, so I always reset the position to proper value as 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Java Spec. 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project position(position > size ? size : position); 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (non-Javadoc) 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer) 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int write(ByteBuffer buffer, long position) throws IOException { 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null == buffer){ 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException(); 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (position < 0){ 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException(); 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!buffer.hasRemaining()){ 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int bytesWritten = 0; 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project synchronized (repositioningLock) { 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long preWritePosition = position(); 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project position(position); 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesWritten = writeImpl(buffer); 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project position(preWritePosition); 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytesWritten; 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int write(ByteBuffer buffer) throws IOException { 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return writeImpl(buffer); 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int writeImpl(ByteBuffer buffer) throws IOException { 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int bytesWritten; 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean completed = false; 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project synchronized (repositioningLock) { 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (buffer.isDirect()) { 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DirectBuffer directBuffer = (DirectBuffer) buffer; 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int address = directBuffer.getEffectiveAddress().toInt(); 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project begin(); 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesWritten = (int) fileSystem.writeDirect(handle, 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project address, buffer.position(), buffer.remaining()); 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project completed = true; 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end(completed); 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project begin(); 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesWritten = (int) fileSystem.write(handle, buffer 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .array(), buffer.arrayOffset() + buffer.position(), 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.remaining()); 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project completed = true; 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end(completed); 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bytesWritten > 0) { 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer.position(buffer.position() + bytesWritten); 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytesWritten; 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public long write(ByteBuffer[] buffers, int offset, int length) 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws IOException { 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0 || length < 0 || (offset + length) > buffers.length) { 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IndexOutOfBoundsException(); 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project openCheck(); 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = 0; 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = offset; i < offset + length; i++) { 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count += buffers[i].remaining(); 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (0 == count) { 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int[] handles = new int[length]; 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int[] offsets = new int[length]; 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int[] lengths = new int[length]; 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-changed 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // list of allocated direct ByteBuffers to prevent them from being GC-ed 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DirectBuffer[] allocatedBufs = new DirectBuffer[length]; 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < length; i++) { 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteBuffer buffer = buffers[i + offset]; 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!buffer.isDirect()) { 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteBuffer directBuffer = ByteBuffer.allocateDirect(buffer 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .remaining()); 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project directBuffer.put(buffer); 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project directBuffer.flip(); 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffer = directBuffer; 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project allocatedBufs[i] = (DirectBuffer) directBuffer; 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offsets[i] = 0; 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offsets[i] = buffer.position(); 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project allocatedBufs[i] = null; 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handles[i] = ((DirectBuffer) buffer).getEffectiveAddress().toInt(); 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lengths[i] = buffer.remaining(); 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-changed 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long bytesWritten = 0; 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean completed = false; 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project synchronized (repositioningLock) { 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project begin(); 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesWritten = fileSystem.writev(handle, handles, offsets, 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lengths, length); 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project completed = true; 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end(completed); 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-added 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // free temporary direct buffers 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < length; ++i) { 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (allocatedBufs[i] != null) { 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project allocatedBufs[i].free(); 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-added 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long bytesRemaining = bytesWritten; 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = offset; i < length + offset; i++) { 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bytesRemaining > buffers[i].remaining()) { 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int pos = buffers[i].limit(); 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffers[i].position(pos); 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytesRemaining -= buffers[i].remaining(); 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int pos = buffers[i].position() + (int) bytesRemaining; 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buffers[i].position(pos); 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytesWritten; 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getHandle(){ 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return handle; 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 661