1446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian/*
2446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * Copyright (C) 2017 The Android Open Source Project
3446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian *
4446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * Licensed under the Apache License, Version 2.0 (the "License");
5446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * you may not use this file except in compliance with the License.
6446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * You may obtain a copy of the License at
7446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian *
8446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian *      http://www.apache.org/licenses/LICENSE-2.0
9446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian *
10446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * Unless required by applicable law or agreed to in writing, software
11446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * distributed under the License is distributed on an "AS IS" BASIS,
12446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * See the License for the specific language governing permissions and
14446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * limitations under the License.
15446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian */
16446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
17446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianpackage com.android.server.am;
18446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
19446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.annotation.NonNull;
20446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.app.IApplicationThread;
21446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.app.servertransaction.ClientTransaction;
22446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.app.servertransaction.ClientTransactionItem;
23446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.app.servertransaction.ActivityLifecycleItem;
240447068f27f4d8c44052026878740cbcd7d598faAndrii Kulianimport android.os.Binder;
25446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.os.IBinder;
26446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianimport android.os.RemoteException;
27446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
28446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian/**
29446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * Class that is able to combine multiple client lifecycle transition requests and/or callbacks,
30446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * and execute them as a single transaction.
31446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian *
32446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian * @see ClientTransaction
33446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian */
34446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulianclass ClientLifecycleManager {
35446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    // TODO(lifecycler): Implement building transactions or global transaction.
36446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    // TODO(lifecycler): Use object pools for transactions and transaction items.
37446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
38446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
39446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.
40446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param transaction A sequence of client transaction items.
41446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @throws RemoteException
42446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     *
43446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @see ClientTransaction
44446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
45446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
460447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian        final IApplicationThread client = transaction.getClient();
47446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        transaction.schedule();
480447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian        if (!(client instanceof Binder)) {
490447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian            // If client is not an instance of Binder - it's a remote call and at this point it is
500447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian            // safe to recycle the object. All objects used for local calls will be recycled after
510447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian            // the transaction is executed on client in ActivityThread.
520447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian            transaction.recycle();
530447068f27f4d8c44052026878740cbcd7d598faAndrii Kulian        }
54446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
55446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
56446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
57446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Schedule a single lifecycle request or callback to client activity.
58446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param client Target client.
59446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param activityToken Target activity token.
60446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param stateRequest A request to move target activity to a desired lifecycle state.
61446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @throws RemoteException
62446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     *
63446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @see ClientTransactionItem
64446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
65446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
66446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
67446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
68446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian                stateRequest);
69446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        scheduleTransaction(clientTransaction);
70446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
71446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
72446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
73446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Schedule a single callback delivery to client activity.
74446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param client Target client.
75446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param activityToken Target activity token.
76446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param callback A request to deliver a callback.
77446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @throws RemoteException
78446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     *
79446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @see ClientTransactionItem
80446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
81446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
82446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            @NonNull ClientTransactionItem callback) throws RemoteException {
83446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        final ClientTransaction clientTransaction = transactionWithCallback(client, activityToken,
84446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian                callback);
85446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        scheduleTransaction(clientTransaction);
86446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
87446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
88446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
89446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * Schedule a single callback delivery to client application.
90446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param client Target client.
91446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @param callback A request to deliver a callback.
92446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @throws RemoteException
93446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     *
94446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @see ClientTransactionItem
95446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
96446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    void scheduleTransaction(@NonNull IApplicationThread client,
97446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            @NonNull ClientTransactionItem callback) throws RemoteException {
98446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        final ClientTransaction clientTransaction = transactionWithCallback(client,
99446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian                null /* activityToken */, callback);
100446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        scheduleTransaction(clientTransaction);
101446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
102446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
103446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
104446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @return A new instance of {@link ClientTransaction} with a single lifecycle state request.
105446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     *
106446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @see ClientTransaction
107446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @see ClientTransactionItem
108446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
109446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
110446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
1119c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
112446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        clientTransaction.setLifecycleStateRequest(stateRequest);
113446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        return clientTransaction;
114446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
115446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian
116446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    /**
117446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @return A new instance of {@link ClientTransaction} with a single callback invocation.
118446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     *
119446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @see ClientTransaction
120446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     * @see ClientTransactionItem
121446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian     */
122446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    private static ClientTransaction transactionWithCallback(@NonNull IApplicationThread client,
123446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian            IBinder activityToken, @NonNull ClientTransactionItem callback) {
1249c5ea9c153fcc1f0fd2cfd35a77f26bf2849c48eAndrii Kulian        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
125446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        clientTransaction.addCallback(callback);
126446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian        return clientTransaction;
127446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian    }
128446e824e22692ee217b5b15e4f0de6add6e83d2aAndrii Kulian}
129