Android Open Source - android-sqlite-server Abstract Binder Client






From Project

Back to project page android-sqlite-server.

License

The source code is released under:

Apache License

If you think the Android project android-sqlite-server listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.devtcg.sqliteserver.impl.binder;
/*from w ww.j  av  a  2 s  .c om*/
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import org.devtcg.sqliteserver.SQLiteServerConnection;
import org.devtcg.sqliteserver.exception.SQLiteServerException;

import static android.os.IBinder.DeathRecipient;
import static org.devtcg.sqliteserver.impl.binder.protocol.AcquireCommand.AcquireMessage;
import static org.devtcg.sqliteserver.impl.binder.protocol.BeginTransactionCommand.BeginTransactionMessage;
import static org.devtcg.sqliteserver.impl.binder.protocol.DeleteCommand.DeleteMessage;
import static org.devtcg.sqliteserver.impl.binder.protocol.EndTransactionCommand.EndTransactionMessage;
import static org.devtcg.sqliteserver.impl.binder.protocol.ExecSQLCommand.ExecSQLMessage;
import static org.devtcg.sqliteserver.impl.binder.protocol.InsertCommand.InsertMessage;
import static org.devtcg.sqliteserver.impl.binder.protocol.RawQueryCommand.RawQueryMessage;
import static org.devtcg.sqliteserver.impl.binder.protocol.ReleaseCommand.ReleaseMessage;
import static org.devtcg.sqliteserver.impl.binder.protocol.SetTransactionSuccessfulCommand.SetTransactionSuccessfulMessage;
import static org.devtcg.sqliteserver.impl.binder.protocol.UpdateCommand.UpdateMessage;

/**
 * Client counterpart to {@link ServerImpl} that takes client requests, packages them up in a
 * generic {@link Bundle} and sends them along to the server implementation.
 */
public abstract class AbstractBinderClient implements SQLiteServerConnection, ClientTransactor {
    private final String mTag = getClass().getSimpleName();

    private BinderHandle mClientHandle;
    private BinderHandle mServerHandle;

    private DeathRecipient mServerDiedHandler;

    private boolean mClosed;
    private volatile boolean mDeadServer;

    @Override
    public BinderHandle getClientHandle() {
        if (mClientHandle == null) {
            mClientHandle = new BinderHandle();
        }
        return mClientHandle;
    }

    public void acquire() throws SQLiteServerProtocolException {
        AcquireMessage message = new AcquireMessage(this);
        message.transact();
        mServerHandle = message.getServerHandle();
        try {
            mServerDiedHandler = new ServerDiedHandler(mServerHandle);
            mServerHandle.asBinder().linkToDeath(mServerDiedHandler, 0);
        } catch (RemoteException e) {
            throw new SQLiteServerProtocolException("Server is not supposed to die!", e);
        }
    }

    public void release() throws SQLiteServerProtocolException {
        if (mServerHandle != null) {
            mServerHandle.asBinder().unlinkToDeath(mServerDiedHandler, 0);
            new ReleaseMessage(this).transact();
        }
    }

    @Override
    public void close() {
        try {
            if (!mDeadServer) {
                release();
            }
        } catch (SQLiteServerProtocolException e) {
            // Not much we can do, but this may also not be harmless so we'll log just in case
            Log.i(mTag, "Failed to release connection with the server, ignoring...");
        }
        mClosed = true;
    }

    private void checkReady() {
        if (mClosed) {
            throw new IllegalStateException("Illegal to access this connection after it has " +
                    "been closed");
        }
        if (mDeadServer) {
            // TODO: try to bring it back up and wait for it to become alive again.  This
            // should be possible by just re-acquiring and re-executing the last failed
            // command?
            throw new SQLiteServerException("Server has died unexpectedly; you must open a " +
                    "new connection");
        }
    }

    @Override
    public void beginTransaction() {
        checkReady();
        new BeginTransactionMessage(this).transact();
    }

    @Override
    public void setTransactionSuccessful() {
        checkReady();
        new SetTransactionSuccessfulMessage(this).transact();
    }

    @Override
    public void endTransaction() {
        checkReady();
        new EndTransactionMessage(this).transact();
    }

    @Override
    public Cursor rawQuery(String sql, String[] selectionArgs) throws SQLiteException, SQLiteServerException {
        checkReady();
        RawQueryMessage command = new RawQueryMessage(this, sql, selectionArgs);
        command.transact();
        return command.getCursor();
    }

    @Override
    public void execSQL(String sql) {
        checkReady();
        new ExecSQLMessage(this, sql).transact();
    }

    @Override
    public long insert(String table, ContentValues values) {
        checkReady();
        InsertMessage command = new InsertMessage(this, table, values);
        command.transact();
        return command.getInsertId();
    }

    @Override
    public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
        checkReady();
        UpdateMessage command = new UpdateMessage(this, table, values, whereClause, whereArgs);
        command.transact();
        return command.getAffectedRowsCount();
    }

    @Override
    public int delete(String table, String whereClause, String[] whereArgs) {
        checkReady();
        DeleteMessage command = new DeleteMessage(this, table, whereClause, whereArgs);
        command.transact();
        return command.getAffectedRowsCount();
    }

    @Override
    public Bundle transact(Bundle request) {
        if (Looper.getMainLooper() == Looper.myLooper()) {
            throw new IllegalStateException("SQLiteServiceConnection operations are not allowed " +
                    "on the main thread by design");
        }

        request.setClassLoader(getClass().getClassLoader());
        Bundle response = doTransact(request);
        if (response != null) {
            response.setClassLoader(getClass().getClassLoader());
        }
        return response;
    }

    /**
     * Blocking call to the server peer to deliver our request and receive the response.
     *
     * @param request Request encoded as a {@link Bundle}.
     * @return Response encoded as a {@link Bundle}.
     */
    protected abstract Bundle doTransact(Bundle request);

    private class ServerDiedHandler implements DeathRecipient {
        private final BinderHandle mServerHandle;

        public ServerDiedHandler(BinderHandle serverHandle) {
            mServerHandle = serverHandle;
        }

        @Override
        public void binderDied() {
            Log.w(mTag, "Unexpected server death (serverHandle=" + mServerHandle + ")");
            mDeadServer = true;
        }
    }
}




Java Source Code List

aosp.android.database.BulkCursorDescriptor.java
aosp.android.database.BulkCursorNative.java
aosp.android.database.BulkCursorToCursorAdaptor.java
aosp.android.database.CrossProcessCursorWrapper.java
aosp.android.database.CursorToBulkCursorAdaptor.java
aosp.android.database.IBulkCursor.java
aosp.android.database.MoreDatabaseUtils.java
org.devtcg.sqliteserver.SQLiteContentProviderServer.java
org.devtcg.sqliteserver.SQLiteServerConnectionManager.java
org.devtcg.sqliteserver.SQLiteServerConnection.java
org.devtcg.sqliteserver.SQLiteServer.java
org.devtcg.sqliteserver.SQLiteServiceServer.java
org.devtcg.sqliteserver.exception.SQLiteServerException.java
org.devtcg.sqliteserver.impl.ExecutorHelper.java
org.devtcg.sqliteserver.impl.SQLiteExecutor.java
org.devtcg.sqliteserver.impl.ServerImplProvider.java
org.devtcg.sqliteserver.impl.binder.AbstractBinderClient.java
org.devtcg.sqliteserver.impl.binder.BinderHandle.java
org.devtcg.sqliteserver.impl.binder.BundleUtils.java
org.devtcg.sqliteserver.impl.binder.ClientTransactor.java
org.devtcg.sqliteserver.impl.binder.ContentObserverProxy.java
org.devtcg.sqliteserver.impl.binder.ContentProviderClient.java
org.devtcg.sqliteserver.impl.binder.SQLiteServerProtocolException.java
org.devtcg.sqliteserver.impl.binder.ServerImpl.java
org.devtcg.sqliteserver.impl.binder.ServerState.java
org.devtcg.sqliteserver.impl.binder.ServiceClient.java
org.devtcg.sqliteserver.impl.binder.ThreadAffinityExecutor.java
org.devtcg.sqliteserver.impl.binder.protocol.AbstractCommandHandler.java
org.devtcg.sqliteserver.impl.binder.protocol.AbstractCommandMessage.java
org.devtcg.sqliteserver.impl.binder.protocol.AcquireCommand.java
org.devtcg.sqliteserver.impl.binder.protocol.BeginTransactionCommand.java
org.devtcg.sqliteserver.impl.binder.protocol.DeleteCommand.java
org.devtcg.sqliteserver.impl.binder.protocol.EndTransactionCommand.java
org.devtcg.sqliteserver.impl.binder.protocol.ExceptionTransportHelper.java
org.devtcg.sqliteserver.impl.binder.protocol.ExecSQLCommand.java
org.devtcg.sqliteserver.impl.binder.protocol.InsertCommand.java
org.devtcg.sqliteserver.impl.binder.protocol.MethodName.java
org.devtcg.sqliteserver.impl.binder.protocol.RawQueryCommand.java
org.devtcg.sqliteserver.impl.binder.protocol.ReleaseCommand.java
org.devtcg.sqliteserver.impl.binder.protocol.SetTransactionSuccessfulCommand.java
org.devtcg.sqliteserver.impl.binder.protocol.UpdateCommand.java
org.devtcg.sqliteserver.sample.MyActivity.java
org.devtcg.sqliteserver.sample.MyOpenHelper.java
org.devtcg.sqliteserver.sample.TestContentProvider.java
org.devtcg.sqliteserver.sample.TestService.java