diff options
-rw-r--r-- | core/java/com/android/internal/os/ZygoteInit.java | 5 | ||||
-rw-r--r-- | include/surfaceflinger/IGraphicBufferAlloc.h | 3 | ||||
-rw-r--r-- | libs/gui/IGraphicBufferAlloc.cpp | 15 | ||||
-rw-r--r-- | libs/gui/SurfaceTexture.cpp | 15 | ||||
-rw-r--r-- | policy/src/com/android/internal/policy/impl/KeyguardViewManager.java | 3 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 24 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 2 | ||||
-rw-r--r-- | telephony/java/com/android/internal/telephony/SemcRIL.java | 501 |
8 files changed, 559 insertions, 9 deletions
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 9c45dc6..51eb7ea 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -66,7 +66,10 @@ public class ZygoteInit { private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030; /** when preloading, GC after allocating this many bytes */ - private static final int PRELOAD_GC_THRESHOLD = 50000; + private static final String heapgrowthlimit = + SystemProperties.get("dalvik.vm.heapgrowthlimit", "16m"); + private static final int PRELOAD_GC_THRESHOLD = Integer.parseInt( + heapgrowthlimit.substring(0, heapgrowthlimit.length()-1))*1024*1024/2; public static final String USAGE_STRING = " <\"start-system-server\"|\"\" for startSystemServer>"; diff --git a/include/surfaceflinger/IGraphicBufferAlloc.h b/include/surfaceflinger/IGraphicBufferAlloc.h index 43c150b..7eadfd8 100644 --- a/include/surfaceflinger/IGraphicBufferAlloc.h +++ b/include/surfaceflinger/IGraphicBufferAlloc.h @@ -45,6 +45,9 @@ public: * the server is referencing, then all buffers are freed. */ virtual void freeAllGraphicBuffersExcept(int bufIndex) = 0; + + /* Free the GraphicBuffer at the specified index */ + virtual void freeGraphicBufferAtIndex(int bufIndex) = 0; #endif }; diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp index 596a80c..d4d579f 100644 --- a/libs/gui/IGraphicBufferAlloc.cpp +++ b/libs/gui/IGraphicBufferAlloc.cpp @@ -34,6 +34,7 @@ enum { CREATE_GRAPHIC_BUFFER = IBinder::FIRST_CALL_TRANSACTION, #ifdef QCOM_HARDWARE FREE_ALL_GRAPHIC_BUFFERS_EXCEPT, + FREE_GRAPHIC_BUFFER_AT_INDEX, #endif }; @@ -75,6 +76,14 @@ public: data.writeInt32(bufIdx); remote()->transact(FREE_ALL_GRAPHIC_BUFFERS_EXCEPT, data, &reply); } + + virtual void freeGraphicBufferAtIndex(int bufIdx) { + Parcel data, reply; + data.writeInterfaceToken( + IGraphicBufferAlloc::getInterfaceDescriptor()); + data.writeInt32(bufIdx); + remote()->transact(FREE_GRAPHIC_BUFFER_AT_INDEX, data, &reply); + } #endif }; @@ -128,6 +137,12 @@ status_t BnGraphicBufferAlloc::onTransact( freeAllGraphicBuffersExcept(bufIdx); return NO_ERROR; } break; + case FREE_GRAPHIC_BUFFER_AT_INDEX: { + CHECK_INTERFACE(IGraphicBufferAlloc, data, reply); + int bufIdx = data.readInt32(); + freeGraphicBufferAtIndex(bufIdx); + return NO_ERROR; + } break; #endif default: return BBinder::onTransact(code, data, reply, flags); diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp index d20ad17..982713a 100644 --- a/libs/gui/SurfaceTexture.cpp +++ b/libs/gui/SurfaceTexture.cpp @@ -506,6 +506,11 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, #endif ((uint32_t(buffer->usage) & usage) != usage)) { +#ifdef QCOM_HARDWARE + if (buffer != NULL) { + mGraphicBufferAlloc->freeGraphicBufferAtIndex(buf); + } +#endif usage |= GraphicBuffer::USAGE_HW_TEXTURE; status_t error; sp<GraphicBuffer> graphicBuffer( @@ -802,16 +807,14 @@ status_t SurfaceTexture::performQcomOperation(int operation, int arg1, int arg2, ST_LOGV("SurfaceTexture::performQcomOperation operation=%d", operation); switch(operation) { -#ifdef QCOM_HARDWARE - case NATIVE_WINDOW_SET_BUFFERS_SIZE: - mReqSize = arg1; - break; - case NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY: + case NATIVE_WINDOW_SET_BUFFERS_SIZE: + mReqSize = arg1; + break; + case NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY: mNextBufferInfo.width = arg1; mNextBufferInfo.height = arg2; mNextBufferInfo.format = arg3; break; -#endif default: return BAD_VALUE; }; return OK; diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java index ff8d5ac..289a942 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java @@ -26,6 +26,7 @@ import android.graphics.PixelFormat; import android.graphics.Canvas; import android.os.IBinder; import android.os.SystemProperties; +import android.provider.Settings; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -108,7 +109,7 @@ public class KeyguardViewManager implements KeyguardWindowController { Resources res = mContext.getResources(); boolean enableScreenRotation = SystemProperties.getBoolean("lockscreen.rot_override",false) - || res.getBoolean(R.bool.config_enableLockScreenRotation); + || (res.getBoolean(R.bool.config_enableLockScreenRotation) && (Settings.System.getInt(mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 1) != 0)); if (mKeyguardHost == null) { if (DEBUG) Log.d(TAG, "keyguard host is null, creating it..."); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 4c1cb22..9074c29 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2706,7 +2706,13 @@ status_t Client::destroySurface(SurfaceID sid) { // --------------------------------------------------------------------------- +#ifdef QCOM_HARDWARE +GraphicBufferAlloc::GraphicBufferAlloc() { + mFreedIndex = -1; +} +#else GraphicBufferAlloc::GraphicBufferAlloc() {} +#endif GraphicBufferAlloc::~GraphicBufferAlloc() {} @@ -2726,7 +2732,12 @@ sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h } #ifdef QCOM_HARDWARE Mutex::Autolock _l(mLock); - mBuffers.add(graphicBuffer); + if (-1 != mFreedIndex) { + mBuffers.insertAt(graphicBuffer, mFreedIndex); + mFreedIndex = -1; + } else { + mBuffers.add(graphicBuffer); + } #endif return graphicBuffer; } @@ -2741,6 +2752,17 @@ void GraphicBufferAlloc::freeAllGraphicBuffersExcept(int bufIdx) { } else { mBuffers.clear(); } + mFreedIndex = -1; +} + +void GraphicBufferAlloc::freeGraphicBufferAtIndex(int bufIdx) { + Mutex::Autolock _l(mLock); + if (0 <= bufIdx && bufIdx < mBuffers.size()) { + mBuffers.removeItemsAt(bufIdx); + mFreedIndex = bufIdx; + } else { + mFreedIndex = -1; + } } #endif // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 7acb66e..66cf291 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -99,9 +99,11 @@ public: PixelFormat format, uint32_t usage, status_t* error); #ifdef QCOM_HARDWARE virtual void freeAllGraphicBuffersExcept(int bufIdx); + virtual void freeGraphicBufferAtIndex(int bufIdx); private: Vector<sp<GraphicBuffer> > mBuffers; Mutex mLock; + int mFreedIndex; #endif }; diff --git a/telephony/java/com/android/internal/telephony/SemcRIL.java b/telephony/java/com/android/internal/telephony/SemcRIL.java new file mode 100644 index 0000000..9288aa1 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/SemcRIL.java @@ -0,0 +1,501 @@ +/* + * Copyright (C) 2011 The CyanogenMod Project + * + * Diogo Ferreira, Andreas Makris, Alin Jerpelea + * + * 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.telephony; + +import static com.android.internal.telephony.RILConstants.*; + +import android.content.Context; +import android.content.res.Resources; +import android.os.Message; +import android.os.Parcel; +import android.os.SystemProperties; +import android.text.TextUtils; +import android.util.Log; +import android.net.ConnectivityManager; +import android.net.LocalSocket; +import android.net.LocalSocketAddress; + +import com.android.internal.telephony.DataCallState; +import com.android.internal.telephony.DataConnection.FailCause; +import com.android.internal.telephony.OperatorInfo; +import com.android.internal.telephony.IccCardApplication; +import com.android.internal.telephony.IccCardStatus; + +import java.util.ArrayList; + + +/** + * Custom SEMC ril + * + * {@hide} + */ +public class SemcRIL extends QualcommNoSimReadyRIL implements CommandsInterface { + protected String mAid; + + boolean RILJ_LOGV = true; + boolean RILJ_LOGD = true; + + public SemcRIL(Context context, int networkMode, int cdmaSubscription) { + super(context, networkMode, cdmaSubscription); + } + + @Override + public void + supplyIccPin(String pin, Message result) { + // but this request is also valid for SIM and RUIM + RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN, result); + + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + rr.mp.writeInt(0); + rr.mp.writeString(mAid); + rr.mp.writeString(pin); + + send(rr); + } + + @Override + public void + supplyIccPuk(String puk, String newPin, Message result) { + //Note: This RIL request has not been renamed to ICC, + // but this request is also valid for SIM and RUIM + RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK, result); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + rr.mp.writeInt(0); + rr.mp.writeString(mAid); + rr.mp.writeString(puk); + rr.mp.writeString(newPin); + + send(rr); + } + + @Override + public void + supplyIccPin2(String pin, Message result) { + //Note: This RIL request has not been renamed to ICC, + // but this request is also valid for SIM and RUIM + RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN2, result); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + rr.mp.writeInt(0); + rr.mp.writeString(mAid); + rr.mp.writeString(pin); + + send(rr); + } + + @Override + public void + supplyIccPuk2(String puk, String newPin2, Message result) { + //Note: This RIL request has not been renamed to ICC, + // but this request is also valid for SIM and RUIM + RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK2, result); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + rr.mp.writeInt(0); + rr.mp.writeString(mAid); + rr.mp.writeString(puk); + rr.mp.writeString(newPin2); + + send(rr); + } + + @Override + public void + changeIccPin(String oldPin, String newPin, Message result) { + //Note: This RIL request has not been renamed to ICC, + // but this request is also valid for SIM and RUIM + RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN, result); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + rr.mp.writeInt(0); + rr.mp.writeString(mAid); + rr.mp.writeString(oldPin); + rr.mp.writeString(newPin); + + send(rr); + } + + @Override + public void + changeIccPin2(String oldPin2, String newPin2, Message result) { + //Note: This RIL request has not been renamed to ICC, + // but this request is also valid for SIM and RUIM + RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN2, result); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + rr.mp.writeInt(0); + rr.mp.writeString(mAid); + rr.mp.writeString(oldPin2); + rr.mp.writeString(newPin2); + + send(rr); + } + + @Override + public void + supplyNetworkDepersonalization(String netpin, Message result) { + RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + rr.mp.writeInt(3); + rr.mp.writeString(netpin); + + send(rr); + } + + @Override + public void + changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) { + RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + rr.mp.writeInt(3); + rr.mp.writeString(facility); + rr.mp.writeString(oldPwd); + rr.mp.writeString(newPwd); + + send(rr); + } + + + @Override + public void + dial(String address, int clirMode, UUSInfo uusInfo, Message result) { + RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result); + + rr.mp.writeString(address); + rr.mp.writeInt(clirMode); + + if (uusInfo == null) { + rr.mp.writeInt(0); // UUS information is absent + } else { + rr.mp.writeInt(1); // UUS information is present + rr.mp.writeInt(uusInfo.getType()); + rr.mp.writeInt(uusInfo.getDcs()); + rr.mp.writeByteArray(uusInfo.getUserData()); + } + rr.mp.writeInt(0xff); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + send(rr); + } + + @Override + public void + getIMSI(Message result) { + RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result); + rr.mp.writeInt(0); + rr.mp.writeString(mAid); + if (RILJ_LOGD) riljLog(rr.serialString() + + "> getIMSI:RIL_REQUEST_GET_IMSI " + + RIL_REQUEST_GET_IMSI + + " " + requestToString(rr.mRequest)); + + send(rr); + } + + @Override + public void + setupDataCall(String radioTechnology, String profile, String apn, + String user, String password, String authType, String ipVersion, + Message result) { + RILRequest rr + = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result); + + rr.mp.writeInt(7); + + rr.mp.writeString(radioTechnology); + rr.mp.writeString(profile); + rr.mp.writeString(apn); + rr.mp.writeString(user); + rr.mp.writeString(password); + rr.mp.writeString(authType); + rr.mp.writeString(ipVersion); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + + requestToString(rr.mRequest) + " " + radioTechnology + " " + + profile + " " + apn + " " + user + " " + + password + " " + authType + " " + ipVersion); + + send(rr); + } + + @Override + public void + deactivateDataCall(int cid, int reason, Message result) { + RILRequest rr + = RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DATA_CALL, result); + + rr.mp.writeInt(2); + rr.mp.writeString(Integer.toString(cid)); + rr.mp.writeString(Integer.toString(reason)); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + + requestToString(rr.mRequest) + " " + cid + " " + reason); + + send(rr); + } + + @Override + public void + iccIO (int command, int fileid, String path, int p1, int p2, int p3, + String data, String pin2, Message result) { + //Note: This RIL request has not been renamed to ICC, + // but this request is also valid for SIM and RUIM + RILRequest rr + = RILRequest.obtain(RIL_REQUEST_SIM_IO, result); + + rr.mp.writeInt(0); + rr.mp.writeString(mAid); + rr.mp.writeInt(command); + rr.mp.writeInt(fileid); + rr.mp.writeString(path); + rr.mp.writeInt(p1); + rr.mp.writeInt(p2); + rr.mp.writeInt(p3); + rr.mp.writeString(data); + rr.mp.writeString(pin2); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> iccIO: " + requestToString(rr.mRequest) + + " 0x" + Integer.toHexString(command) + + " 0x" + Integer.toHexString(fileid) + " " + + " path: " + path + "," + + p1 + "," + p2 + "," + p3); + + send(rr); + } + + @Override + public void + setNetworkSelectionModeAutomatic(Message response) { + RILRequest rr + = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, + response); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + rr.mp.writeString(null); + rr.mp.writeInt(-1); + send(rr); + } + + @Override + public void + setNetworkSelectionModeManual(String operatorNumeric, Message response) { + RILRequest rr + = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, + response); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + + " " + operatorNumeric); + + rr.mp.writeString(operatorNumeric); + rr.mp.writeInt(-1); + + send(rr); + } + + @Override + public void + queryFacilityLock (String facility, String password, int serviceClass, + Message response) { + RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_FACILITY_LOCK, response); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + // count strings + rr.mp.writeInt(5); + rr.mp.writeString("0"); + rr.mp.writeString(mAid); + rr.mp.writeString(facility); + rr.mp.writeString(password); + + rr.mp.writeString(Integer.toString(serviceClass)); + + send(rr); + } + + @Override + public void + setFacilityLock (String facility, boolean lockState, String password, + int serviceClass, Message response) { + String lockString; + RILRequest rr + = RILRequest.obtain(RIL_REQUEST_SET_FACILITY_LOCK, response); + + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); + + // count strings + rr.mp.writeInt(6); + + rr.mp.writeString("0"); + rr.mp.writeString(mAid); + rr.mp.writeString(facility); + lockString = (lockState)?"1":"0"; + rr.mp.writeString(lockString); + rr.mp.writeString(password); + rr.mp.writeString(Integer.toString(serviceClass)); + + send(rr); + + } + + @Override + protected Object + responseIccCardStatus(Parcel p) { + IccCardApplication ca; + + IccCardStatus status = new IccCardStatus(); + p.readInt(); // unknown first parameter + status.setCardState(p.readInt()); + status.setUniversalPinState(p.readInt()); + int gsmUmtsSubscriptionAppCount = p.readInt(); + + for (int i = 0; i < gsmUmtsSubscriptionAppCount; i++) { + if (i == 0) + status.setGsmUmtsSubscriptionAppIndex(p.readInt()); + else + p.readInt(); + } + + int cdmaSubscriptionAppCount = p.readInt(); + for (int i = 0; i < cdmaSubscriptionAppCount; i++) { + if (i == 0) + status.setCdmaSubscriptionAppIndex(p.readInt()); + else + p.readInt(); + } + + int numApplications = p.readInt(); + + // limit to maximum allowed applications + if (numApplications > IccCardStatus.CARD_MAX_APPS) { + numApplications = IccCardStatus.CARD_MAX_APPS; + } + status.setNumApplications(numApplications); + + for (int i = 0 ; i < numApplications ; i++) { + ca = new IccCardApplication(); + ca.app_type = ca.AppTypeFromRILInt(p.readInt()); + ca.app_state = ca.AppStateFromRILInt(p.readInt()); + ca.perso_substate = ca.PersoSubstateFromRILInt(p.readInt()); + ca.aid = p.readString(); + ca.app_label = p.readString(); + ca.pin1_replaced = p.readInt(); + ca.pin1 = ca.PinStateFromRILInt(p.readInt()); + ca.pin2 = ca.PinStateFromRILInt(p.readInt()); + status.addApplication(ca); + p.readInt(); + p.readInt(); + p.readInt(); + p.readInt(); + } + + + int appIndex = -1; + if (mPhoneType == RILConstants.CDMA_PHONE) { + appIndex = status.getCdmaSubscriptionAppIndex(); + Log.d(LOG_TAG, "This is a CDMA PHONE " + appIndex); + } else { + appIndex = status.getGsmUmtsSubscriptionAppIndex(); + Log.d(LOG_TAG, "This is a GSM PHONE " + appIndex); + } + + IccCardApplication application = status.getApplication(appIndex); + mAid = application.aid; + + return status; + } + + @Override + protected DataCallState getDataCallState(Parcel p, int version) { + DataCallState datacallstate = new DataCallState(); + datacallstate.version = 3; + datacallstate.cid = p.readInt(); + datacallstate.active = p.readInt(); + datacallstate.type = p.readString(); + String s1 = p.readString(); + if(!TextUtils.isEmpty(s1)) { + datacallstate.addresses = s1.split(" "); } + datacallstate.ifname = "rmnet0"; + p.readInt(); + p.readInt(); + return datacallstate; + } + + @Override + protected Object + responseSetupDataCall(Parcel p) { + + DataCallState dataCall; + + dataCall = new DataCallState(); + dataCall.version = 3; + dataCall.cid = 0; + p.readInt(); + dataCall.ifname = p.readString(); + if (TextUtils.isEmpty(dataCall.ifname)) { + throw new RuntimeException( + "RIL_REQUEST_SETUP_DATA_CALL response, no ifname"); + } + + String addresses = p.readString(); + if (!TextUtils.isEmpty(addresses)) { + dataCall.addresses = addresses.split(" "); + } + return dataCall; + } + + @Override + protected Object + responseOperatorInfos(Parcel p) { + String strings[] = (String [])responseStrings(p); + ArrayList<OperatorInfo> ret; + + if (strings.length % 5 != 0) { + throw new RuntimeException( + "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got " + + strings.length + " strings, expected multible of 5"); + } + + ret = new ArrayList<OperatorInfo>(strings.length / 5); + + for (int i = 0 ; i < strings.length ; i += 5) { + ret.add ( + new OperatorInfo( + strings[i+0], + strings[i+1], + strings[i+2], + strings[i+3])); + } + + return ret; + } +} |