1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.hardware.camera2.params;
18 
19 import android.hardware.camera2.CaptureResult;
20 import android.hardware.camera2.utils.HashCodeHelpers;
21 
22 import com.android.internal.util.Preconditions;
23 
24 /**
25  * Immutable class to store an
26  * {@link CaptureResult#STATISTICS_OIS_SAMPLES optical image stabilization sample}.
27  */
28 public final class OisSample {
29     /**
30      * Create a new {@link OisSample}.
31      *
32      * <p>{@link OisSample} contains the timestamp and the amount of shifts in x and y direction,
33      * in pixels, of the OIS sample.
34      *
35      * <p>A positive value for a shift in x direction is a shift from left to right in active array
36      * coordinate system. For example, if the optical center is {@code (1000, 500)} in active array
37      * coordinates, a shift of {@code (3, 0)} puts the new optical center at {@code (1003, 500)}.
38      * </p>
39      *
40      * <p>A positive value for a shift in y direction is a shift from top to bottom in active array
41      * coordinate system. For example, if the optical center is {@code (1000, 500)} in active array
42      * coordinates, a shift of {@code (0, 5)} puts the new optical center at {@code (1000, 505)}.
43      * </p>
44      *
45      * <p>xShift and yShift must be finite; NaN and infinity is not allowed.</p>
46      *
47      * @param timestamp timestamp of the OIS sample.
48      * @param xShift shift of the OIS sample in x direction.
49      * @param yShift shift of the OIS sample in y direction.
50      *
51      * @throws IllegalArgumentException if xShift or yShift is not finite
52      */
OisSample(final long timestamp, final float xShift, final float yShift)53     public OisSample(final long timestamp, final float xShift, final float yShift) {
54         mTimestampNs = timestamp;
55         mXShift = Preconditions.checkArgumentFinite(xShift, "xShift must be finite");
56         mYShift = Preconditions.checkArgumentFinite(yShift, "yShift must be finite");
57     }
58 
59     /**
60      * Get the timestamp in nanoseconds.
61      *
62      *<p>The timestamps are in the same timebase as and comparable to
63      *{@link CaptureResult#SENSOR_TIMESTAMP android.sensor.timestamp}.</p>
64      *
65      * @return a long value (guaranteed to be finite)
66      */
getTimestamp()67     public long getTimestamp() {
68         return mTimestampNs;
69     }
70 
71     /**
72      * Get the shift in x direction.
73      *
74      * @return a floating point value (guaranteed to be finite)
75      */
getXshift()76     public float getXshift() {
77         return mXShift;
78     }
79 
80     /**
81      * Get the shift in y direction.
82      *
83      * @return a floating point value (guaranteed to be finite)
84      */
getYshift()85     public float getYshift() {
86         return mYShift;
87     }
88 
89     /**
90      * Check if this {@link OisSample} is equal to another {@link OisSample}.
91      *
92      * <p>Two samples are only equal if and only if each of the OIS information is equal.</p>
93      *
94      * @return {@code true} if the objects were equal, {@code false} otherwise
95      */
96     @Override
equals(final Object obj)97     public boolean equals(final Object obj) {
98         if (obj == null) {
99             return false;
100         } else if (this == obj) {
101             return true;
102         } else if (obj instanceof OisSample) {
103             final OisSample other = (OisSample) obj;
104             return mTimestampNs == other.mTimestampNs
105                     && mXShift == other.mXShift
106                     && mYShift == other.mYShift;
107         }
108         return false;
109     }
110 
111     /**
112      * {@inheritDoc}
113      */
114     @Override
hashCode()115     public int hashCode() {
116         int timestampHash = HashCodeHelpers.hashCode(mTimestampNs);
117         return HashCodeHelpers.hashCode(mXShift, mYShift, timestampHash);
118     }
119 
120     /**
121      * Return the OisSample as a string representation.
122      *
123      * <p> {@code "OisSample{timestamp:%l, shift_x:%f, shift_y:%f}"} represents the OIS sample's
124      * timestamp, shift in x direction, and shift in y direction.</p>
125      *
126      * @return string representation of {@link OisSample}
127      */
128     @Override
toString()129     public String toString() {
130         return String.format("OisSample{timestamp:%d, shift_x:%f, shift_y:%f}", mTimestampNs,
131                 mXShift, mYShift);
132     }
133 
134     private final long mTimestampNs;
135     private final float mXShift;
136     private final float mYShift;
137 }
138