AsyncChannel.java(WiFiDirect的channel相关)

本文概述了AI音视频处理领域的关键技术,包括视频分割、语义识别、自动驾驶、AR、SLAM等,并探讨了其在实际应用中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/***
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;


import java.util.Stack;


/***
 * <p>An asynchronous channel between two handlers.</p>
 *
 * <p>The handlers maybe in the same process or in another process. There
 * are two protocol styles that can be used with an AysncChannel. The
 * first is a simple request/reply protocol where the server does
 * not need to know which client is issuing the request.</p>
 *
 * <p>In a simple request/reply protocol the client/source sends requests to the
 * server/destination. And the server uses the replyToMessage methods.
 * In this usage model there is no need for the destination to
 * use the connect methods. The typical sequence of operations is:</p>
 *<ol>
 *   <li>Client calls AsyncChannel#connectSync or Asynchronously:</li>
 *      <ol>For an asynchronous half connection client calls AsyncChannel#connect.</ol>
 *          <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
 *      </ol>
 *   <li><code>comm-loop:</code></li>
 *   <li>Client calls AsyncChannel#sendMessage</li>
 *   <li>Server processes messages and optionally replies using AsyncChannel#replyToMessage
 *   <li>Loop to <code>comm-loop</code> until done</li>
 *   <li>When done Client calls {@link AsyncChannel#disconnect}</li>
 *   <li>Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li>
 *</ol>
 *<br/>
 * <p>A second usage model is where the server/destination needs to know
 * which client it's connected too. For example the server needs to
 * send unsolicited messages back to the client. Or the server keeps
 * different state for each client. In this model the server will also
 * use the connect methods. The typical sequence of operation is:</p>
 *<ol>
 *   <li>Client calls AsyncChannel#fullyConnectSync or Asynchronously:<li>
 *      <ol>For an asynchronous full connection it calls AsyncChannel#connect</li>
 *          <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
 *          <li>Client calls AsyncChannel#sendMessage(CMD_CHANNEL_FULL_CONNECTION)</li>
 *      </ol>
 *   <li>Server receives CMD_CHANNEL_FULL_CONNECTION</li>
 *   <li>Server calls AsyncChannel#connected</li>
 *   <li>Server sends AsyncChannel#sendMessage(CMD_CHANNEL_FULLY_CONNECTED)</li>
 *   <li>Client receives CMD_CHANNEL_FULLY_CONNECTED</li>
 *   <li><code>comm-loop:</code></li>
 *   <li>Client/Server uses AsyncChannel#sendMessage/replyToMessage
 *       to communicate and perform work</li>
 *   <li>Loop to <code>comm-loop</code> until done</li>
 *   <li>When done Client/Server calls {@link AsyncChannel#disconnect}</li>
 *   <li>Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li>
 *</ol>
 *
 * TODO: Consider simplifying where we have connect and fullyConnect with only one response
 * message RSP_CHANNEL_CONNECT instead of two, CMD_CHANNEL_HALF_CONNECTED and
 * CMD_CHANNEL_FULLY_CONNECTED. We'd also change CMD_CHANNEL_FULL_CONNECTION to REQ_CHANNEL_CONNECT.
 */
public class AsyncChannel {
    /*** Log tag */
    private static final String TAG = "AsyncChannel";


    /*** Enable to turn on debugging */
    private static final boolean DBG = false;


    private static final int BASE = Protocol.BASE_SYSTEM_ASYNC_CHANNEL;


    /***
     * Command sent when the channel is half connected. Half connected
     * means that the channel can be used to send commends to the destination
     * but the destination is unaware that the channel exists. The first
     * command sent to the destination is typically CMD_CHANNEL_FULL_CONNECTION if
     * it is desired to establish a long term connection, but any command maybe
     * sent.
     *
     * msg.arg1 == 0 : STATUS_SUCCESSFUL
     *             1 : STATUS_BINDING_UNSUCCESSFUL
     * msg.obj  == the AsyncChannel
     * msg.replyTo == dstMessenger if successful
     */
    public static final int CMD_CHANNEL_HALF_CONNECTED = BASE + 0;


    /***
     * Command typically sent when after receiving the CMD_CHANNEL_HALF_CONNECTED.
     * This is used to initiate a long term connection with the destination and
     * typically the destination will reply with CMD_CHANNEL_FULLY_CONNECTED.
     *
     * msg.replyTo = srcMessenger.
     */
    public static final int CMD_CHANNEL_FULL_CONNECTION = BASE + 1;


    /***
     * Command typically sent after the destination receives a CMD_CHANNEL_FULL_CONNECTION.
     * This signifies the acceptance or rejection of the channel by the sender.
     *
     * msg.arg1 == 0 : Accept connection
     *               : All other values signify the destination rejected the connection
     *                 and {@link AsyncChannel#disconnect} would typically be called.
     */
    public static final int CMD_CHANNEL_FULLY_CONNECTED = BASE + 2;


    /***
     * Command sent when one side or the other wishes to disconnect. The sender
     * may or may not be able to receive a reply depending upon the protocol and
     * the state of the connection. The receiver should call {@link AsyncChannel#disconnect}
     * to close its side of the channel and it will receive a CMD_CHANNEL_DISCONNECTED
     * when the channel is closed.
     *
     * msg.replyTo = messenger that is disconnecting
     */
    public static final int CMD_CHANNEL_DISCONNECT = BASE + 3;


    /***
     * Command sent when the channel becomes disconnected. This is sent when the
     * channel is forcibly disconnected by the system or as a reply to CMD_CHANNEL_DISCONNECT.
     *
     * msg.arg1 == 0 : STATUS_SUCCESSFUL
     *             1 : STATUS_BINDING_UNSUCCESSFUL
     *             2 : STATUS_SEND_UNSUCCESSFUL
     *               : All other values signify failure and the channel state is indeterminate
     * msg.obj  == the AsyncChannel
     * msg.replyTo = messenger disconnecting or null if it was never connected.
     */
    public static final int CMD_CHANNEL_DISCONNECTED = BASE + 4;


    /*** Successful status always 0, !0 is an unsuccessful status */
    public static final int STATUS_SUCCESSFUL = 0;


    /*** Error attempting to bind on a connect */
    public static final int STATUS_BINDING_UNSUCCESSFUL = 1;


    /*** Error attempting to send a message */
    public static final int STATUS_SEND_UNSUCCESSFUL = 2;


    /*** CMD_FULLY_CONNECTED refused because a connection already exists*/
    public static final int STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED = 3;


    /*** Service connection */
    private AsyncChannelConnection mConnection;


    /*** Context for source */
    private Context mSrcContext;


    /*** Handler for source */
    private Handler mSrcHandler;


    /*** Messenger for source */
    private Messenger mSrcMessenger;


    /*** Messenger for destination */
    private Messenger mDstMessenger;


    /***
     * AsyncChannel constructor
     */
    public AsyncChannel() {
    }


    /***
     * Connect handler to named package/class synchronously.
     *
     * @param srcContext is the context of the source
     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
     *            messages
     * @param dstPackageName is the destination package name
     * @param dstClassName is the fully qualified class name (i.e. contains
     *            package name)
     *
     * @return STATUS_SUCCESSFUL on success any other value is an error.
     */
    public int connectSrcHandlerToPackageSync(
            Context srcContext, Handler srcHandler, String dstPackageName, String dstClassName) {
        if (DBG) log("connect srcHandler to dst Package & class E");


        mConnection = new AsyncChannelConnection();


        /** Initialize the source information */
        mSrcContext = srcContext;
        mSrcHandler = srcHandler;
        mSrcMessenger = new Messenger(srcHandler);


        /**
         * Initialize destination information to null they will
         * be initialized when the AsyncChannelConnection#onServiceConnected
         * is called
         */
        mDstMessenger = null;


        /** Send intent to create the connection */
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setClassName(dstPackageName, dstClassName);
        boolean result = srcContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        if (DBG) log("connect srcHandler to dst Package & class X result=" + result);
        return result ? STATUS_SUCCESSFUL : STATUS_BINDING_UNSUCCESSFUL;
    }


    /***
     * Connect a handler to Messenger synchronously.
     *
     * @param srcContext is the context of the source
     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
     *            messages
     * @param dstMessenger is the hander to send messages to.
     *
     * @return STATUS_SUCCESSFUL on success any other value is an error.
     */
    public int connectSync(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
        if (DBG) log("halfConnectSync srcHandler to the dstMessenger  E");


        // We are connected
        connected(srcContext, srcHandler, dstMessenger);


        if (DBG) log("halfConnectSync srcHandler to the dstMessenger X");
        return STATUS_SUCCESSFUL;
    }


    /***
     * connect two local Handlers synchronously.
     *
     * @param srcContext is the context of the source
     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
     *            messages
     * @param dstHandler is the hander to send messages to.
     *
     * @return STATUS_SUCCESSFUL on success any other value is an error.
     */
    public int connectSync(Context srcContext, Handler srcHandler, Handler dstHandler) {
        return connectSync(srcContext, srcHandler, new Messenger(dstHandler));
    }


    /***
     * Fully connect two local Handlers synchronously.
     *
     * @param srcContext is the context of the source
     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
     *            messages
     * @param dstHandler is the hander to send messages to.
     *
     * @return STATUS_SUCCESSFUL on success any other value is an error.
     */
    public int fullyConnectSync(Context srcContext, Handler srcHandler, Handler dstHandler) {
        int status = connectSync(srcContext, srcHandler, dstHandler);
        if (status == STATUS_SUCCESSFUL) {
            Message response = sendMessageSynchronously(CMD_CHANNEL_FULL_CONNECTION);
            status = response.arg1;
        }
        return status;
    }


    /***
     * Connect handler to named package/class.
     *
     * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
     *      msg.arg1 = status
     *      msg.obj = the AsyncChannel
     *
     * @param srcContext is the context of the source
     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
     *            messages
     * @param dstPackageName is the destination package name
     * @param dstClassName is the fully qualified class name (i.e. contains
     *            package name)
     */
    public void connect(Context srcContext, Handler srcHandler, String dstPackageName,
            String dstClassName) {
        if (DBG) log("connect srcHandler to dst Package & class E");


        final class ConnectAsync implements Runnable {
            Context mSrcCtx;
            Handler mSrcHdlr;
            String mDstPackageName;
            String mDstClassName;


            ConnectAsync(Context srcContext, Handler srcHandler, String dstPackageName,
                    String dstClassName) {
                mSrcCtx = srcContext;
                mSrcHdlr = srcHandler;
                mDstPackageName = dstPackageName;
                mDstClassName = dstClassName;
            }


            @Override
            public void run() {
                int result = connectSrcHandlerToPackageSync(mSrcCtx, mSrcHdlr, mDstPackageName,
                        mDstClassName);
                replyHalfConnected(result);
            }
        }


        ConnectAsync ca = new ConnectAsync(srcContext, srcHandler, dstPackageName, dstClassName);
        new Thread(ca).start();


        if (DBG) log("connect srcHandler to dst Package & class X");
    }


    /***
     * Connect handler to a class
     *
     * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
     *      msg.arg1 = status
     *      msg.obj = the AsyncChannel
     *
     * @param srcContext
     * @param srcHandler
     * @param klass is the class to send messages to.
     */
    public void connect(Context srcContext, Handler srcHandler, Class<?> klass) {
        connect(srcContext, srcHandler, klass.getPackage().getName(), klass.getName());
    }


    /***
     * Connect handler and messenger.
     *
     * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
     *      msg.arg1 = status
     *      msg.obj = the AsyncChannel
     *
     * @param srcContext
     * @param srcHandler
     * @param dstMessenger
     */
    public void connect(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
        if (DBG) log("connect srcHandler to the dstMessenger  E");


        // We are connected
        connected(srcContext, srcHandler, dstMessenger);


        // Tell source we are half connected
        replyHalfConnected(STATUS_SUCCESSFUL);


        if (DBG) log("connect srcHandler to the dstMessenger X");
    }


    /***
     * Connect handler to messenger. This method is typically called
     * when a server receives a CMD_CHANNEL_FULL_CONNECTION request
     * and initializes the internal instance variables to allow communication
     * with the dstMessenger.
     *
     * @param srcContext
     * @param srcHandler
     * @param dstMessenger
     */
    public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
        if (DBG) log("connected srcHandler to the dstMessenger  E");


        // Initialize source fields
        mSrcContext = srcContext;
        mSrcHandler = srcHandler;
        mSrcMessenger = new Messenger(mSrcHandler);


        // Initialize destination fields
        mDstMessenger = dstMessenger;


        if (DBG) log("connected srcHandler to the dstMessenger X");
    }


    /***
     * Connect two local Handlers.
     *
     * @param srcContext is the context of the source
     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
     *            messages
     * @param dstHandler is the hander to send messages to.
     */
    public void connect(Context srcContext, Handler srcHandler, Handler dstHandler) {
        connect(srcContext, srcHandler, new Messenger(dstHandler));
    }


    /***
     * Connect service and messenger.
     *
     * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcAsyncService when complete.
     *      msg.arg1 = status
     *      msg.obj = the AsyncChannel
     *
     * @param srcAsyncService
     * @param dstMessenger
     */
    public void connect(AsyncService srcAsyncService, Messenger dstMessenger) {
        connect(srcAsyncService, srcAsyncService.getHandler(), dstMessenger);
    }


    /***
     * To close the connection call when handler receives CMD_CHANNEL_DISCONNECTED
     */
    public void disconnected() {
        mSrcContext = null;
        mSrcHandler = null;
        mSrcMessenger = null;
        mDstMessenger = null;
        mConnection = null;
    }


    /***
     * Disconnect
     */
    public void disconnect() {
        if ((mConnection != null) && (mSrcContext != null)) {
            mSrcContext.unbindService(mConnection);
        }
        if (mSrcHandler != null) {
            replyDisconnected(STATUS_SUCCESSFUL);
        }
    }


    /***
     * Send a message to the destination handler.
     *
     * @param msg
     */
    public void sendMessage(Message msg) {
        msg.replyTo = mSrcMessenger;
        try {
            mDstMessenger.send(msg);
        } catch (RemoteException e) {
            replyDisconnected(STATUS_SEND_UNSUCCESSFUL);
        }
    }


    /***
     * Send a message to the destination handler
     *
     * @param what
     */
    public void sendMessage(int what) {
        Message msg = Message.obtain();
        msg.what = what;
        sendMessage(msg);
    }


    /***
     * Send a message to the destination handler
     *
     * @param what
     * @param arg1
     */
    public void sendMessage(int what, int arg1) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.arg1 = arg1;
        sendMessage(msg);
    }


    /***
     * Send a message to the destination handler
     *
     * @param what
     * @param arg1
     * @param arg2
     */
    public void sendMessage(int what, int arg1, int arg2) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        sendMessage(msg);
    }


    /***
     * Send a message to the destination handler
     *
     * @param what
     * @param arg1
     * @param arg2
     * @param obj
     */
    public void sendMessage(int what, int arg1, int arg2, Object obj) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        msg.obj = obj;
        sendMessage(msg);
    }


    /***
     * Send a message to the destination handler
     *
     * @param what
     * @param obj
     */
    public void sendMessage(int what, Object obj) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        sendMessage(msg);
    }


    /***
     * Reply to srcMsg sending dstMsg
     *
     * @param srcMsg
     * @param dstMsg
     */
    public void replyToMessage(Message srcMsg, Message dstMsg) {
        try {
            dstMsg.replyTo = mSrcMessenger;
            srcMsg.replyTo.send(dstMsg);
        } catch (RemoteException e) {
            log("TODO: handle replyToMessage RemoteException" + e);
            e.printStackTrace();
        }
    }


    /***
     * Reply to srcMsg
     *
     * @param srcMsg
     * @param what
     */
    public void replyToMessage(Message srcMsg, int what) {
        Message msg = Message.obtain();
        msg.what = what;
        replyToMessage(srcMsg, msg);
    }


    /***
     * Reply to srcMsg
     *
     * @param srcMsg
     * @param what
     * @param arg1
     */
    public void replyToMessage(Message srcMsg, int what, int arg1) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.arg1 = arg1;
        replyToMessage(srcMsg, msg);
    }


    /***
     * Reply to srcMsg
     *
     * @param srcMsg
     * @param what
     * @param arg1
     * @param arg2
     */
    public void replyToMessage(Message srcMsg, int what, int arg1, int arg2) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        replyToMessage(srcMsg, msg);
    }


    /***
     * Reply to srcMsg
     *
     * @param srcMsg
     * @param what
     * @param arg1
     * @param arg2
     * @param obj
     */
    public void replyToMessage(Message srcMsg, int what, int arg1, int arg2, Object obj) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        msg.obj = obj;
        replyToMessage(srcMsg, msg);
    }


    /***
     * Reply to srcMsg
     *
     * @param srcMsg
     * @param what
     * @param obj
     */
    public void replyToMessage(Message srcMsg, int what, Object obj) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        replyToMessage(srcMsg, msg);
    }


    /***
     * Send the Message synchronously.
     *
     * @param msg to send
     * @return reply message or null if an error.
     */
    public Message sendMessageSynchronously(Message msg) {
        Message resultMsg = SyncMessenger.sendMessageSynchronously(mDstMessenger, msg);
        return resultMsg;
    }


    /***
     * Send the Message synchronously.
     *
     * @param what
     * @return reply message or null if an error.
     */
    public Message sendMessageSynchronously(int what) {
        Message msg = Message.obtain();
        msg.what = what;
        Message resultMsg = sendMessageSynchronously(msg);
        return resultMsg;
    }


    /***
     * Send the Message synchronously.
     *
     * @param what
     * @param arg1
     * @return reply message or null if an error.
     */
    public Message sendMessageSynchronously(int what, int arg1) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.arg1 = arg1;
        Message resultMsg = sendMessageSynchronously(msg);
        return resultMsg;
    }


    /***
     * Send the Message synchronously.
     *
     * @param what
     * @param arg1
     * @param arg2
     * @return reply message or null if an error.
     */
    public Message sendMessageSynchronously(int what, int arg1, int arg2) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        Message resultMsg = sendMessageSynchronously(msg);
        return resultMsg;
    }


    /***
     * Send the Message synchronously.
     *
     * @param what
     * @param arg1
     * @param arg2
     * @param obj
     * @return reply message or null if an error.
     */
    public Message sendMessageSynchronously(int what, int arg1, int arg2, Object obj) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        msg.obj = obj;
        Message resultMsg = sendMessageSynchronously(msg);
        return resultMsg;
    }


    /***
     * Send the Message synchronously.
     *
     * @param what
     * @param obj
     * @return reply message or null if an error.
     */
    public Message sendMessageSynchronously(int what, Object obj) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        Message resultMsg = sendMessageSynchronously(msg);
        return resultMsg;
    }


    /***
     * Helper class to send messages synchronously
     */
    private static class SyncMessenger {
        /*** A stack of SyncMessengers */
        private static Stack<SyncMessenger> sStack = new Stack<SyncMessenger>();
        /*** A number of SyncMessengers created */
        private static int sCount = 0;
        /*** The handler thread */
        private HandlerThread mHandlerThread;
        /*** The handler that will receive the result */
        private SyncHandler mHandler;
        /*** The messenger used to send the message */
        private Messenger mMessenger;


        /*** private constructor */
        private SyncMessenger() {
        }


        /*** Synchronous Handler class */
        private class SyncHandler extends Handler {
            /*** The object used to wait/notify */
            private Object mLockObject = new Object();
            /*** The resulting message */
            private Message mResultMsg;


            /*** Constructor */
            private SyncHandler(Looper looper) {
                super(looper);
            }


            /*** Handle of the reply message */
            @Override
            public void handleMessage(Message msg) {
                mResultMsg = Message.obtain();
                mResultMsg.copyFrom(msg);
                synchronized(mLockObject) {
                    mLockObject.notify();
                }
            }
        }


        /***
         * @return the SyncMessenger
         */
        private static SyncMessenger obtain() {
            SyncMessenger sm;
            synchronized (sStack) {
                if (sStack.isEmpty()) {
                    sm = new SyncMessenger();
                    sm.mHandlerThread = new HandlerThread("SyncHandler-" + sCount++);
                    sm.mHandlerThread.start();
                    sm.mHandler = sm.new SyncHandler(sm.mHandlerThread.getLooper());
                    sm.mMessenger = new Messenger(sm.mHandler);
                } else {
                    sm = sStack.pop();
                }
            }
            return sm;
        }


        /***
         * Recycle this object
         */
        private void recycle() {
            synchronized (sStack) {
                sStack.push(this);
            }
        }


        /***
         * Send a message synchronously.
         *
         * @param msg to send
         * @return result message or null if an error occurs
         */
        private static Message sendMessageSynchronously(Messenger dstMessenger, Message msg) {
            SyncMessenger sm = SyncMessenger.obtain();
            try {
                if (dstMessenger != null && msg != null) {
                    msg.replyTo = sm.mMessenger;
                    synchronized (sm.mHandler.mLockObject) {
                        dstMessenger.send(msg);
                        sm.mHandler.mLockObject.wait();
                    }
                } else {
                    sm.mHandler.mResultMsg = null;
                }
            } catch (InterruptedException e) {
                sm.mHandler.mResultMsg = null;
            } catch (RemoteException e) {
                sm.mHandler.mResultMsg = null;
            }
            Message resultMsg = sm.mHandler.mResultMsg;
            sm.recycle();
            return resultMsg;
        }
    }


    /***
     * Reply to the src handler that we're half connected.
     * see: CMD_CHANNEL_HALF_CONNECTED for message contents
     *
     * @param status to be stored in msg.arg1
     */
    private void replyHalfConnected(int status) {
        Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_HALF_CONNECTED);
        msg.arg1 = status;
        msg.obj = this;
        msg.replyTo = mDstMessenger;
        mSrcHandler.sendMessage(msg);
    }


    /***
     * Reply to the src handler that we are disconnected
     * see: CMD_CHANNEL_DISCONNECTED for message contents
     *
     * @param status to be stored in msg.arg1
     */
    private void replyDisconnected(int status) {
        Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED);
        msg.arg1 = status;
        msg.obj = this;
        msg.replyTo = mDstMessenger;
        mSrcHandler.sendMessage(msg);
    }




    /***
     * ServiceConnection to receive call backs.
     */
    class AsyncChannelConnection implements ServiceConnection {
        AsyncChannelConnection() {
        }


        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            mDstMessenger = new Messenger(service);
            replyHalfConnected(STATUS_SUCCESSFUL);
        }


        @Override
        public void onServiceDisconnected(ComponentName className) {
            replyDisconnected(STATUS_SUCCESSFUL);
        }
    }


    /***
     * Log the string.
     *
     * @param s
     */
    private static void log(String s) {
        Slog.d(TAG, s);
    }
}

1. 用户与权限管理模块 角色管理: 学生:查看实验室信息、预约设备、提交耗材申请、参与安全考核 教师:管理课题组预约、审批学生耗材申请、查看本课题组使用记录 管理员:设备全生命周期管理、审核预约、耗材采购与分发、安全检查 用户操作: 登录认证:统一身份认证(对接学号 / 工号系统,模拟实现),支持密码重置 信息管理:学生 / 教师维护个人信息(联系方式、所属院系),管理员管理所有用户 权限控制:不同角色仅可见对应功能(如学生不可删除设备信息) 2. 实验室与设备管理模块 实验室信息管理: 基础信息:实验室编号、名称、位置、容纳人数、开放时间、负责人 功能分类:按学科(计算机实验室 / 电子实验室 / 化学实验室)标记,关联可开展实验类型 状态展示:实时显示当前使用人数、设备运行状态(正常 / 故障) 设备管理: 设备档案:名称、型号、规格、购置日期、单价、生产厂家、存放位置、责任人 全生命周期管理: 入库登记:管理员录入新设备信息,生成唯一资产编号 维护记录:记录维修、校准、保养信息(时间、内容、执行人) 报废处理:登记报废原因、时间,更新设备状态为 "已报废" 设备查询:支持按名称、型号、状态多条件检索,显示设备当前可用情况 3. 预约与使用模块 预约管理: 预约规则:学生可预约未来 7 天内的设备 / 实验室,单次最长 4 小时(可设置) 预约流程:选择实验室→选择设备→选择时间段→提交申请(需填写实验目的) 审核机制:普通实验自动通过,高危实验(如化学实验)需教师审核 使用记录: 签到 / 签退:到达实验室后扫码签到,离开时签退,系统自动记录实际使用时长 使用登记:填写实验内容、设备运行情况(正常 / 异常),异常情况需详细描述 违规管理:迟到 15 分钟自动取消预约,多次违规限制预约权限 4. 耗材与安全管理模块 耗材管理: 耗材档案:名称、规格、数量、存放位置、
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值