summaryrefslogtreecommitdiff
path: root/core/java/com/android/internal/os/SomeArgs.java
blob: b12df6ed36ca35587f6e7c2b2c7491641453199f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * Copyright (C) 2012 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.
 */

package com.android.internal.os;

import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;

/**
 * Helper class for passing more arguments though a message
 * and avoiding allocation of a custom class for wrapping the
 * arguments. This class maintains a pool of instances and
 * it is responsibility of the client to recycle and instance
 * once it is no longer used.
 */
public final class SomeArgs {

    private static final int MAX_POOL_SIZE = 10;

    private static SomeArgs sPool;
    private static int sPoolSize;
    private static Object sPoolLock = new Object();

    private SomeArgs mNext;

    private boolean mInPool;

    static final int WAIT_NONE = 0;
    static final int WAIT_WAITING = 1;
    static final int WAIT_FINISHED = 2;
    int mWaitState = WAIT_NONE;

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public Object arg1;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public Object arg2;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public Object arg3;
    public Object arg4;
    public Object arg5;
    public Object arg6;
    public Object arg7;
    public int argi1;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public int argi2;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public int argi3;
    public int argi4;
    public int argi5;
    public int argi6;
    public long argl1;
    public long argl2;

    private SomeArgs() {
        /* do nothing - reduce visibility */
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public static SomeArgs obtain() {
        synchronized (sPoolLock) {
            if (sPoolSize > 0) {
                SomeArgs args = sPool;
                sPool = sPool.mNext;
                args.mNext = null;
                args.mInPool = false;
                sPoolSize--;
                return args;
            } else {
                return new SomeArgs();
            }
        }
    }

    public void complete() {
        synchronized (this) {
            if (mWaitState != WAIT_WAITING) {
                throw new IllegalStateException("Not waiting");
            }
            mWaitState = WAIT_FINISHED;
            notifyAll();
        }
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public void recycle() {
        if (mInPool) {
            throw new IllegalStateException("Already recycled.");
        }
        if (mWaitState != WAIT_NONE) {
            return;
        }
        synchronized (sPoolLock) {
            clear();
            if (sPoolSize < MAX_POOL_SIZE) {
                mNext = sPool;
                mInPool = true;
                sPool = this;
                sPoolSize++;
            }
        }
    }

    private void clear() {
        arg1 = null;
        arg2 = null;
        arg3 = null;
        arg4 = null;
        arg5 = null;
        arg6 = null;
        arg7 = null;
        argi1 = 0;
        argi2 = 0;
        argi3 = 0;
        argi4 = 0;
        argi5 = 0;
        argi6 = 0;
        argl1 = 0;
        argl2 = 0;
    }
}