diff options
79 files changed, 3252 insertions, 3440 deletions
diff --git a/Android.mk b/Android.mk index b7f8977d3f23..e2c3def5a312 100644 --- a/Android.mk +++ b/Android.mk @@ -109,6 +109,7 @@ LOCAL_SRC_FILES += \ core/java/com/android/internal/view/IInputMethodManager.aidl \ core/java/com/android/internal/view/IInputMethodSession.aidl \ im/java/android/im/IImPlugin.aidl \ + location/java/android/location/IGeocodeProvider.aidl \ location/java/android/location/IGpsStatusListener.aidl \ location/java/android/location/ILocationCollector.aidl \ location/java/android/location/ILocationListener.aidl \ diff --git a/api/current.xml b/api/current.xml index 26a416db456f..6704766c9e19 100644 --- a/api/current.xml +++ b/api/current.xml @@ -28346,6 +28346,28 @@ visibility="public" > </field> +<field name="ACTION_POWER_CONNECTED" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.intent.action.ACTION_POWER_CONNECTED"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="ACTION_POWER_DISCONNECTED" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.intent.action.ACTION_POWER_DISCONNECTED"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="ACTION_PROVIDER_CHANGED" type="java.lang.String" transient="false" diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 849a37dc95a9..9b1f0f97171f 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -611,7 +611,7 @@ public class Activity extends ContextThemeWrapper private IBinder mToken; /*package*/ String mEmbeddedID; private Application mApplication; - private Intent mIntent; + /*package*/ Intent mIntent; private ComponentName mComponent; /*package*/ ActivityInfo mActivityInfo; /*package*/ ActivityThread mMainThread; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index d8161936a44d..09862d2705d1 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1689,7 +1689,7 @@ public final class ActivityThread { r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo); - handleLaunchActivity(r); + handleLaunchActivity(r, null); } break; case RELAUNCH_ACTIVITY: { ActivityRecord r = (ActivityRecord)msg.obj; @@ -2109,7 +2109,7 @@ public final class ActivityThread { + ", comp=" + name + ", token=" + token); } - return performLaunchActivity(r); + return performLaunchActivity(r, null); } public final Activity getActivity(IBinder token) { @@ -2159,7 +2159,7 @@ public final class ActivityThread { queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci); } - private final Activity performLaunchActivity(ActivityRecord r) { + private final Activity performLaunchActivity(ActivityRecord r, Intent customIntent) { // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); ActivityInfo aInfo = r.activityInfo; @@ -2219,6 +2219,9 @@ public final class ActivityThread { r.lastNonConfigurationInstance, r.lastNonConfigurationChildInstances, config); + if (customIntent != null) { + activity.mIntent = customIntent; + } r.lastNonConfigurationInstance = null; r.lastNonConfigurationChildInstances = null; activity.mStartedActivity = false; @@ -2274,14 +2277,14 @@ public final class ActivityThread { return activity; } - private final void handleLaunchActivity(ActivityRecord r) { + private final void handleLaunchActivity(ActivityRecord r, Intent customIntent) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); if (localLOGV) Log.v( TAG, "Handling launch of " + r); - Activity a = performLaunchActivity(r); + Activity a = performLaunchActivity(r, customIntent); if (a != null) { handleResumeActivity(r.token, false, r.isForward); @@ -3243,6 +3246,7 @@ public final class ActivityThread { } r.activity.mConfigChangeFlags |= configChanges; + Intent currentIntent = r.activity.mIntent; Bundle savedState = null; if (!r.paused) { @@ -3275,7 +3279,7 @@ public final class ActivityThread { r.state = savedState; } - handleLaunchActivity(r); + handleLaunchActivity(r, currentIntent); } private final void handleRequestThumbnail(IBinder token) { diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 99cf34c2ca57..e82a86cd4a3e 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -508,6 +508,8 @@ import java.util.Set; * <li> {@link #ACTION_PACKAGE_DATA_CLEARED} * <li> {@link #ACTION_UID_REMOVED} * <li> {@link #ACTION_BATTERY_CHANGED} + * <li> {@link #ACTION_POWER_CONNECTED} + * <li> {@link #ACTION_POWER_DISCONNECTED} * </ul> * * <h3>Standard Categories</h3> @@ -1250,6 +1252,24 @@ public class Intent implements Parcelable { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW"; /** + * Broadcast Action: External power has been connected to the device. + * This is intended for applications that wish to register specifically to this notification. + * Unlike ACTION_BATTERY_CHANGED, applications will be woken for this and so do not have to + * stay active to receive this notification. This action can be used to implement actions + * that wait until power is available to trigger. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_POWER_CONNECTED = "android.intent.action.ACTION_POWER_CONNECTED"; + /** + * Broadcast Action: External power has been removed from the device. + * This is intended for applications that wish to register specifically to this notification. + * Unlike ACTION_BATTERY_CHANGED, applications will be woken for this and so do not have to + * stay active to receive this notification. This action can be used to implement actions + * that wait until power is available to trigger. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED"; + /** * Broadcast Action: Indicates low memory condition on the device */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index ed7c0568353c..1064fb64fb94 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -354,9 +354,10 @@ public class MobileDataStateTracker extends NetworkStateTracker { /** * Tells the phone sub-system that the caller wants to - * begin using the named feature. The only supported feature at - * this time is {@code Phone.FEATURE_ENABLE_MMS}, which allows an application - * to specify that it wants to send and/or receive MMS data. + * begin using the named feature. The only supported features at + * this time are {@code Phone.FEATURE_ENABLE_MMS}, which allows an application + * to specify that it wants to send and/or receive MMS data, and + * {@code Phone.FEATURE_ENABLE_SUPL}, which is used for Assisted GPS. * @param feature the name of the feature to be used * @param callingPid the process ID of the process that is issuing this request * @param callingUid the user ID of the process that is issuing this request @@ -376,6 +377,8 @@ public class MobileDataStateTracker extends NetworkStateTracker { if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) { mLastCallingPid = callingPid; return setEnableApn(Phone.APN_TYPE_MMS, true); + } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) { + return setEnableApn(Phone.APN_TYPE_SUPL, true); } else { return -1; } @@ -396,6 +399,8 @@ public class MobileDataStateTracker extends NetworkStateTracker { public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) { if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) { return setEnableApn(Phone.APN_TYPE_MMS, false); + } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) { + return setEnableApn(Phone.APN_TYPE_SUPL, false); } else { return -1; } diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java index 9f07c0a2c5b0..66eefb26af97 100644 --- a/core/java/android/net/Proxy.java +++ b/core/java/android/net/Proxy.java @@ -30,6 +30,9 @@ import junit.framework.Assert; */ final public class Proxy { + // Set to true to enable extra debugging. + static final private boolean DEBUG = false; + static final public String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE"; @@ -49,7 +52,7 @@ final public class Proxy { if (host != null) { int i = host.indexOf(':'); if (i == -1) { - if (android.util.Config.DEBUG) { + if (DEBUG) { Assert.assertTrue(host.length() == 0); } return null; @@ -73,12 +76,12 @@ final public class Proxy { if (host != null) { int i = host.indexOf(':'); if (i == -1) { - if (android.util.Config.DEBUG) { + if (DEBUG) { Assert.assertTrue(host.length() == 0); } return -1; } - if (android.util.Config.DEBUG) { + if (DEBUG) { Assert.assertTrue(i < host.length()); } return Integer.parseInt(host.substring(i+1)); diff --git a/core/java/android/provider/Gmail.java b/core/java/android/provider/Gmail.java index cc039686249d..c4b29ae440fa 100644 --- a/core/java/android/provider/Gmail.java +++ b/core/java/android/provider/Gmail.java @@ -38,7 +38,6 @@ import android.text.TextUtils; import android.text.TextUtils.SimpleStringSplitter; import android.text.style.CharacterStyle; import android.text.util.Regex; -import android.util.Config; import android.util.Log; import java.io.UnsupportedEncodingException; @@ -61,6 +60,9 @@ import java.util.regex.Pattern; * @hide */ public final class Gmail { + // Set to true to enable extra debugging. + private static final boolean DEBUG = false; + public static final String GMAIL_AUTH_SERVICE = "mail"; // These constants come from google3/java/com/google/caribou/backend/MailLabel.java. public static final String LABEL_SENT = "^f"; @@ -1195,7 +1197,7 @@ public final class Gmail { @Override public void onChange(boolean selfChange) { - if (Config.DEBUG) { + if (DEBUG) { Log.d(TAG, "MailCursor is notifying " + mObservers.size() + " observers"); } for (MailCursorObserver o: mObservers) { diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index a6ed922f89fe..29dc2ea5246e 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -24,7 +24,6 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Path; import com.android.internal.util.ArrayUtils; -import android.util.Config; import junit.framework.Assert; import android.text.style.*; @@ -39,6 +38,8 @@ import android.view.KeyEvent; * For text that will not change, use a {@link StaticLayout}. */ public abstract class Layout { + private static final boolean DEBUG = false; + /* package */ static final EmojiFactory EMOJI_FACTORY = EmojiFactory.newAvailableInstance(); /* package */ static final int MIN_EMOJI, MAX_EMOJI; @@ -330,7 +331,7 @@ public abstract class Layout { boolean hasTab = getLineContainsTab(i); if (directions == DIRS_ALL_LEFT_TO_RIGHT && !spannedText && !hasTab) { - if (Config.DEBUG) { + if (DEBUG) { Assert.assertTrue(dir == DIR_LEFT_TO_RIGHT); Assert.assertNotNull(c); } @@ -797,7 +798,7 @@ public abstract class Layout { } private int getLineVisibleEnd(int line, int start, int end) { - if (Config.DEBUG) { + if (DEBUG) { Assert.assertTrue(getLineStart(line) == start && getLineStart(line+1) == end); } @@ -1340,7 +1341,7 @@ public abstract class Layout { char[] buf; if (!hasTabs) { if (directions == DIRS_ALL_LEFT_TO_RIGHT) { - if (Config.DEBUG) { + if (DEBUG) { Assert.assertTrue(DIR_LEFT_TO_RIGHT == dir); } Styled.drawText(canvas, text, start, end, dir, false, x, top, y, bottom, paint, workPaint, false); diff --git a/core/java/android/util/DebugUtils.java b/core/java/android/util/DebugUtils.java index 1c5d669ad52a..56f389c9faa9 100644 --- a/core/java/android/util/DebugUtils.java +++ b/core/java/android/util/DebugUtils.java @@ -43,8 +43,8 @@ public class DebugUtils { * * <p>This class is useful for debugging and logging purpose:</p> * <pre> - * if (Config.DEBUG) { - * if (DebugUtils.isObjectSelected(childView) && Config.LOGV) { + * if (DEBUG) { + * if (DebugUtils.isObjectSelected(childView) && LOGV_ENABLED) { * Log.v(TAG, "Object " + childView + " logged!"); * } * } diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index 5401a6e0af12..ba3f78cf22ec 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -24,7 +24,6 @@ import android.net.WebAddress; import android.net.http.SslCertificate; import android.os.Handler; import android.os.Message; -import android.util.Config; import android.util.Log; import android.util.TypedValue; @@ -120,7 +119,7 @@ class BrowserFrame extends Handler { mDatabase = WebViewDatabase.getInstance(context); mWebViewCore = w; - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "BrowserFrame constructor: this=" + this); } } @@ -331,7 +330,7 @@ class BrowserFrame extends Handler { switch (msg.what) { case FRAME_COMPLETED: { if (mSettings.getSavePassword() && hasPasswordField()) { - if (Config.DEBUG) { + if (WebView.DEBUG) { Assert.assertNotNull(mCallbackProxy.getBackForwardList() .getCurrentItem()); } @@ -480,7 +479,7 @@ class BrowserFrame extends Handler { } if (mSettings.getSavePassword() && hasPasswordField()) { try { - if (Config.DEBUG) { + if (WebView.DEBUG) { Assert.assertNotNull(mCallbackProxy.getBackForwardList() .getCurrentItem()); } @@ -528,7 +527,7 @@ class BrowserFrame extends Handler { // is this resource the main-frame top-level page? boolean isMainFramePage = mIsMainFrame; - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "startLoadingResource: url=" + url + ", method=" + method + ", postData=" + postData + ", isHighPriority=" + isHighPriority + ", isMainFramePage=" + isMainFramePage); diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java index 4528b73aa788..7897435df2fc 100644 --- a/core/java/android/webkit/CacheManager.java +++ b/core/java/android/webkit/CacheManager.java @@ -19,7 +19,6 @@ package android.webkit; import android.content.Context; import android.net.http.Headers; import android.os.FileUtils; -import android.util.Config; import android.util.Log; import java.io.File; import java.io.FileInputStream; @@ -322,7 +321,7 @@ public final class CacheManager { } } - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "getCacheFile for url " + url); } @@ -416,7 +415,7 @@ public final class CacheManager { mDataBase.addCache(url, cacheRet); - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "saveCacheFile for url " + url); } } diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java index 0f9f29cedb6d..5f8acc87db63 100644 --- a/core/java/android/webkit/CallbackProxy.java +++ b/core/java/android/webkit/CallbackProxy.java @@ -30,7 +30,6 @@ import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.provider.Browser; -import android.util.Config; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -822,7 +821,7 @@ class CallbackProxy extends Handler { String password, Message resumeMsg) { // resumeMsg should be null at this point because we want to create it // within the CallbackProxy. - if (Config.DEBUG) { + if (WebView.DEBUG) { junit.framework.Assert.assertNull(resumeMsg); } resumeMsg = obtainMessage(NOTIFY); diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java index d90a2fdbd11b..c0c6775c3f53 100644 --- a/core/java/android/webkit/CookieManager.java +++ b/core/java/android/webkit/CookieManager.java @@ -18,7 +18,6 @@ package android.webkit; import android.net.ParseException; import android.net.WebAddress; -import android.util.Config; import android.util.Log; import java.util.ArrayList; @@ -263,7 +262,7 @@ public final class CookieManager { if (!mAcceptCookie || uri == null) { return; } - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "setCookie: uri: " + uri + " value: " + value); } @@ -428,12 +427,12 @@ public final class CookieManager { } } if (ret.length() > 0) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "getCookie: uri: " + uri + " value: " + ret); } return ret.toString(); } else { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "getCookie: uri: " + uri + " But can't find cookie."); } @@ -589,7 +588,7 @@ public final class CookieManager { Iterator<ArrayList<Cookie>> listIter = cookieLists.iterator(); while (listIter.hasNext() && count < MAX_RAM_COOKIES_COUNT) { ArrayList<Cookie> list = listIter.next(); - if (Config.DEBUG) { + if (WebView.DEBUG) { Iterator<Cookie> iter = list.iterator(); while (iter.hasNext() && count < MAX_RAM_COOKIES_COUNT) { Cookie cookie = iter.next(); @@ -609,7 +608,7 @@ public final class CookieManager { ArrayList<Cookie> retlist = new ArrayList<Cookie>(); if (mapSize >= MAX_RAM_DOMAIN_COUNT || count >= MAX_RAM_COOKIES_COUNT) { - if (Config.DEBUG) { + if (WebView.DEBUG) { Log.v(LOGTAG, count + " cookies used " + byteCount + " bytes with " + mapSize + " domains"); } @@ -617,7 +616,7 @@ public final class CookieManager { int toGo = mapSize / 10 + 1; while (toGo-- > 0){ String domain = domains[toGo].toString(); - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "delete domain: " + domain + " from RAM cache"); } diff --git a/core/java/android/webkit/CookieSyncManager.java b/core/java/android/webkit/CookieSyncManager.java index f2511d84d18f..8d66529f24b9 100644 --- a/core/java/android/webkit/CookieSyncManager.java +++ b/core/java/android/webkit/CookieSyncManager.java @@ -17,7 +17,6 @@ package android.webkit; import android.content.Context; -import android.util.Config; import android.util.Log; import android.webkit.CookieManager.Cookie; @@ -162,7 +161,7 @@ public final class CookieSyncManager extends WebSyncManager { } protected void syncFromRamToFlash() { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash STARTS"); } @@ -179,7 +178,7 @@ public final class CookieSyncManager extends WebSyncManager { CookieManager.getInstance().deleteLRUDomain(); syncFromRamToFlash(lruList); - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash DONE"); } } diff --git a/core/java/android/webkit/FrameLoader.java b/core/java/android/webkit/FrameLoader.java index 42d03f0dcc99..6f1b16047950 100644 --- a/core/java/android/webkit/FrameLoader.java +++ b/core/java/android/webkit/FrameLoader.java @@ -18,7 +18,6 @@ package android.webkit; import android.net.http.EventHandler; import android.net.http.RequestHandle; -import android.util.Config; import android.util.Log; import android.webkit.CacheManager.CacheResult; @@ -121,7 +120,7 @@ class FrameLoader { } else if (handleLocalFile(url, mListener, mSettings)) { return true; } - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "FrameLoader.executeLoad: url protocol not supported:" + mListener.url()); } @@ -181,7 +180,7 @@ class FrameLoader { return true; } - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "FrameLoader: http " + mMethod + " load for: " + mListener.url()); } @@ -212,7 +211,7 @@ class FrameLoader { * setup a load from the byte stream in a CacheResult. */ private void startCacheLoad(CacheResult result) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "FrameLoader: loading from cache: " + mListener.url()); } @@ -286,7 +285,7 @@ class FrameLoader { // of it's state. If it is not in the cache, then go to the // network. case WebSettings.LOAD_CACHE_ELSE_NETWORK: { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "FrameLoader: checking cache: " + mListener.url()); } diff --git a/core/java/android/webkit/JWebCoreJavaBridge.java b/core/java/android/webkit/JWebCoreJavaBridge.java index a0049ac982e2..2a84683cdc86 100644 --- a/core/java/android/webkit/JWebCoreJavaBridge.java +++ b/core/java/android/webkit/JWebCoreJavaBridge.java @@ -18,7 +18,6 @@ package android.webkit; import android.os.Handler; import android.os.Message; -import android.util.Config; import android.util.Log; final class JWebCoreJavaBridge extends Handler { @@ -156,7 +155,7 @@ final class JWebCoreJavaBridge extends Handler { * @param timemillis The relative time when the timer should fire */ private void setSharedTimer(long timemillis) { - if (Config.LOGV) Log.v(LOGTAG, "setSharedTimer " + timemillis); + if (WebView.LOGV_ENABLED) Log.v(LOGTAG, "setSharedTimer " + timemillis); if (timemillis <= 0) { // we don't accumulate the sharedTimer unless it is a delayed @@ -180,7 +179,7 @@ final class JWebCoreJavaBridge extends Handler { * Stop the shared timer. */ private void stopSharedTimer() { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "stopSharedTimer removing all timers"); } removeMessages(TIMER_MESSAGE); diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java index c64200cd5b2a..d583eb18a043 100644 --- a/core/java/android/webkit/LoadListener.java +++ b/core/java/android/webkit/LoadListener.java @@ -29,7 +29,6 @@ import android.net.http.SslCertificate; import android.os.Handler; import android.os.Message; -import android.util.Config; import android.util.Log; import android.webkit.CacheManager.CacheResult; @@ -134,7 +133,7 @@ class LoadListener extends Handler implements EventHandler { LoadListener(Context context, BrowserFrame frame, String url, int nativeLoader, boolean synchronous, boolean isMainPageLoader) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener constructor url=" + url); } mContext = context; @@ -285,7 +284,7 @@ class LoadListener extends Handler implements EventHandler { * directly */ public void headers(Headers headers) { - if (Config.LOGV) Log.v(LOGTAG, "LoadListener.headers"); + if (WebView.LOGV_ENABLED) Log.v(LOGTAG, "LoadListener.headers"); sendMessageInternal(obtainMessage(MSG_CONTENT_HEADERS, headers)); } @@ -432,7 +431,7 @@ class LoadListener extends Handler implements EventHandler { */ public void status(int majorVersion, int minorVersion, int code, /* Status-Code value */ String reasonPhrase) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener: from: " + mUrl + " major: " + majorVersion + " minor: " + minorVersion @@ -489,7 +488,7 @@ class LoadListener extends Handler implements EventHandler { * directly */ public void error(int id, String description) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener.error url:" + url() + " id:" + id + " description:" + description); } @@ -517,7 +516,7 @@ class LoadListener extends Handler implements EventHandler { * mDataBuilder is a thread-safe structure. */ public void data(byte[] data, int length) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener.data(): url: " + url()); } @@ -555,7 +554,7 @@ class LoadListener extends Handler implements EventHandler { * directly */ public void endData() { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener.endData(): url: " + url()); } sendMessageInternal(obtainMessage(MSG_CONTENT_FINISHED)); @@ -608,7 +607,7 @@ class LoadListener extends Handler implements EventHandler { // before calling it. if (mCacheLoader != null) { mCacheLoader.load(); - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener cache load url=" + url()); } return; @@ -658,7 +657,7 @@ class LoadListener extends Handler implements EventHandler { CacheManager.HEADER_KEY_IFNONEMATCH) && !headers.containsKey( CacheManager.HEADER_KEY_IFMODIFIEDSINCE)) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "FrameLoader: HTTP URL in cache " + "and usable: " + url()); } @@ -677,7 +676,7 @@ class LoadListener extends Handler implements EventHandler { * directly */ public void handleSslErrorRequest(SslError error) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener.handleSslErrorRequest(): url:" + url() + " primary error: " + error.getPrimaryError() + @@ -743,7 +742,7 @@ class LoadListener extends Handler implements EventHandler { * are null, cancel the request. */ void handleAuthResponse(String username, String password) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener.handleAuthResponse: url: " + mUrl + " username: " + username + " password: " + password); @@ -840,7 +839,7 @@ class LoadListener extends Handler implements EventHandler { } void attachRequestHandle(RequestHandle requestHandle) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener.attachRequestHandle(): " + "requestHandle: " + requestHandle); } @@ -848,7 +847,7 @@ class LoadListener extends Handler implements EventHandler { } void detachRequestHandle() { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener.detachRequestHandle(): " + "requestHandle: " + mRequestHandle); } @@ -887,7 +886,7 @@ class LoadListener extends Handler implements EventHandler { */ static boolean willLoadFromCache(String url) { boolean inCache = CacheManager.getCacheFile(url, null) != null; - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "willLoadFromCache: " + url + " in cache: " + inCache); } @@ -1057,7 +1056,7 @@ class LoadListener extends Handler implements EventHandler { * EventHandler's method call. */ public void cancel() { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { if (mRequestHandle == null) { Log.v(LOGTAG, "LoadListener.cancel(): no requestHandle"); } else { @@ -1189,7 +1188,7 @@ class LoadListener extends Handler implements EventHandler { tearDown(); } - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener.onRedirect(): redirect to: " + redirectTo); } @@ -1203,7 +1202,7 @@ class LoadListener extends Handler implements EventHandler { Pattern.compile("^((?:[xX]-)?[a-zA-Z\\*]+/[\\w\\+\\*-]+[\\.[\\w\\+-]+]*)$"); private void parseContentTypeHeader(String contentType) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "LoadListener.parseContentTypeHeader: " + "contentType: " + contentType); } @@ -1390,7 +1389,7 @@ class LoadListener extends Handler implements EventHandler { */ private String guessMimeTypeFromExtension() { // PENDING: need to normalize url - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "guessMimeTypeFromExtension: mURL = " + mUrl); } @@ -1425,7 +1424,7 @@ class LoadListener extends Handler implements EventHandler { * Cycle through our messages for synchronous loads. */ /* package */ void loadSynchronousMessages() { - if (Config.DEBUG && !mSynchronous) { + if (WebView.DEBUG && !mSynchronous) { throw new AssertionError(); } // Note: this can be called twice if it is a synchronous network load, diff --git a/core/java/android/webkit/Network.java b/core/java/android/webkit/Network.java index 6fa07753dea3..c9b80ce77df6 100644 --- a/core/java/android/webkit/Network.java +++ b/core/java/android/webkit/Network.java @@ -20,7 +20,6 @@ import android.content.Context; import android.net.http.*; import android.os.*; import android.util.Log; -import android.util.Config; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -133,7 +132,7 @@ class Network { * XXX: Must be created in the same thread as WebCore!!!!! */ private Network(Context context) { - if (Config.DEBUG) { + if (WebView.DEBUG) { Assert.assertTrue(Thread.currentThread(). getName().equals(WebViewCore.THREAD_NAME)); } @@ -233,7 +232,7 @@ class Network { * connecting through the proxy. */ public synchronized void setProxyUsername(String proxyUsername) { - if (Config.DEBUG) { + if (WebView.DEBUG) { Assert.assertTrue(isValidProxySet()); } @@ -253,7 +252,7 @@ class Network { * connecting through the proxy. */ public synchronized void setProxyPassword(String proxyPassword) { - if (Config.DEBUG) { + if (WebView.DEBUG) { Assert.assertTrue(isValidProxySet()); } @@ -267,7 +266,7 @@ class Network { * @return True iff succeeds. */ public boolean saveState(Bundle outState) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "Network.saveState()"); } @@ -281,7 +280,7 @@ class Network { * @return True iff succeeds. */ public boolean restoreState(Bundle inState) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "Network.restoreState()"); } @@ -301,7 +300,7 @@ class Network { * @param loader The loader that resulted in SSL errors. */ public void handleSslErrorRequest(LoadListener loader) { - if (Config.DEBUG) Assert.assertNotNull(loader); + if (WebView.DEBUG) Assert.assertNotNull(loader); if (loader != null) { mSslErrorHandler.handleSslErrorRequest(loader); } @@ -314,7 +313,7 @@ class Network { * authentication request. */ public void handleAuthRequest(LoadListener loader) { - if (Config.DEBUG) Assert.assertNotNull(loader); + if (WebView.DEBUG) Assert.assertNotNull(loader); if (loader != null) { mHttpAuthHandler.handleAuthRequest(loader); } diff --git a/core/java/android/webkit/SslErrorHandler.java b/core/java/android/webkit/SslErrorHandler.java index 2e2fa12052ab..5f84bbe04dd3 100644 --- a/core/java/android/webkit/SslErrorHandler.java +++ b/core/java/android/webkit/SslErrorHandler.java @@ -22,7 +22,6 @@ import android.net.http.SslError; import android.os.Bundle; import android.os.Handler; import android.os.Message; -import android.util.Config; import android.util.Log; import java.util.LinkedList; @@ -121,7 +120,7 @@ public class SslErrorHandler extends Handler { * Handles SSL error(s) on the way up to the user. */ /* package */ synchronized void handleSslErrorRequest(LoadListener loader) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "SslErrorHandler.handleSslErrorRequest(): " + "url=" + loader.url()); } @@ -158,14 +157,14 @@ public class SslErrorHandler extends Handler { SslError error = loader.sslError(); - if (Config.DEBUG) { + if (WebView.DEBUG) { Assert.assertNotNull(error); } int primary = error.getPrimaryError(); String host = loader.host(); - if (Config.DEBUG) { + if (WebView.DEBUG) { Assert.assertTrue(host != null && primary != 0); } @@ -206,11 +205,11 @@ public class SslErrorHandler extends Handler { */ /* package */ synchronized void handleSslErrorResponse(boolean proceed) { LoadListener loader = mLoaderQueue.poll(); - if (Config.DEBUG) { + if (WebView.DEBUG) { Assert.assertNotNull(loader); } - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "SslErrorHandler.handleSslErrorResponse():" + " proceed: " + proceed + " url:" + loader.url()); @@ -222,7 +221,7 @@ public class SslErrorHandler extends Handler { int primary = loader.sslError().getPrimaryError(); String host = loader.host(); - if (Config.DEBUG) { + if (WebView.DEBUG) { Assert.assertTrue(host != null && primary != 0); } boolean hasKey = mSslPrefTable.containsKey(host); diff --git a/core/java/android/webkit/StreamLoader.java b/core/java/android/webkit/StreamLoader.java index 9098307e8052..705157c639f2 100644 --- a/core/java/android/webkit/StreamLoader.java +++ b/core/java/android/webkit/StreamLoader.java @@ -20,7 +20,6 @@ import android.net.http.EventHandler; import android.net.http.Headers; import android.os.Handler; import android.os.Message; -import android.util.Config; import java.io.IOException; import java.io.InputStream; @@ -114,7 +113,7 @@ abstract class StreamLoader extends Handler { * @see android.os.Handler#handleMessage(android.os.Message) */ public void handleMessage(Message msg) { - if (Config.DEBUG && mHandler.isSynchronous()) { + if (WebView.DEBUG && mHandler.isSynchronous()) { throw new AssertionError(); } switch(msg.what) { diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java index 0e8144edd60a..d6ac3e9093bf 100644 --- a/core/java/android/webkit/URLUtil.java +++ b/core/java/android/webkit/URLUtil.java @@ -23,7 +23,6 @@ import java.util.regex.Pattern; import android.net.Uri; import android.net.ParseException; import android.net.WebAddress; -import android.util.Config; import android.util.Log; public final class URLUtil { @@ -62,7 +61,7 @@ public final class URLUtil { webAddress = new WebAddress(inUrl); } catch (ParseException ex) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "smartUrlFilter: failed to parse url = " + inUrl); } return retVal; diff --git a/core/java/android/webkit/WebBackForwardList.java b/core/java/android/webkit/WebBackForwardList.java index 9dea5ecbecd4..ffd6a118d9e6 100644 --- a/core/java/android/webkit/WebBackForwardList.java +++ b/core/java/android/webkit/WebBackForwardList.java @@ -16,7 +16,6 @@ package android.webkit; -import android.util.Config; import java.io.Serializable; import java.util.ArrayList; @@ -138,7 +137,7 @@ public class WebBackForwardList implements Cloneable, Serializable { // when removing the first item, we can assert that the index is 0. // This lets us change the current index without having to query the // native BackForwardList. - if (Config.DEBUG && (index != 0)) { + if (WebView.DEBUG && (index != 0)) { throw new AssertionError(); } final WebHistoryItem h = mArray.remove(index); diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index 025e6bb819cc..105eacdca754 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -1097,7 +1097,7 @@ public class WebSettings { /*package*/ synchronized void syncSettingsAndCreateHandler(BrowserFrame frame) { mBrowserFrame = frame; - if (android.util.Config.DEBUG) { + if (WebView.DEBUG) { junit.framework.Assert.assertTrue(frame.mNativeFrame != 0); } nativeSync(frame.mNativeFrame); diff --git a/core/java/android/webkit/WebSyncManager.java b/core/java/android/webkit/WebSyncManager.java index e6e9994486be..ded17ed518c7 100644 --- a/core/java/android/webkit/WebSyncManager.java +++ b/core/java/android/webkit/WebSyncManager.java @@ -21,7 +21,6 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Process; -import android.util.Config; import android.util.Log; abstract class WebSyncManager implements Runnable { @@ -48,7 +47,7 @@ abstract class WebSyncManager implements Runnable { @Override public void handleMessage(Message msg) { if (msg.what == SYNC_MESSAGE) { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "*** WebSyncManager sync ***"); } syncFromRamToFlash(); @@ -95,7 +94,7 @@ abstract class WebSyncManager implements Runnable { * sync() forces sync manager to sync now */ public void sync() { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "*** WebSyncManager sync ***"); } if (mHandler == null) { @@ -110,7 +109,7 @@ abstract class WebSyncManager implements Runnable { * resetSync() resets sync manager's timer */ public void resetSync() { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "*** WebSyncManager resetSync ***"); } if (mHandler == null) { @@ -125,7 +124,7 @@ abstract class WebSyncManager implements Runnable { * startSync() requests sync manager to start sync */ public void startSync() { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "*** WebSyncManager startSync ***, Ref count:" + mStartSyncRefCount); } @@ -143,7 +142,7 @@ abstract class WebSyncManager implements Runnable { * the queue to break the sync loop */ public void stopSync() { - if (Config.LOGV) { + if (WebView.LOGV_ENABLED) { Log.v(LOGTAG, "*** WebSyncManager stopSync ***, Ref count:" + mStartSyncRefCount); } diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index a5846ed07778..a926355f6f51 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -42,7 +42,6 @@ import android.text.IClipboard; import android.text.Selection; import android.text.Spannable; import android.util.AttributeSet; -import android.util.Config; import android.util.EventLog; import android.util.Log; import android.view.Gravity; @@ -110,7 +109,7 @@ public class WebView extends AbsoluteLayout // keep debugging parameters near the top of the file static final String LOGTAG = "webview"; static final boolean DEBUG = false; - static final boolean LOGV_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; + static final boolean LOGV_ENABLED = DEBUG; private class ExtendedZoomControls extends FrameLayout { public ExtendedZoomControls(Context context, AttributeSet attrs) { diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 72b30f65f1f5..58d8ae75eec5 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -29,7 +29,6 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Process; -import android.util.Config; import android.util.Log; import android.util.SparseBooleanArray; import android.view.KeyEvent; @@ -43,7 +42,7 @@ final class WebViewCore { private static final String LOGTAG = "webcore"; static final boolean DEBUG = false; - static final boolean LOGV_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; + static final boolean LOGV_ENABLED = DEBUG; static { // Load libwebcore during static initialization. This happens in the diff --git a/core/java/android/webkit/gears/AndroidWifiDataProvider.java b/core/java/android/webkit/gears/AndroidWifiDataProvider.java index 7379f5953588..d2850b060386 100644 --- a/core/java/android/webkit/gears/AndroidWifiDataProvider.java +++ b/core/java/android/webkit/gears/AndroidWifiDataProvider.java @@ -33,7 +33,6 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; import android.os.Handler; import android.os.Looper; -import android.util.Config; import android.util.Log; import android.webkit.WebView; import java.util.List; @@ -48,6 +47,11 @@ public final class AndroidWifiDataProvider extends BroadcastReceiver { */ private static final String TAG = "Gears-J-WifiProvider"; /** + * Flag for guarding Log.v() calls. + * Set to true to enable extra debug logging. + */ + private static final boolean LOGV_ENABLED = false; + /** * Our Wifi manager instance. */ private WifiManager mWifiManager; @@ -104,7 +108,7 @@ public final class AndroidWifiDataProvider extends BroadcastReceiver { */ public void shutdown() { mContext.unregisterReceiver(this); - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.v(TAG, "Wifi provider closed."); } } @@ -118,7 +122,7 @@ public final class AndroidWifiDataProvider extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { if (intent.getAction().equals( mWifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.v(TAG, "Wifi scan resulst available"); } onUpdateAvailable(mWifiManager.getScanResults(), mNativeObject); diff --git a/core/java/android/webkit/gears/ApacheHttpRequestAndroid.java b/core/java/android/webkit/gears/ApacheHttpRequestAndroid.java index 529e666dbb8e..74d27edd29b9 100644 --- a/core/java/android/webkit/gears/ApacheHttpRequestAndroid.java +++ b/core/java/android/webkit/gears/ApacheHttpRequestAndroid.java @@ -29,7 +29,6 @@ import android.net.http.Headers; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.util.Config; import android.util.Log; import android.webkit.CacheManager; import android.webkit.CacheManager.CacheResult; @@ -88,6 +87,8 @@ import java.util.concurrent.locks.ReentrantLock; public final class ApacheHttpRequestAndroid { /** Debug logging tag. */ private static final String LOG_TAG = "Gears-J"; + /** Flag for guarding Log.v() calls. */ + private static final boolean LOGV_ENABLED = false; /** HTTP response header line endings are CR-LF style. */ private static final String HTTP_LINE_ENDING = "\r\n"; /** Safe MIME type to use whenever it isn't specified. */ @@ -173,18 +174,18 @@ public final class ApacheHttpRequestAndroid { public void run() { boolean problem = false; try { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "REQUEST : " + mMethod.getRequestLine()); } mResponse = mClient.execute(mMethod); if (mResponse != null) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "response (status line): " + mResponse.getStatusLine()); } mResponseLine = "" + mResponse.getStatusLine(); } else { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "problem, response == null"); } problem = true; @@ -198,7 +199,7 @@ public final class ApacheHttpRequestAndroid { } if (!problem) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Request complete (" + mMethod.getRequestLine() + ")"); } @@ -206,7 +207,7 @@ public final class ApacheHttpRequestAndroid { mConnectionFailedLock.lock(); mConnectionFailed = true; mConnectionFailedLock.unlock(); - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Request FAILED (" + mMethod.getRequestLine() + ")"); } @@ -233,7 +234,7 @@ public final class ApacheHttpRequestAndroid { try { wait(); } catch (InterruptedException e) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "InterruptedException while putting " + "a DataPacket in the Buffer: " + e); } @@ -248,7 +249,7 @@ public final class ApacheHttpRequestAndroid { try { wait(); } catch (InterruptedException e) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "InterruptedException while getting " + "a DataPacket in the Buffer: " + e); } @@ -271,7 +272,7 @@ public final class ApacheHttpRequestAndroid { try { wait(); } catch (InterruptedException e) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "InterruptedException while waiting " + "until a DataPacket is consumed: " + e); } @@ -285,7 +286,7 @@ public final class ApacheHttpRequestAndroid { try { wait(); } catch (InterruptedException e) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "InterruptedException while indicating " + "that the DataPacket has been consumed: " + e); } @@ -373,14 +374,14 @@ public final class ApacheHttpRequestAndroid { mSignal.packetConsumed(); mConnectionFailedLock.lock(); if (mConnectionFailed) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "stopping loop on error"); } finished = true; } mConnectionFailedLock.unlock(); } - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "flushing the outputstream..."); } mOutputStream.flush(); @@ -399,7 +400,7 @@ public final class ApacheHttpRequestAndroid { private void write(DataPacket packet) { try { if (mOutputStream == null) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "NO OUTPUT STREAM !!!"); } return; @@ -407,7 +408,7 @@ public final class ApacheHttpRequestAndroid { mOutputStream.write(packet.getBytes(), 0, packet.getLength()); mOutputStream.flush(); } catch (IOException e) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "exc: " + e); } mConnectionFailedLock.lock(); @@ -423,7 +424,7 @@ public final class ApacheHttpRequestAndroid { mStreamingReady.await(); } } catch (InterruptedException e) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "InterruptedException in " + "StreamEntity::isReady() : ", e); } @@ -468,7 +469,7 @@ public final class ApacheHttpRequestAndroid { * False on failure. */ public synchronized boolean open(String method, String url) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "open " + method + " " + url); } // Create the client @@ -502,7 +503,7 @@ public final class ApacheHttpRequestAndroid { } else if ("DELETE".equalsIgnoreCase(method)) { mMethod = new HttpDelete(url); } else { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Method " + method + " not supported"); } return false; @@ -549,7 +550,7 @@ public final class ApacheHttpRequestAndroid { * (unless already finished) */ private void waitUntilConnectionFinished() { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "waitUntilConnectionFinished(" + mConnectionFinished + ")"); } @@ -558,11 +559,11 @@ public final class ApacheHttpRequestAndroid { try { mHttpThread.join(); mConnectionFinished = true; - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "http thread joined"); } } catch (InterruptedException e) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "interrupted: " + e); } } @@ -596,7 +597,7 @@ public final class ApacheHttpRequestAndroid { Header[] headers = mResponse.getAllHeaders(); for (int i = 0; i < headers.length; i++) { Header header = headers[i]; - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "header " + header.getName() + " -> " + header.getValue()); } @@ -615,7 +616,7 @@ public final class ApacheHttpRequestAndroid { */ public synchronized void setRequestHeader(String name, String value) { String[] mapValue = { name, value }; - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "setRequestHeader: " + name + " => " + value); } if (name.equalsIgnoreCase(KEY_CONTENT_LENGTH)) { @@ -647,7 +648,7 @@ public final class ApacheHttpRequestAndroid { while (it.hasNext()) { // Set the key case-sensitive. String[] entry = it.next(); - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "apply header " + entry[HEADERS_MAP_INDEX_KEY] + " => " + entry[HEADERS_MAP_INDEX_VALUE]); } @@ -671,7 +672,7 @@ public final class ApacheHttpRequestAndroid { return null; } } else { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "getResponseHeader() called but " + "response not received"); } @@ -687,7 +688,7 @@ public final class ApacheHttpRequestAndroid { */ public synchronized String getAllResponseHeaders() { if (mResponseHeaders == null) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "getAllResponseHeaders() called but " + "response not received"); } @@ -715,7 +716,7 @@ public final class ApacheHttpRequestAndroid { * @param value The associated value. */ private void setResponseHeader(String name, String value) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Set response header " + name + ": " + value); } String mapValue[] = { name, value }; @@ -766,7 +767,7 @@ public final class ApacheHttpRequestAndroid { UrlInterceptHandlerGears.ServiceResponse serviceResponse = handler.getServiceResponse(url, mRequestHeaders); if (serviceResponse == null) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "No response in LocalServer"); } return false; @@ -776,7 +777,7 @@ public final class ApacheHttpRequestAndroid { mBodyInputStream = serviceResponse.getInputStream(); mResponseLine = serviceResponse.getStatusLine(); mResponseHeaders = serviceResponse.getResponseHeaders(); - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Got response from LocalServer: " + mResponseLine); } return true; @@ -803,19 +804,19 @@ public final class ApacheHttpRequestAndroid { CacheResult mCacheResult = CacheManager.getCacheFile(url, cacheRequestHeaders); if (mCacheResult == null) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "No CacheResult for " + url); } return false; } - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Got CacheResult from browser cache"); } // Check for expiry. -1 is "never", otherwise milliseconds since 1970. // Can be compared to System.currentTimeMillis(). long expires = mCacheResult.getExpires(); if (expires >= 0 && System.currentTimeMillis() >= expires) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "CacheResult expired " + (System.currentTimeMillis() - expires) + " milliseconds ago"); @@ -827,7 +828,7 @@ public final class ApacheHttpRequestAndroid { mBodyInputStream = mCacheResult.getInputStream(); if (mBodyInputStream == null) { // Cache result may have gone away. - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "No mBodyInputStream for CacheResult " + url); } return false; @@ -855,7 +856,7 @@ public final class ApacheHttpRequestAndroid { } // Synthesize the response line. mResponseLine = "HTTP/1.1 " + statusCode + " " + statusMessage; - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Synthesized " + mResponseLine); } // Synthesize the returned headers from cache. @@ -914,7 +915,7 @@ public final class ApacheHttpRequestAndroid { */ public synchronized boolean createCacheResult( String url, int responseCode, String mimeType, String encoding) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Making cache entry for " + url); } // Take the headers and parse them into a format needed by @@ -935,14 +936,14 @@ public final class ApacheHttpRequestAndroid { mCacheResult = CacheManager.createCacheFile( url, responseCode, cacheHeaders, mimeType, true); if (mCacheResult != null) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Saving into cache"); } mCacheResult.setEncoding(encoding); mCacheResultUrl = url; return true; } else { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Couldn't create mCacheResult"); } return false; @@ -960,7 +961,7 @@ public final class ApacheHttpRequestAndroid { */ public synchronized boolean appendCacheResult(byte[] data, int bytes) { if (mCacheResult == null) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "appendCacheResult() called without a " + "CacheResult initialized"); } @@ -969,7 +970,7 @@ public final class ApacheHttpRequestAndroid { try { mCacheResult.getOutputStream().write(data, 0, bytes); } catch (IOException ex) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Got IOException writing cache data: " + ex); } return false; @@ -984,14 +985,14 @@ public final class ApacheHttpRequestAndroid { */ public synchronized boolean saveCacheResult() { if (mCacheResult == null || mCacheResultUrl == null) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Tried to save cache result but " + "createCacheResult not called"); } return false; } - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Saving cache result"); } CacheManager.saveCacheFile(mCacheResultUrl, mCacheResult); @@ -1006,7 +1007,7 @@ public final class ApacheHttpRequestAndroid { * ability to receive a null packet for sendPostData(). */ public synchronized void abort() { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "ABORT CALLED"); } if (mMethod != null) { @@ -1019,7 +1020,7 @@ public final class ApacheHttpRequestAndroid { * thread to complete. */ public synchronized void interrupt() { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "INTERRUPT CALLED"); } mConnectionFailedLock.lock(); @@ -1053,7 +1054,7 @@ public final class ApacheHttpRequestAndroid { mBodyInputStream = entity.getContent(); } } catch (IOException inputException) { - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Failed to connect InputStream: " + inputException); } @@ -1062,7 +1063,7 @@ public final class ApacheHttpRequestAndroid { } if (mBodyInputStream == null) { // No error stream either. Treat as a 0 byte response. - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "No InputStream"); } return 0; // EOF. @@ -1081,7 +1082,7 @@ public final class ApacheHttpRequestAndroid { } } catch (IOException e) { // An abort() interrupts us by calling close() on our stream. - if (Config.LOGV) { + if (LOGV_ENABLED) { Log.i(LOG_TAG, "Got IOException in mBodyInputStream.read(): ", e); } ret = -1; diff --git a/core/java/com/android/internal/app/IUsageStats.aidl b/core/java/com/android/internal/app/IUsageStats.aidl index 6b053d5c9975..1ea74090a419 100755 --- a/core/java/com/android/internal/app/IUsageStats.aidl +++ b/core/java/com/android/internal/app/IUsageStats.aidl @@ -22,6 +22,7 @@ import com.android.internal.os.PkgUsageStats; interface IUsageStats { void noteResumeComponent(in ComponentName componentName); void notePauseComponent(in ComponentName componentName); + void noteLaunchTime(in ComponentName componentName, int millis); PkgUsageStats getPkgUsageStats(in ComponentName componentName); PkgUsageStats[] getAllPkgUsageStats(); } diff --git a/core/java/com/android/internal/util/BitwiseInputStream.java b/core/java/com/android/internal/util/BitwiseInputStream.java new file mode 100644 index 000000000000..5da3bc64fc91 --- /dev/null +++ b/core/java/com/android/internal/util/BitwiseInputStream.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2008 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.util; + +/** + * An object that provides bitwise incremental read access to a byte array. + * + * This is useful, for example, when accessing a series of fields that + * may not be aligned on byte boundaries. + * + * NOTE -- This class is not threadsafe. + */ +public class BitwiseInputStream { + + // The byte array being read from. + private byte[] mBuf; + + // The current position offset, in bits, from the msb in byte 0. + private int mPos; + + // The last valid bit offset. + private int mEnd; + + /** + * An exception to report access problems. + */ + public static class AccessException extends Exception { + public AccessException(String s) { + super("BitwiseInputStream access failed: " + s); + } + } + + /** + * Create object from byte array. + * + * @param buf a byte array containing data + */ + public BitwiseInputStream(byte buf[]) { + mBuf = buf; + mEnd = buf.length * 8; + mPos = 0; + } + + /** + * Return the number of bit still available for reading. + */ + public int available() { + return mEnd - mPos; + } + + /** + * Read some data and increment the current position. + * + * @param bits the amount of data to read (gte 0, lte 8) + * + * @return byte of read data (possibly partially filled, from lsb) + */ + public byte read(int bits) throws AccessException { + int index = mPos / 8; + int offset = 16 - (mPos % 8) - bits; + if ((bits < 0) || (bits > 8) || ((mPos + bits) > mEnd)) { + throw new AccessException("illegal read " + + "(pos " + mPos + ", end " + mEnd + ", bits " + bits + ")"); + } + int data = (mBuf[index] & 0xFF) << 8; + if (offset < 8) data |= (mBuf[index + 1] & 0xFF); + data >>>= offset; + data &= (-1 >>> (32 - bits)); + mPos += bits; + return (byte)data; + } + + /** + * Read data in bulk into a byte array and increment the current position. + * + * @param bits the amount of data to read + * + * @return newly allocated byte array of read data + */ + public byte[] readByteArray(int bits) throws AccessException { + int bytes = (bits / 8) + ((bits % 8) > 0 ? 1 : 0); + byte[] arr = new byte[bytes]; + for (int i = 0; i < bytes; i++) { + int increment = Math.min(8, bits - (i * 8)); + arr[i] = (byte)(read(increment) << (8 - increment)); + } + return arr; + } + + /** + * Increment the current position and ignore contained data. + * + * @param bits the amount by which to increment the position + */ + public void skip(int bits) throws AccessException { + if ((mPos + bits) > mEnd) { + throw new AccessException("illegal skip " + + "(pos " + mPos + ", end " + mEnd + ", bits " + bits + ")"); + } + mPos += bits; + } +} diff --git a/core/java/com/android/internal/util/BitwiseOutputStream.java b/core/java/com/android/internal/util/BitwiseOutputStream.java new file mode 100644 index 000000000000..5941bf3203e9 --- /dev/null +++ b/core/java/com/android/internal/util/BitwiseOutputStream.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008 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.util; + +/** + * An object that rovides bitwise incremental write access to a byte array. + * + * This is useful, for example, when writing a series of fields that + * may not be aligned on byte boundaries. + * + * NOTE -- This class is not threadsafe. + */ +public class BitwiseOutputStream { + + // The byte array being written to, which will be grown as needed. + private byte[] mBuf; + + // The current position offset, in bits, from the msb in byte 0. + private int mPos; + + // The last bit offset, given the current buf length. + private int mEnd; + + /** + * An exception to report access problems. + */ + public static class AccessException extends Exception { + public AccessException(String s) { + super("BitwiseOutputStream access failed: " + s); + } + } + + /** + * Create object from hint at desired size. + * + * @param startingLength initial internal byte array length in bytes + */ + public BitwiseOutputStream(int startingLength) { + mBuf = new byte[startingLength]; + mEnd = startingLength * 8; + mPos = 0; + } + + /** + * Return byte array containing accumulated data, sized to just fit. + * + * @return newly allocated byte array + */ + public byte[] toByteArray() { + int len = (mPos / 8) + ((mPos % 8) > 0 ? 1 : 0); + byte[] newBuf = new byte[len]; + System.arraycopy(mBuf, 0, newBuf, 0, len); + return newBuf; + } + + /** + * Allocate a new internal buffer, if needed. + * + * @param bits additional bits to be accommodated + */ + private void possExpand(int bits) { + if ((mPos + bits) < mEnd) return; + byte[] newBuf = new byte[((mPos + bits) * 2) / 8]; + System.arraycopy(mBuf, 0, newBuf, 0, mEnd / 8); + mBuf = newBuf; + } + + /** + * Write some data and increment the current position. + * + * @param bits the amount of data to write (gte 0, lte 8) + * @param data to write, will be masked to expose only bits param from lsb + */ + public void write(int bits, int data) throws AccessException { + if ((bits < 0) || (bits > 8)) { + throw new AccessException("illegal write (" + bits + " bits)"); + } + possExpand(bits); + data &= (-1 >>> (32 - bits)); + int index = mPos / 8; + int offset = 16 - (mPos % 8) - bits; + data <<= offset; + mPos += bits; + mBuf[index] |= (data >>> 8); + if (offset < 8) mBuf[index + 1] |= (data & 0xFF); + } + + /** + * Write data in bulk from a byte array and increment the current position. + * + * @param bits the amount of data to write + * @param arr the byte array containing data to be written + */ + public void writeByteArray(int bits, byte[] arr) throws AccessException { + for (int i = 0; i < arr.length; i++) { + int increment = Math.min(8, bits - (i * 8)); + if (increment > 0) { + write(increment, (byte)(arr[i] >>> (8 - increment))); + } + } + } + + /** + * Increment the current position, implicitly writing zeros. + * + * @param bits the amount by which to increment the position + */ + public void skip(int bits) { + possExpand(bits); + mPos += bits; + } +} diff --git a/core/jni/android_location_GpsLocationProvider.cpp b/core/jni/android_location_GpsLocationProvider.cpp index f0b35e977ef1..bbde8d50f3df 100644 --- a/core/jni/android_location_GpsLocationProvider.cpp +++ b/core/jni/android_location_GpsLocationProvider.cpp @@ -31,6 +31,7 @@ static pthread_cond_t sEventCond = PTHREAD_COND_INITIALIZER; static jmethodID method_reportLocation; static jmethodID method_reportStatus; static jmethodID method_reportSvStatus; +static jmethodID method_reportSuplStatus; static jmethodID method_xtraDownloadRequest; static const GpsInterface* sGpsInterface = NULL; @@ -41,19 +42,22 @@ static const GpsSuplInterface* sGpsSuplInterface = NULL; static GpsLocation sGpsLocation; static GpsStatus sGpsStatus; static GpsSvStatus sGpsSvStatus; +static GpsSuplStatus sGpsSuplStatus; // a copy of the data shared by android_location_GpsLocationProvider_wait_for_event // and android_location_GpsLocationProvider_read_status static GpsLocation sGpsLocationCopy; static GpsStatus sGpsStatusCopy; static GpsSvStatus sGpsSvStatusCopy; +static GpsSuplStatus sGpsSuplStatusCopy; enum CallbackType { kLocation = 1, kStatus = 2, kSvStatus = 4, - kXtraDownloadRequest = 8, - kDisableRequest = 16, + kSuplStatus = 8, + kXtraDownloadRequest = 16, + kDisableRequest = 32, }; static int sPendingCallbacks; @@ -92,6 +96,17 @@ static void sv_status_callback(GpsSvStatus* sv_status) pthread_mutex_unlock(&sEventMutex); } +static void supl_status_callback(GpsSuplStatus* supl_status) +{ + pthread_mutex_lock(&sEventMutex); + + sPendingCallbacks |= kSuplStatus; + memcpy(&sGpsSuplStatus, supl_status, sizeof(GpsSuplStatus)); + + pthread_cond_signal(&sEventCond); + pthread_mutex_unlock(&sEventMutex); +} + GpsCallbacks sGpsCallbacks = { location_callback, status_callback, @@ -111,11 +126,15 @@ GpsXtraCallbacks sGpsXtraCallbacks = { download_request_callback, }; +GpsSuplCallbacks sGpsSuplCallbacks = { + supl_status_callback, +}; static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V"); method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V"); + method_reportSuplStatus = env->GetMethodID(clazz, "reportSuplStatus", "(I)V"); method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); } @@ -129,7 +148,13 @@ static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject o { if (!sGpsInterface) sGpsInterface = gps_get_interface(); - return (sGpsInterface && sGpsInterface->init(&sGpsCallbacks) == 0); + if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) + return false; + + if (!sGpsSuplInterface) + sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); + if (sGpsSuplInterface) + sGpsSuplInterface->init(&sGpsSuplCallbacks); } static void android_location_GpsLocationProvider_disable(JNIEnv* env, jobject obj) @@ -186,6 +211,7 @@ static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, job memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy)); memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy)); memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy)); + memcpy(&sGpsSuplStatusCopy, &sGpsSuplStatus, sizeof(sGpsSuplStatusCopy)); pthread_mutex_unlock(&sEventMutex); if (pendingCallbacks & kLocation) { @@ -201,6 +227,9 @@ static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, job if (pendingCallbacks & kSvStatus) { env->CallVoidMethod(obj, method_reportSvStatus); } + if (pendingCallbacks & kSuplStatus) { + env->CallVoidMethod(obj, method_reportSuplStatus, sGpsSuplStatusCopy.status); + } if (pendingCallbacks & kXtraDownloadRequest) { env->CallVoidMethod(obj, method_xtraDownloadRequest); } @@ -269,30 +298,50 @@ static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, j env->ReleaseByteArrayElements(data, bytes, 0); } -static void android_location_GpsLocationProvider_set_supl_server(JNIEnv* env, jobject obj, - jint addr, jint port) +static void android_location_GpsLocationProvider_supl_data_conn_open(JNIEnv* env, jobject obj, jstring apn) { if (!sGpsSuplInterface) { sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); } if (sGpsSuplInterface) { - sGpsSuplInterface->set_server(addr, port); + if (apn == NULL) { + jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + return; + } + const char *apnStr = env->GetStringUTFChars(apn, NULL); + sGpsSuplInterface->data_conn_open(apnStr); + env->ReleaseStringUTFChars(apn, apnStr); } } -static void android_location_GpsLocationProvider_set_supl_apn(JNIEnv* env, jobject obj, jstring apn) +static void android_location_GpsLocationProvider_supl_data_conn_closed(JNIEnv* env, jobject obj) { if (!sGpsSuplInterface) { sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); } if (sGpsSuplInterface) { - if (apn == NULL) { - jniThrowException(env, "java/lang/IllegalArgumentException", NULL); - return; - } - const char *apnStr = env->GetStringUTFChars(apn, NULL); - sGpsSuplInterface->set_apn(apnStr); - env->ReleaseStringUTFChars(apn, apnStr); + sGpsSuplInterface->data_conn_closed(); + } +} + +static void android_location_GpsLocationProvider_supl_data_conn_failed(JNIEnv* env, jobject obj) +{ + if (!sGpsSuplInterface) { + sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); + } + if (sGpsSuplInterface) { + sGpsSuplInterface->data_conn_failed(); + } +} + +static void android_location_GpsLocationProvider_set_supl_server(JNIEnv* env, jobject obj, + jint addr, jint port) +{ + if (!sGpsSuplInterface) { + sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); + } + if (sGpsSuplInterface) { + sGpsSuplInterface->set_server(addr, port); } } @@ -312,8 +361,10 @@ static JNINativeMethod sMethods[] = { {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time}, {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra}, {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data}, + {"native_supl_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_supl_data_conn_open}, + {"native_supl_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_closed}, + {"native_supl_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_failed}, {"native_set_supl_server", "(II)V", (void*)android_location_GpsLocationProvider_set_supl_server}, - {"native_set_supl_apn", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_set_supl_apn}, }; int register_android_location_GpsLocationProvider(JNIEnv* env) diff --git a/location/java/android/location/IGeocodeProvider.aidl b/location/java/android/location/IGeocodeProvider.aidl new file mode 100644 index 000000000000..e79e8d2db623 --- /dev/null +++ b/location/java/android/location/IGeocodeProvider.aidl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2009 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 android.location; + +import android.location.Address; + +/** + * An interface for location providers implementing the Geocoder services. + * + * {@hide} + */ +interface IGeocodeProvider { + + String getFromLocation(double latitude, double longitude, int maxResults, + String language, String country, String variant, String appName, out List<Address> addrs); + + String getFromLocationName(String locationName, + double lowerLeftLatitude, double lowerLeftLongitude, + double upperRightLatitude, double upperRightLongitude, int maxResults, + String language, String country, String variant, String appName, out List<Address> addrs); +} diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index 86bd8b6e6f27..7d35814e513f 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -18,6 +18,7 @@ package android.location; import android.app.PendingIntent; import android.location.Address; +import android.location.IGeocodeProvider; import android.location.IGpsStatusListener; import android.location.ILocationCollector; import android.location.ILocationListener; @@ -77,7 +78,8 @@ interface ILocationManager void setTestProviderStatus(String provider, int status, in Bundle extras, long updateTime); void clearTestProviderStatus(String provider); - /* for installing Network Location Provider */ + /* for installing external Location Providers */ void setNetworkLocationProvider(ILocationProvider provider); void setLocationCollector(ILocationCollector collector); + void setGeocodeProvider(IGeocodeProvider provider); } diff --git a/location/java/android/location/ILocationProvider.aidl b/location/java/android/location/ILocationProvider.aidl index 6f9daff31064..08b924668954 100644 --- a/location/java/android/location/ILocationProvider.aidl +++ b/location/java/android/location/ILocationProvider.aidl @@ -16,7 +16,6 @@ package android.location; -import android.location.Address; import android.os.Bundle; /** @@ -52,10 +51,4 @@ interface ILocationProvider { void updateCellLockStatus(boolean acquired); void addListener(in String[] applications); void removeListener(in String[] applications); - String getFromLocation(double latitude, double longitude, int maxResults, - String language, String country, String variant, String appName, out List<Address> addrs); - String getFromLocationName(String locationName, - double lowerLeftLatitude, double lowerLeftLongitude, - double upperRightLatitude, double upperRightLongitude, int maxResults, - String language, String country, String variant, String appName, out List<Address> addrs); } diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java index 8a33574eb4aa..d56594e8e21f 100644 --- a/location/java/com/android/internal/location/GpsLocationProvider.java +++ b/location/java/com/android/internal/location/GpsLocationProvider.java @@ -28,6 +28,7 @@ import android.location.Location; import android.location.LocationManager; import android.location.LocationProvider; import android.location.LocationProviderImpl; +import android.net.ConnectivityManager; import android.net.SntpClient; import android.os.Bundle; import android.os.IBinder; @@ -99,6 +100,14 @@ public class GpsLocationProvider extends LocationProviderImpl { private static final int GPS_STATUS_ENGINE_ON = 3; private static final int GPS_STATUS_ENGINE_OFF = 4; + // these need to match GpsSuplStatusValue defines in gps.h + /** SUPL status event values. */ + private static final int GPS_REQUEST_SUPL_DATA_CONN = 1; + private static final int GPS_RELEASE_SUPL_DATA_CONN = 2; + private static final int GPS_SUPL_DATA_CONNECTED = 3; + private static final int GPS_SUPL_DATA_CONN_DONE = 4; + private static final int GPS_SUPL_DATA_CONN_FAILED = 5; + // these need to match GpsLocationFlags enum in gps.h private static final int LOCATION_INVALID = 0; private static final int LOCATION_HAS_LAT_LONG = 1; @@ -122,6 +131,11 @@ public class GpsLocationProvider extends LocationProviderImpl { private static final int GPS_DELETE_CELLDB_INFO = 0x8000; private static final int GPS_DELETE_ALL = 0xFFFF; + // for mSuplDataConnectionState + private static final int SUPL_DATA_CONNECTION_CLOSED = 0; + private static final int SUPL_DATA_CONNECTION_OPENING = 1; + private static final int SUPL_DATA_CONNECTION_OPEN = 2; + private static final String PROPERTIES_FILE = "/etc/gps.conf"; private int mLocationFlags = LOCATION_INVALID; @@ -176,6 +190,9 @@ public class GpsLocationProvider extends LocationProviderImpl { private String mSuplHost; private int mSuplPort; private boolean mSetSuplServer; + private String mSuplApn; + private int mSuplDataConnectionState; + private ConnectivityManager mConnMgr; // how often to request NTP time, in milliseconds // current setting 4 hours @@ -199,9 +216,11 @@ public class GpsLocationProvider extends LocationProviderImpl { Log.d(TAG, "state: " + state + " apnName: " + apnName + " reason: " + reason); } if ("CONNECTED".equals(state)) { - native_set_supl_apn(apnName); - } else { - native_set_supl_apn(""); + mSuplApn = apnName; + if (mSuplDataConnectionState == SUPL_DATA_CONNECTION_OPENING) { + native_supl_data_conn_open(mSuplApn); + mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPEN; + } } } } @@ -220,6 +239,8 @@ public class GpsLocationProvider extends LocationProviderImpl { intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); context.registerReceiver(receiver, intentFilter); + mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); + mProperties = new Properties(); try { File file = new File(PROPERTIES_FILE); @@ -782,7 +803,44 @@ public class GpsLocationProvider extends LocationProviderImpl { updateStatus(TEMPORARILY_UNAVAILABLE, mSvCount); } } - + + /** + * called from native code to update SUPL status + */ + private void reportSuplStatus(int status) { + switch (status) { + case GPS_REQUEST_SUPL_DATA_CONN: + int result = mConnMgr.startUsingNetworkFeature( + ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); + if (result == Phone.APN_ALREADY_ACTIVE) { + native_supl_data_conn_open(mSuplApn); + mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPEN; + } else if (result == Phone.APN_REQUEST_STARTED) { + mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPENING; + } else { + native_supl_data_conn_failed(); + } + break; + case GPS_RELEASE_SUPL_DATA_CONN: + if (mSuplDataConnectionState != SUPL_DATA_CONNECTION_CLOSED) { + mConnMgr.stopUsingNetworkFeature( + ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); + native_supl_data_conn_closed(); + mSuplDataConnectionState = SUPL_DATA_CONNECTION_CLOSED; + } + break; + case GPS_SUPL_DATA_CONNECTED: + // Log.d(TAG, "GPS_SUPL_DATA_CONNECTED"); + break; + case GPS_SUPL_DATA_CONN_DONE: + // Log.d(TAG, "GPS_SUPL_DATA_CONN_DONE"); + break; + case GPS_SUPL_DATA_CONN_FAILED: + // Log.d(TAG, "GPS_SUPL_DATA_CONN_FAILED"); + break; + } + } + private void xtraDownloadRequest() { if (Config.LOGD) Log.d(TAG, "xtraDownloadRequest"); if (mNetworkThread != null) { @@ -1002,6 +1060,8 @@ public class GpsLocationProvider extends LocationProviderImpl { private native void native_inject_xtra_data(byte[] data, int length); // SUPL Support + private native void native_supl_data_conn_open(String apn); + private native void native_supl_data_conn_closed(); + private native void native_supl_data_conn_failed(); private native void native_set_supl_server(int addr, int port); - private native void native_set_supl_apn(String apn); } diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java index 1f4940fed085..5b5b27a6d107 100644 --- a/location/java/com/android/internal/location/LocationProviderProxy.java +++ b/location/java/com/android/internal/location/LocationProviderProxy.java @@ -245,29 +245,4 @@ public class LocationProviderProxy extends LocationProviderImpl { Log.e(TAG, "removeListener failed", e); } } - - public String getFromLocation(double latitude, double longitude, int maxResults, - String language, String country, String variant, String appName, List<Address> addrs) { - try { - return mProvider.getFromLocation(latitude, longitude, maxResults, language, country, - variant, appName, addrs); - } catch (RemoteException e) { - Log.e(TAG, "getFromLocation failed", e); - return null; - } - } - - public String getFromLocationName(String locationName, - double lowerLeftLatitude, double lowerLeftLongitude, - double upperRightLatitude, double upperRightLongitude, int maxResults, - String language, String country, String variant, String appName, List<Address> addrs) { - try { - return mProvider.getFromLocationName(locationName, lowerLeftLatitude, - lowerLeftLongitude, upperRightLatitude, upperRightLongitude, - maxResults, language, country, variant, appName, addrs); - } catch (RemoteException e) { - Log.e(TAG, "getFromLocationName failed", e); - return null; - } - } } diff --git a/opengl/tools/glgen/gen b/opengl/tools/glgen/gen index c060040cec44..25e9a09f2768 100755 --- a/opengl/tools/glgen/gen +++ b/opengl/tools/glgen/gen @@ -1,4 +1,5 @@ -#!/bin/sh +#!/bin/bash +set -u rm -rf out generated mkdir out @@ -12,12 +13,18 @@ echo "public interface Canvas {}" >> out/android/graphics/Canvas.java GLFILE=out/javax/microedition/khronos/opengles/GL.java cp stubs/GLHeader.java-if $GLFILE -GLGEN_FILES="CFunc.java CType.java CodeEmitter.java GenerateGL.java JFunc.java JType.java JniCodeEmitter.java ParameterChecker.java" +GLGEN_FILES="CFunc.java CType.java CodeEmitter.java GenerateGL.java JFunc.java JniCodeEmitter.java JType.java Jsr239CodeEmitter.java ParameterChecker.java" pushd src > /dev/null javac ${GLGEN_FILES} +JAVAC_RESULT=$? +if [ $JAVAC_RESULT -ne 0 ]; then + echo "Could not compile glgen." + exit $JAVAC_RESULT +fi popd > /dev/null java -classpath src GenerateGL -c glspec-1.0 glspec-1.0ext glspec-1.1 glspec-1.1ext glspec-1.1extpack glspec-checks +rm src/*.class pushd out > /dev/null mkdir classes diff --git a/opengl/tools/glgen/src/.gitignore b/opengl/tools/glgen/src/.gitignore new file mode 100644 index 000000000000..6b468b62a988 --- /dev/null +++ b/opengl/tools/glgen/src/.gitignore @@ -0,0 +1 @@ +*.class diff --git a/opengl/tools/glgen/src/CFunc.java b/opengl/tools/glgen/src/CFunc.java index 0794f417427b..a89e1c59e4a5 100644 --- a/opengl/tools/glgen/src/CFunc.java +++ b/opengl/tools/glgen/src/CFunc.java @@ -1,155 +1,156 @@ -
-import java.util.*;
-
-public class CFunc {
-
- String original;
-
- CType ftype;
- String fname;
-
- List<String> argNames = new ArrayList<String>();
- List<CType> argTypes = new ArrayList<CType>();
-
- boolean hasPointerArg = false;
- boolean hasTypedPointerArg = false;
-
- public CFunc(String original) {
- this.original = original;
- }
-
- public String getOriginal() {
- return original;
- }
-
- public void setName(String fname) {
- this.fname = fname;
- }
-
- public String getName() {
- return fname;
- }
-
- public void setType(CType ftype) {
- this.ftype = ftype;
- }
-
- public CType getType() {
- return ftype;
- }
-
- public void addArgument(String argName, CType argType) {
- argNames.add(argName);
- argTypes.add(argType);
-
- if (argType.isPointer()) {
- hasPointerArg = true;
- }
- if (argType.isTypedPointer()) {
- hasTypedPointerArg = true;
- }
- }
-
- public int getNumArgs() {
- return argNames.size();
- }
-
- public int getArgIndex(String name) {
- int len = argNames.size();
- for (int i = 0; i < len; i++) {
- if (name.equals(argNames.get(i))) {
- return i;
- }
- }
- return -1;
- }
-
- public String getArgName(int index) {
- return argNames.get(index);
- }
-
- public CType getArgType(int index) {
- return argTypes.get(index);
- }
-
- public boolean hasPointerArg() {
- return hasPointerArg;
- }
-
- public boolean hasTypedPointerArg() {
- return hasTypedPointerArg;
- }
-
- public String toString() {
- String s = "Function " + fname + " returns " + ftype + ": ";
- for (int i = 0; i < argNames.size(); i++) {
- if (i > 0) {
- s += ", ";
- }
- s += argTypes.get(i) + " " + argNames.get(i);
- }
- return s;
- }
-
- public static CFunc parseCFunc(String s) {
- CFunc cfunc = new CFunc(s);
- String[] tokens = s.split("\\s");
-
- int i = 0;
- CType ftype = new CType();
- String ftypeName = tokens[i++];
- if (ftypeName.equals("const")) {
- ftype.setIsConst(true);
- ftypeName = tokens[i++];
- }
- ftype.setBaseType(ftypeName);
-
- String fname = tokens[i++];
- if (fname.equals("*")) {
- ftype.setIsPointer(true);
- fname = tokens[i++];
- }
-
- cfunc.setName(fname);
- cfunc.setType(ftype);
-
- while (i < tokens.length) {
- String tok = tokens[i++];
-
- if (tok.equals("(")) {
- continue;
- }
- if (tok.equals(")")) {
- break;
- }
-
- CType argType = new CType();
-
- String argTypeName = tok;
- String argName = "";
-
- if (argTypeName.equals("const")) {
- argType.setIsConst(true);
- argTypeName = tokens[i++];
- }
- argType.setBaseType(argTypeName);
-
- if (argTypeName.equals("void")) {
- break;
- }
-
- argName = tokens[i++];
- if (argName.startsWith("*")) {
- argType.setIsPointer(true);
- argName = argName.substring(1, argName.length());
- }
- if (argName.endsWith(",")) {
- argName = argName.substring(0, argName.length() - 1);
- }
-
- cfunc.addArgument(argName, argType);
- }
-
- return cfunc;
- }
-}
+ +import java.util.*; + +public class CFunc { + + String original; + + CType ftype; + String fname; + + List<String> argNames = new ArrayList<String>(); + List<CType> argTypes = new ArrayList<CType>(); + + boolean hasPointerArg = false; + boolean hasTypedPointerArg = false; + + public CFunc(String original) { + this.original = original; + } + + public String getOriginal() { + return original; + } + + public void setName(String fname) { + this.fname = fname; + } + + public String getName() { + return fname; + } + + public void setType(CType ftype) { + this.ftype = ftype; + } + + public CType getType() { + return ftype; + } + + public void addArgument(String argName, CType argType) { + argNames.add(argName); + argTypes.add(argType); + + if (argType.isPointer()) { + hasPointerArg = true; + } + if (argType.isTypedPointer()) { + hasTypedPointerArg = true; + } + } + + public int getNumArgs() { + return argNames.size(); + } + + public int getArgIndex(String name) { + int len = argNames.size(); + for (int i = 0; i < len; i++) { + if (name.equals(argNames.get(i))) { + return i; + } + } + return -1; + } + + public String getArgName(int index) { + return argNames.get(index); + } + + public CType getArgType(int index) { + return argTypes.get(index); + } + + public boolean hasPointerArg() { + return hasPointerArg; + } + + public boolean hasTypedPointerArg() { + return hasTypedPointerArg; + } + + @Override + public String toString() { + String s = "Function " + fname + " returns " + ftype + ": "; + for (int i = 0; i < argNames.size(); i++) { + if (i > 0) { + s += ", "; + } + s += argTypes.get(i) + " " + argNames.get(i); + } + return s; + } + + public static CFunc parseCFunc(String s) { + CFunc cfunc = new CFunc(s); + String[] tokens = s.split("\\s"); + + int i = 0; + CType ftype = new CType(); + String ftypeName = tokens[i++]; + if (ftypeName.equals("const")) { + ftype.setIsConst(true); + ftypeName = tokens[i++]; + } + ftype.setBaseType(ftypeName); + + String fname = tokens[i++]; + if (fname.equals("*")) { + ftype.setIsPointer(true); + fname = tokens[i++]; + } + + cfunc.setName(fname); + cfunc.setType(ftype); + + while (i < tokens.length) { + String tok = tokens[i++]; + + if (tok.equals("(")) { + continue; + } + if (tok.equals(")")) { + break; + } + + CType argType = new CType(); + + String argTypeName = tok; + String argName = ""; + + if (argTypeName.equals("const")) { + argType.setIsConst(true); + argTypeName = tokens[i++]; + } + argType.setBaseType(argTypeName); + + if (argTypeName.equals("void")) { + break; + } + + argName = tokens[i++]; + if (argName.startsWith("*")) { + argType.setIsPointer(true); + argName = argName.substring(1, argName.length()); + } + if (argName.endsWith(",")) { + argName = argName.substring(0, argName.length() - 1); + } + + cfunc.addArgument(argName, argType); + } + + return cfunc; + } +} diff --git a/opengl/tools/glgen/src/CType.java b/opengl/tools/glgen/src/CType.java index 331ec625a5e0..826c90d46f19 100644 --- a/opengl/tools/glgen/src/CType.java +++ b/opengl/tools/glgen/src/CType.java @@ -1,85 +1,88 @@ -
-public class CType {
-
- String baseType;
- boolean isConst;
- boolean isPointer;
-
- public CType() {
- }
-
- public CType(String baseType) {
- setBaseType(baseType);
- }
-
- public CType(String baseType, boolean isConst, boolean isPointer) {
- setBaseType(baseType);
- setIsConst(isConst);
- setIsPointer(isPointer);
- }
-
- public String getDeclaration() {
- return baseType + (isPointer ? " *" : "");
- }
-
- public void setIsConst(boolean isConst) {
- this.isConst = isConst;
- }
-
- public boolean isConst() {
- return isConst;
- }
-
- public void setIsPointer(boolean isPointer) {
- this.isPointer = isPointer;
- }
-
- public boolean isPointer() {
- return isPointer;
- }
-
- boolean isVoid() {
- String baseType = getBaseType();
- return baseType.equals("GLvoid") ||
- baseType.equals("void");
- }
-
- public boolean isTypedPointer() {
- return isPointer() && !isVoid();
- }
-
- public void setBaseType(String baseType) {
- this.baseType = baseType;
- }
-
- public String getBaseType() {
- return baseType;
- }
-
- public String toString() {
- String s = "";
- if (isConst()) {
- s += "const ";
- }
- s += baseType;
- if (isPointer()) {
- s += "*";
- }
-
- return s;
- }
-
- public int hashCode() {
- return baseType.hashCode() ^ (isPointer ? 2 : 0) ^ (isConst ? 1 : 0);
- }
-
- public boolean equals(Object o) {
- if (o != null && o instanceof CType) {
- CType c = (CType)o;
- return baseType.equals(c.baseType) &&
- isPointer() == c.isPointer() &&
- isConst() == c.isConst();
- }
- return false;
- }
-}
+ +public class CType { + + String baseType; + boolean isConst; + boolean isPointer; + + public CType() { + } + + public CType(String baseType) { + setBaseType(baseType); + } + + public CType(String baseType, boolean isConst, boolean isPointer) { + setBaseType(baseType); + setIsConst(isConst); + setIsPointer(isPointer); + } + + public String getDeclaration() { + return baseType + (isPointer ? " *" : ""); + } + + public void setIsConst(boolean isConst) { + this.isConst = isConst; + } + + public boolean isConst() { + return isConst; + } + + public void setIsPointer(boolean isPointer) { + this.isPointer = isPointer; + } + + public boolean isPointer() { + return isPointer; + } + + boolean isVoid() { + String baseType = getBaseType(); + return baseType.equals("GLvoid") || + baseType.equals("void"); + } + + public boolean isTypedPointer() { + return isPointer() && !isVoid(); + } + + public void setBaseType(String baseType) { + this.baseType = baseType; + } + + public String getBaseType() { + return baseType; + } + + @Override + public String toString() { + String s = ""; + if (isConst()) { + s += "const "; + } + s += baseType; + if (isPointer()) { + s += "*"; + } + + return s; + } + + @Override + public int hashCode() { + return baseType.hashCode() ^ (isPointer ? 2 : 0) ^ (isConst ? 1 : 0); + } + + @Override + public boolean equals(Object o) { + if (o != null && o instanceof CType) { + CType c = (CType)o; + return baseType.equals(c.baseType) && + isPointer() == c.isPointer() && + isConst() == c.isConst(); + } + return false; + } +} diff --git a/opengl/tools/glgen/src/CodeEmitter.java b/opengl/tools/glgen/src/CodeEmitter.java index 3e9b90aab881..ebb97277e55f 100644 --- a/opengl/tools/glgen/src/CodeEmitter.java +++ b/opengl/tools/glgen/src/CodeEmitter.java @@ -1,8 +1,8 @@ -
-public interface CodeEmitter {
-
- void setVersion(int version, boolean ext, boolean pack);
- void emitCode(CFunc cfunc, String original);
- void addNativeRegistration(String fname);
- void emitNativeRegistration();
-}
+ +public interface CodeEmitter { + + void setVersion(int version, boolean ext, boolean pack); + void emitCode(CFunc cfunc, String original); + void addNativeRegistration(String fname); + void emitNativeRegistration(); +} diff --git a/opengl/tools/glgen/src/GenerateGL.java b/opengl/tools/glgen/src/GenerateGL.java index 657ee6e7c7e0..accb16e965d7 100644 --- a/opengl/tools/glgen/src/GenerateGL.java +++ b/opengl/tools/glgen/src/GenerateGL.java @@ -1,164 +1,167 @@ -
-import java.io.*;
-import java.util.*;
-
-public class GenerateGL {
-
- static void copy(String filename, PrintStream out) throws IOException {
- BufferedReader br = new BufferedReader(new FileReader(filename));
- String s;
- while ((s = br.readLine()) != null) {
- out.println(s);
- }
- }
-
- private static void emit(int version, boolean ext, boolean pack,
- CodeEmitter emitter,
- BufferedReader specReader,
- PrintStream glStream,
- PrintStream glImplStream,
- PrintStream cStream) throws Exception {
- String s = null;
- int counter = 0;
- while ((s = specReader.readLine()) != null) {
- if (s.trim().startsWith("//")) {
- continue;
- }
-
- CFunc cfunc = CFunc.parseCFunc(s);
-
- String fname = cfunc.getName();
- File f = new File("stubs/" + fname +
- ".java-1" + version + "-if");
- if (f.exists()) {
- System.out.println("Special-casing function " + fname);
- copy("stubs/" + fname +
- ".java-1" + version + "-if", glStream);
- copy("stubs/" + fname + ".java-impl", glImplStream);
- copy("stubs/" + fname + ".cpp", cStream);
-
- // Register native function names
- // This should be improved to require fewer discrete files
- String filename = "stubs/" + fname + ".nativeReg";
- BufferedReader br =
- new BufferedReader(new FileReader(filename));
- String nfunc;
- while ((nfunc = br.readLine()) != null) {
- emitter.addNativeRegistration(nfunc);
- }
- } else {
- emitter.setVersion(version, ext, pack);
- emitter.emitCode(cfunc, s);
- }
- }
- }
-
- public static void main(String[] args) throws Exception {
- String classPathName = "com/google/android/gles_jni/GLImpl";
- boolean useContextPointer = true;
-
- int aidx = 0;
- while (args[aidx].charAt(0) == '-') {
- switch (args[aidx].charAt(1)) {
- case 'c':
- useContextPointer = false;
- break;
-
- default:
- System.err.println("Unknown flag: " + args[aidx]);
- System.exit(1);
- }
-
- aidx++;
- }
-
- System.out.println("useContextPointer = " + useContextPointer);
-
- BufferedReader spec10Reader =
- new BufferedReader(new FileReader(args[aidx++]));
- BufferedReader spec10ExtReader =
- new BufferedReader(new FileReader(args[aidx++]));
- BufferedReader spec11Reader =
- new BufferedReader(new FileReader(args[aidx++]));
- BufferedReader spec11ExtReader =
- new BufferedReader(new FileReader(args[aidx++]));
- BufferedReader spec11ExtPackReader =
- new BufferedReader(new FileReader(args[aidx++]));
- BufferedReader checksReader =
- new BufferedReader(new FileReader(args[aidx++]));
-
- String gl10Filename = "javax/microedition/khronos/opengles/GL10.java";
- String gl10ExtFilename =
- "javax/microedition/khronos/opengles/GL10Ext.java";
- String gl11Filename = "javax/microedition/khronos/opengles/GL11.java";
- String gl11ExtFilename =
- "javax/microedition/khronos/opengles/GL11Ext.java";
- String gl11ExtPackFilename =
- "javax/microedition/khronos/opengles/GL11ExtensionPack.java";
- String glImplFilename = "com/google/android/gles_jni/GLImpl.java";
- String cFilename = "com_google_android_gles_jni_GLImpl.cpp";
-
- PrintStream gl10Stream =
- new PrintStream(new FileOutputStream("out/" + gl10Filename));
- PrintStream gl10ExtStream =
- new PrintStream(new FileOutputStream("out/" + gl10ExtFilename));
- PrintStream gl11Stream =
- new PrintStream(new FileOutputStream("out/" + gl11Filename));
- PrintStream gl11ExtStream =
- new PrintStream(new FileOutputStream("out/" + gl11ExtFilename));
- PrintStream gl11ExtPackStream =
- new PrintStream(new FileOutputStream("out/" + gl11ExtPackFilename));
- PrintStream glImplStream =
- new PrintStream(new FileOutputStream("out/" + glImplFilename));
- PrintStream cStream =
- new PrintStream(new FileOutputStream("out/" + cFilename));
-
- ParameterChecker checker = new ParameterChecker(checksReader);
-
- CodeEmitter emitter =
- new JniCodeEmitter(classPathName,
- checker,
- gl10Stream, gl10ExtStream,
- gl11Stream, gl11ExtStream, gl11ExtPackStream,
- glImplStream, cStream,
- useContextPointer);
-
- gl10Stream.println("/* //device/java/android/" + gl10Filename);
- gl10ExtStream.println("/* //device/java/android/" + gl10ExtFilename);
- gl11Stream.println("/* //device/java/android/" + gl11Filename);
- gl11ExtStream.println("/* //device/java/android/" + gl11ExtFilename);
- gl11ExtPackStream.println("/* //device/java/android/" +
- gl11ExtPackFilename);
- glImplStream.println("/* //device/java/android/" + glImplFilename);
- cStream.println("/* //device/libs/android_runtime/" + cFilename);
-
- copy("stubs/GL10Header.java-if", gl10Stream);
- copy("stubs/GL10ExtHeader.java-if", gl10ExtStream);
- copy("stubs/GL11Header.java-if", gl11Stream);
- copy("stubs/GL11ExtHeader.java-if", gl11ExtStream);
- copy("stubs/GL11ExtensionPackHeader.java-if", gl11ExtPackStream);
- copy("stubs/GLImplHeader.java-impl", glImplStream);
- copy("stubs/GLCHeader.cpp", cStream);
-
- emit(0, false, false,
- emitter, spec10Reader, gl10Stream, glImplStream, cStream);
- emit(0, true, false,
- emitter, spec10ExtReader, gl10ExtStream, glImplStream, cStream);
- emit(1, false, false,
- emitter, spec11Reader, gl11Stream, glImplStream, cStream);
- emit(1, true, false,
- emitter, spec11ExtReader, gl11ExtStream, glImplStream, cStream);
- emit(1, true, true,
- emitter, spec11ExtPackReader, gl11ExtPackStream, glImplStream,
- cStream);
-
- emitter.emitNativeRegistration();
-
- gl10Stream.println("}");
- gl10ExtStream.println("}");
- gl11Stream.println("}");
- gl11ExtStream.println("}");
- gl11ExtPackStream.println("}");
- glImplStream.println("}");
- }
-}
+ +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintStream; + +public class GenerateGL { + + static void copy(String filename, PrintStream out) throws IOException { + BufferedReader br = new BufferedReader(new FileReader(filename)); + String s; + while ((s = br.readLine()) != null) { + out.println(s); + } + } + + private static void emit(int version, boolean ext, boolean pack, + CodeEmitter emitter, + BufferedReader specReader, + PrintStream glStream, + PrintStream glImplStream, + PrintStream cStream) throws Exception { + String s = null; + while ((s = specReader.readLine()) != null) { + if (s.trim().startsWith("//")) { + continue; + } + + CFunc cfunc = CFunc.parseCFunc(s); + + String fname = cfunc.getName(); + File f = new File("stubs/" + fname + + ".java-1" + version + "-if"); + if (f.exists()) { + System.out.println("Special-casing function " + fname); + copy("stubs/" + fname + + ".java-1" + version + "-if", glStream); + copy("stubs/" + fname + ".java-impl", glImplStream); + copy("stubs/" + fname + ".cpp", cStream); + + // Register native function names + // This should be improved to require fewer discrete files + String filename = "stubs/" + fname + ".nativeReg"; + BufferedReader br = + new BufferedReader(new FileReader(filename)); + String nfunc; + while ((nfunc = br.readLine()) != null) { + emitter.addNativeRegistration(nfunc); + } + } else { + emitter.setVersion(version, ext, pack); + emitter.emitCode(cfunc, s); + } + } + } + + public static void main(String[] args) throws Exception { + String classPathName = "com/google/android/gles_jni/GLImpl"; + boolean useContextPointer = true; + + int aidx = 0; + while (args[aidx].charAt(0) == '-') { + switch (args[aidx].charAt(1)) { + case 'c': + useContextPointer = false; + break; + + default: + System.err.println("Unknown flag: " + args[aidx]); + System.exit(1); + } + + aidx++; + } + + System.out.println("useContextPointer = " + useContextPointer); + + BufferedReader spec10Reader = + new BufferedReader(new FileReader(args[aidx++])); + BufferedReader spec10ExtReader = + new BufferedReader(new FileReader(args[aidx++])); + BufferedReader spec11Reader = + new BufferedReader(new FileReader(args[aidx++])); + BufferedReader spec11ExtReader = + new BufferedReader(new FileReader(args[aidx++])); + BufferedReader spec11ExtPackReader = + new BufferedReader(new FileReader(args[aidx++])); + BufferedReader checksReader = + new BufferedReader(new FileReader(args[aidx++])); + + String gl10Filename = "javax/microedition/khronos/opengles/GL10.java"; + String gl10ExtFilename = + "javax/microedition/khronos/opengles/GL10Ext.java"; + String gl11Filename = "javax/microedition/khronos/opengles/GL11.java"; + String gl11ExtFilename = + "javax/microedition/khronos/opengles/GL11Ext.java"; + String gl11ExtPackFilename = + "javax/microedition/khronos/opengles/GL11ExtensionPack.java"; + String glImplFilename = "com/google/android/gles_jni/GLImpl.java"; + String cFilename = "com_google_android_gles_jni_GLImpl.cpp"; + + PrintStream gl10Stream = + new PrintStream(new FileOutputStream("out/" + gl10Filename)); + PrintStream gl10ExtStream = + new PrintStream(new FileOutputStream("out/" + gl10ExtFilename)); + PrintStream gl11Stream = + new PrintStream(new FileOutputStream("out/" + gl11Filename)); + PrintStream gl11ExtStream = + new PrintStream(new FileOutputStream("out/" + gl11ExtFilename)); + PrintStream gl11ExtPackStream = + new PrintStream(new FileOutputStream("out/" + gl11ExtPackFilename)); + PrintStream glImplStream = + new PrintStream(new FileOutputStream("out/" + glImplFilename)); + PrintStream cStream = + new PrintStream(new FileOutputStream("out/" + cFilename)); + + ParameterChecker checker = new ParameterChecker(checksReader); + + CodeEmitter emitter = + new Jsr239CodeEmitter(classPathName, + checker, + gl10Stream, gl10ExtStream, + gl11Stream, gl11ExtStream, gl11ExtPackStream, + glImplStream, cStream, + useContextPointer); + + gl10Stream.println("/* //device/java/android/" + gl10Filename); + gl10ExtStream.println("/* //device/java/android/" + gl10ExtFilename); + gl11Stream.println("/* //device/java/android/" + gl11Filename); + gl11ExtStream.println("/* //device/java/android/" + gl11ExtFilename); + gl11ExtPackStream.println("/* //device/java/android/" + + gl11ExtPackFilename); + glImplStream.println("/* //device/java/android/" + glImplFilename); + cStream.println("/* //device/libs/android_runtime/" + cFilename); + + copy("stubs/GL10Header.java-if", gl10Stream); + copy("stubs/GL10ExtHeader.java-if", gl10ExtStream); + copy("stubs/GL11Header.java-if", gl11Stream); + copy("stubs/GL11ExtHeader.java-if", gl11ExtStream); + copy("stubs/GL11ExtensionPackHeader.java-if", gl11ExtPackStream); + copy("stubs/GLImplHeader.java-impl", glImplStream); + copy("stubs/GLCHeader.cpp", cStream); + + emit(0, false, false, + emitter, spec10Reader, gl10Stream, glImplStream, cStream); + emit(0, true, false, + emitter, spec10ExtReader, gl10ExtStream, glImplStream, cStream); + emit(1, false, false, + emitter, spec11Reader, gl11Stream, glImplStream, cStream); + emit(1, true, false, + emitter, spec11ExtReader, gl11ExtStream, glImplStream, cStream); + emit(1, true, true, + emitter, spec11ExtPackReader, gl11ExtPackStream, glImplStream, + cStream); + + emitter.emitNativeRegistration(); + + gl10Stream.println("}"); + gl10ExtStream.println("}"); + gl11Stream.println("}"); + gl11ExtStream.println("}"); + gl11ExtPackStream.println("}"); + glImplStream.println("}"); + } +} diff --git a/opengl/tools/glgen/src/JFunc.java b/opengl/tools/glgen/src/JFunc.java index 42d466c33ed6..68f717c81956 100644 --- a/opengl/tools/glgen/src/JFunc.java +++ b/opengl/tools/glgen/src/JFunc.java @@ -1,148 +1,149 @@ -
-import java.util.ArrayList;
-import java.util.List;
-
-public class JFunc {
-
- String className = "com.google.android.gles_jni.GL11Impl";
-
- CFunc cfunc;
- JType ftype;
- String fname;
-
- List<String> argNames = new ArrayList<String>();
- List<JType> argTypes = new ArrayList<JType>();
- List<Integer> argCIndices = new ArrayList<Integer>();
-
- boolean hasBufferArg = false;
- boolean hasTypedBufferArg = false;
- ArrayList<String> bufferArgNames = new ArrayList<String>();
-
- public JFunc(CFunc cfunc) {
- this.cfunc = cfunc;
- }
-
- public CFunc getCFunc() {
- return cfunc;
- }
-
- public void setName(String fname) {
- this.fname = fname;
- }
-
- public String getName() {
- return fname;
- }
-
- public void setType(JType ftype) {
- this.ftype = ftype;
- }
-
- public JType getType() {
- return ftype;
- }
-
- public void setClassName(String className) {
- this.className = className;
- }
-
- public String getClassName() {
- return className;
- }
-
- public boolean hasBufferArg() {
- return hasBufferArg;
- }
-
- public boolean hasTypedBufferArg() {
- return hasTypedBufferArg;
- }
-
- public String getBufferArgName(int index) {
- return bufferArgNames.get(index);
- }
-
- public void addArgument(String argName, JType argType, int cindex) {
- argNames.add(argName);
- argTypes.add(argType);
- argCIndices.add(new Integer(cindex));
-
- if (argType.isBuffer()) {
- hasBufferArg = true;
- bufferArgNames.add(argName);
- }
- if (argType.isTypedBuffer()) {
- hasTypedBufferArg = true;
- bufferArgNames.add(argName);
- }
- }
-
- public int getNumArgs() {
- return argNames.size();
- }
-
- public int getArgIndex(String name) {
- int len = argNames.size();
- for (int i = 0; i < len; i++) {
- if (name.equals(argNames.get(i))) {
- return i;
- }
- }
- return -1;
- }
-
- public String getArgName(int index) {
- return argNames.get(index);
- }
-
- public JType getArgType(int index) {
- return argTypes.get(index);
- }
-
- public int getArgCIndex(int index) {
- return argCIndices.get(index).intValue();
- }
-
- public static JFunc convert(CFunc cfunc, boolean useArray) {
- JFunc jfunc = new JFunc(cfunc);
- jfunc.setName(cfunc.getName());
- jfunc.setType(JType.convert(cfunc.getType(), false));
-
- int numArgs = cfunc.getNumArgs();
- int numOffsets = 0;
- for (int i = 0; i < numArgs; i++) {
- CType cArgType = cfunc.getArgType(i);
- if (cArgType.isTypedPointer() && useArray) {
- ++numOffsets;
- }
- }
-
- for (int i = 0; i < numArgs; i++) {
- String cArgName = cfunc.getArgName(i);
- CType cArgType = cfunc.getArgType(i);
-
- jfunc.addArgument(cArgName, JType.convert(cArgType, useArray), i);
- if (cArgType.isTypedPointer() && useArray) {
- if (numOffsets > 1) {
- jfunc.addArgument(cArgName + "Offset", new JType("int"), i);
- } else {
- jfunc.addArgument("offset", new JType("int"), i);
- }
- }
- }
-
- return jfunc;
- }
-
- public String toString() {
- String s = "Function " + fname + " returns " + ftype + ": ";
- for (int i = 0; i < argNames.size(); i++) {
- if (i > 0) {
- s += ", ";
- }
- s += argTypes.get(i) + " " + argNames.get(i);
- }
- return s;
- }
-
-}
+ +import java.util.ArrayList; +import java.util.List; + +public class JFunc { + + String className = "com.google.android.gles_jni.GL11Impl"; + + CFunc cfunc; + JType ftype; + String fname; + + List<String> argNames = new ArrayList<String>(); + List<JType> argTypes = new ArrayList<JType>(); + List<Integer> argCIndices = new ArrayList<Integer>(); + + boolean hasBufferArg = false; + boolean hasTypedBufferArg = false; + ArrayList<String> bufferArgNames = new ArrayList<String>(); + + public JFunc(CFunc cfunc) { + this.cfunc = cfunc; + } + + public CFunc getCFunc() { + return cfunc; + } + + public void setName(String fname) { + this.fname = fname; + } + + public String getName() { + return fname; + } + + public void setType(JType ftype) { + this.ftype = ftype; + } + + public JType getType() { + return ftype; + } + + public void setClassName(String className) { + this.className = className; + } + + public String getClassName() { + return className; + } + + public boolean hasBufferArg() { + return hasBufferArg; + } + + public boolean hasTypedBufferArg() { + return hasTypedBufferArg; + } + + public String getBufferArgName(int index) { + return bufferArgNames.get(index); + } + + public void addArgument(String argName, JType argType, int cindex) { + argNames.add(argName); + argTypes.add(argType); + argCIndices.add(new Integer(cindex)); + + if (argType.isBuffer()) { + hasBufferArg = true; + bufferArgNames.add(argName); + } + if (argType.isTypedBuffer()) { + hasTypedBufferArg = true; + bufferArgNames.add(argName); + } + } + + public int getNumArgs() { + return argNames.size(); + } + + public int getArgIndex(String name) { + int len = argNames.size(); + for (int i = 0; i < len; i++) { + if (name.equals(argNames.get(i))) { + return i; + } + } + return -1; + } + + public String getArgName(int index) { + return argNames.get(index); + } + + public JType getArgType(int index) { + return argTypes.get(index); + } + + public int getArgCIndex(int index) { + return argCIndices.get(index).intValue(); + } + + public static JFunc convert(CFunc cfunc, boolean useArray) { + JFunc jfunc = new JFunc(cfunc); + jfunc.setName(cfunc.getName()); + jfunc.setType(JType.convert(cfunc.getType(), false)); + + int numArgs = cfunc.getNumArgs(); + int numOffsets = 0; + for (int i = 0; i < numArgs; i++) { + CType cArgType = cfunc.getArgType(i); + if (cArgType.isTypedPointer() && useArray) { + ++numOffsets; + } + } + + for (int i = 0; i < numArgs; i++) { + String cArgName = cfunc.getArgName(i); + CType cArgType = cfunc.getArgType(i); + + jfunc.addArgument(cArgName, JType.convert(cArgType, useArray), i); + if (cArgType.isTypedPointer() && useArray) { + if (numOffsets > 1) { + jfunc.addArgument(cArgName + "Offset", new JType("int"), i); + } else { + jfunc.addArgument("offset", new JType("int"), i); + } + } + } + + return jfunc; + } + + @Override + public String toString() { + String s = "Function " + fname + " returns " + ftype + ": "; + for (int i = 0; i < argNames.size(); i++) { + if (i > 0) { + s += ", "; + } + s += argTypes.get(i) + " " + argNames.get(i); + } + return s; + } + +} diff --git a/opengl/tools/glgen/src/JType.java b/opengl/tools/glgen/src/JType.java index a16d4400d83f..5ad0e5486f84 100644 --- a/opengl/tools/glgen/src/JType.java +++ b/opengl/tools/glgen/src/JType.java @@ -1,139 +1,140 @@ -
-import java.util.HashMap;
-
-public class JType {
-
- String baseType;
- boolean isArray;
- boolean isClass;
-
- static HashMap<CType,JType> typeMapping = new HashMap<CType,JType>();
- static HashMap<CType,JType> arrayTypeMapping = new HashMap<CType,JType>();
-
- static {
- // Primitive types
- typeMapping.put(new CType("GLbitfield"), new JType("int"));
- typeMapping.put(new CType("GLboolean"), new JType("boolean"));
- typeMapping.put(new CType("GLclampf"), new JType("float"));
- typeMapping.put(new CType("GLclampx"), new JType("int"));
- typeMapping.put(new CType("GLenum"), new JType("int"));
- typeMapping.put(new CType("GLfloat"), new JType("float"));
- typeMapping.put(new CType("GLfixed"), new JType("int"));
- typeMapping.put(new CType("GLint"), new JType("int"));
- typeMapping.put(new CType("GLintptr"), new JType("int"));
- typeMapping.put(new CType("GLshort"), new JType("short"));
- typeMapping.put(new CType("GLsizei"), new JType("int"));
- typeMapping.put(new CType("GLsizeiptr"), new JType("int"));
- typeMapping.put(new CType("GLubyte"), new JType("byte"));
- typeMapping.put(new CType("GLuint"), new JType("int"));
- typeMapping.put(new CType("void"), new JType("void"));
- typeMapping.put(new CType("GLubyte", true, true), new JType("String"));
-
- // Untyped pointers map to untyped Buffers
- typeMapping.put(new CType("GLvoid", true, true),
- new JType("java.nio.Buffer", true, false));
- typeMapping.put(new CType("GLvoid", false, true),
- new JType("java.nio.Buffer", true, false));
- typeMapping.put(new CType("void", false, true),
- new JType("java.nio.Buffer", true, false));
-
- // Typed pointers map to typed Buffers
- typeMapping.put(new CType("GLboolean", false, true),
- new JType("java.nio.IntBuffer", true, false));
- typeMapping.put(new CType("GLfixed", false, true),
- new JType("java.nio.IntBuffer", true, false));
- typeMapping.put(new CType("GLfixed", true, true),
- new JType("java.nio.IntBuffer", true, false));
- typeMapping.put(new CType("GLfloat", false, true),
- new JType("java.nio.FloatBuffer", true, false));
- typeMapping.put(new CType("GLfloat", true, true),
- new JType("java.nio.FloatBuffer", true, false));
- typeMapping.put(new CType("GLint", false, true),
- new JType("java.nio.IntBuffer", true, false));
- typeMapping.put(new CType("GLint", true, true),
- new JType("java.nio.IntBuffer", true, false));
- typeMapping.put(new CType("GLuint", false, true),
- new JType("java.nio.IntBuffer", true, false));
- typeMapping.put(new CType("GLuint", true, true),
- new JType("java.nio.IntBuffer", true, false));
- typeMapping.put(new CType("GLshort", true, true),
- new JType("java.nio.ShortBuffer", true, false));
-
- // Typed pointers map to arrays + offsets
- arrayTypeMapping.put(new CType("GLboolean", false, true),
- new JType("boolean", false, true));
- arrayTypeMapping.put(new CType("GLfixed", true, true), new JType("int", false, true));
- arrayTypeMapping.put(new CType("GLfixed", false, true), new JType("int", false, true));
- arrayTypeMapping.put(new CType("GLfloat", false, true), new JType("float", false, true));
- arrayTypeMapping.put(new CType("GLfloat", true, true), new JType("float", false, true));
- arrayTypeMapping.put(new CType("GLint", false, true), new JType("int", false, true));
- arrayTypeMapping.put(new CType("GLint", true, true), new JType("int", false, true));
- arrayTypeMapping.put(new CType("GLshort", true, true), new JType("short", false, true));
- arrayTypeMapping.put(new CType("GLuint", false, true), new JType("int", false, true));
- arrayTypeMapping.put(new CType("GLuint", true, true), new JType("int", false, true));
- arrayTypeMapping.put(new CType("GLintptr"), new JType("int", false, true));
- arrayTypeMapping.put(new CType("GLsizeiptr"), new JType("int", false, true));
- }
-
- public JType() {
- }
-
- public JType(String primitiveTypeName) {
- this.baseType = primitiveTypeName;
- this.isClass = false;
- this.isArray = false;
- }
-
- public JType(String primitiveTypeName, boolean isClass, boolean isArray) {
- this.baseType = primitiveTypeName;
- this.isClass = isClass;
- this.isArray = isArray;
- }
-
- public String getBaseType() {
- return baseType;
- }
-
- public String toString() {
- return baseType + (isArray ? "[]" : "");
- }
-
- public boolean isArray() {
- return isArray;
- }
-
- public boolean isClass() {
- return isClass;
- }
-
- public boolean isPrimitive() {
- return !isClass() && !isArray();
- }
-
- public boolean isVoid() {
- return baseType.equals("void");
- }
-
- public boolean isBuffer() {
- return baseType.indexOf("Buffer") != -1;
- }
-
- public boolean isTypedBuffer() {
- return !baseType.equals("java.nio.Buffer") &&
- (baseType.indexOf("Buffer") != -1);
- }
-
- public static JType convert(CType ctype, boolean useArray) {
- JType javaType = null;
- if (useArray) {
- javaType = arrayTypeMapping.get(ctype);
- }
- if (javaType == null) {
- javaType = typeMapping.get(ctype);
- }
- if (javaType == null) {
- throw new RuntimeException("Unsupported C type: " + ctype);
- }
- return javaType;
- }
-}
+ +import java.util.HashMap; + +public class JType { + + String baseType; + boolean isArray; + boolean isClass; + + static HashMap<CType,JType> typeMapping = new HashMap<CType,JType>(); + static HashMap<CType,JType> arrayTypeMapping = new HashMap<CType,JType>(); + + static { + // Primitive types + typeMapping.put(new CType("GLbitfield"), new JType("int")); + typeMapping.put(new CType("GLboolean"), new JType("boolean")); + typeMapping.put(new CType("GLclampf"), new JType("float")); + typeMapping.put(new CType("GLclampx"), new JType("int")); + typeMapping.put(new CType("GLenum"), new JType("int")); + typeMapping.put(new CType("GLfloat"), new JType("float")); + typeMapping.put(new CType("GLfixed"), new JType("int")); + typeMapping.put(new CType("GLint"), new JType("int")); + typeMapping.put(new CType("GLintptr"), new JType("int")); + typeMapping.put(new CType("GLshort"), new JType("short")); + typeMapping.put(new CType("GLsizei"), new JType("int")); + typeMapping.put(new CType("GLsizeiptr"), new JType("int")); + typeMapping.put(new CType("GLubyte"), new JType("byte")); + typeMapping.put(new CType("GLuint"), new JType("int")); + typeMapping.put(new CType("void"), new JType("void")); + typeMapping.put(new CType("GLubyte", true, true), new JType("String")); + + // Untyped pointers map to untyped Buffers + typeMapping.put(new CType("GLvoid", true, true), + new JType("java.nio.Buffer", true, false)); + typeMapping.put(new CType("GLvoid", false, true), + new JType("java.nio.Buffer", true, false)); + typeMapping.put(new CType("void", false, true), + new JType("java.nio.Buffer", true, false)); + + // Typed pointers map to typed Buffers + typeMapping.put(new CType("GLboolean", false, true), + new JType("java.nio.IntBuffer", true, false)); + typeMapping.put(new CType("GLfixed", false, true), + new JType("java.nio.IntBuffer", true, false)); + typeMapping.put(new CType("GLfixed", true, true), + new JType("java.nio.IntBuffer", true, false)); + typeMapping.put(new CType("GLfloat", false, true), + new JType("java.nio.FloatBuffer", true, false)); + typeMapping.put(new CType("GLfloat", true, true), + new JType("java.nio.FloatBuffer", true, false)); + typeMapping.put(new CType("GLint", false, true), + new JType("java.nio.IntBuffer", true, false)); + typeMapping.put(new CType("GLint", true, true), + new JType("java.nio.IntBuffer", true, false)); + typeMapping.put(new CType("GLuint", false, true), + new JType("java.nio.IntBuffer", true, false)); + typeMapping.put(new CType("GLuint", true, true), + new JType("java.nio.IntBuffer", true, false)); + typeMapping.put(new CType("GLshort", true, true), + new JType("java.nio.ShortBuffer", true, false)); + + // Typed pointers map to arrays + offsets + arrayTypeMapping.put(new CType("GLboolean", false, true), + new JType("boolean", false, true)); + arrayTypeMapping.put(new CType("GLfixed", true, true), new JType("int", false, true)); + arrayTypeMapping.put(new CType("GLfixed", false, true), new JType("int", false, true)); + arrayTypeMapping.put(new CType("GLfloat", false, true), new JType("float", false, true)); + arrayTypeMapping.put(new CType("GLfloat", true, true), new JType("float", false, true)); + arrayTypeMapping.put(new CType("GLint", false, true), new JType("int", false, true)); + arrayTypeMapping.put(new CType("GLint", true, true), new JType("int", false, true)); + arrayTypeMapping.put(new CType("GLshort", true, true), new JType("short", false, true)); + arrayTypeMapping.put(new CType("GLuint", false, true), new JType("int", false, true)); + arrayTypeMapping.put(new CType("GLuint", true, true), new JType("int", false, true)); + arrayTypeMapping.put(new CType("GLintptr"), new JType("int", false, true)); + arrayTypeMapping.put(new CType("GLsizeiptr"), new JType("int", false, true)); + } + + public JType() { + } + + public JType(String primitiveTypeName) { + this.baseType = primitiveTypeName; + this.isClass = false; + this.isArray = false; + } + + public JType(String primitiveTypeName, boolean isClass, boolean isArray) { + this.baseType = primitiveTypeName; + this.isClass = isClass; + this.isArray = isArray; + } + + public String getBaseType() { + return baseType; + } + + @Override + public String toString() { + return baseType + (isArray ? "[]" : ""); + } + + public boolean isArray() { + return isArray; + } + + public boolean isClass() { + return isClass; + } + + public boolean isPrimitive() { + return !isClass() && !isArray(); + } + + public boolean isVoid() { + return baseType.equals("void"); + } + + public boolean isBuffer() { + return baseType.indexOf("Buffer") != -1; + } + + public boolean isTypedBuffer() { + return !baseType.equals("java.nio.Buffer") && + (baseType.indexOf("Buffer") != -1); + } + + public static JType convert(CType ctype, boolean useArray) { + JType javaType = null; + if (useArray) { + javaType = arrayTypeMapping.get(ctype); + } + if (javaType == null) { + javaType = typeMapping.get(ctype); + } + if (javaType == null) { + throw new RuntimeException("Unsupported C type: " + ctype); + } + return javaType; + } +} diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java index 33b9a3e538f6..9d37607c851e 100644 --- a/opengl/tools/glgen/src/JniCodeEmitter.java +++ b/opengl/tools/glgen/src/JniCodeEmitter.java @@ -1,99 +1,54 @@ import java.io.PrintStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; -/** - * Emits a Java interface and Java & C implementation for a C function. - * - * <p> The Java interface will have Buffer and array variants for functions that - * have a typed pointer argument. The array variant will convert a single "<type> *data" - * argument to a pair of arguments "<type>[] data, int offset". - */ -public class JniCodeEmitter implements CodeEmitter { - - // If true, use C++ style for calling through a JNIEnv *: - // env->Func(...) - // If false, use C style: - // (*env)->Func(env, ...) - static final boolean mUseCPlusPlus = true; - - boolean mUseContextPointer = true; - - String mClassPathName; - - ParameterChecker mChecker; - PrintStream mJava10InterfaceStream; - PrintStream mJava10ExtInterfaceStream; - PrintStream mJava11InterfaceStream; - PrintStream mJava11ExtInterfaceStream; - PrintStream mJava11ExtPackInterfaceStream; - PrintStream mJavaImplStream; - PrintStream mCStream; - - PrintStream mJavaInterfaceStream; - - List<String> nativeRegistrations = new ArrayList<String>(); +public class JniCodeEmitter { + static final boolean mUseCPlusPlus = true; + protected boolean mUseContextPointer = true; + protected String mClassPathName; + protected ParameterChecker mChecker; + protected List<String> nativeRegistrations = new ArrayList<String>(); boolean needsExit; - - static String indent = " "; - + protected static String indent = " "; HashSet<String> mFunctionsEmitted = new HashSet<String>(); - /** - * @param java10InterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 functions - * @param java10ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 extension functions - * @param java11InterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 functions - * @param java11ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension functions - * @param java11ExtPackInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension Pack functions - * @param javaImplStream the PrintStream to which to emit the Java implementation - * @param cStream the PrintStream to which to emit the C implementation - */ - public JniCodeEmitter(String classPathName, - ParameterChecker checker, - PrintStream java10InterfaceStream, - PrintStream java10ExtInterfaceStream, - PrintStream java11InterfaceStream, - PrintStream java11ExtInterfaceStream, - PrintStream java11ExtPackInterfaceStream, - PrintStream javaImplStream, - PrintStream cStream, - boolean useContextPointer) { - mClassPathName = classPathName; - mChecker = checker; - mJava10InterfaceStream = java10InterfaceStream; - mJava10ExtInterfaceStream = java10ExtInterfaceStream; - mJava11InterfaceStream = java11InterfaceStream; - mJava11ExtInterfaceStream = java11ExtInterfaceStream; - mJava11ExtPackInterfaceStream = java11ExtPackInterfaceStream; - mJavaImplStream = javaImplStream; - mCStream = cStream; - mUseContextPointer = useContextPointer; - } + public static String getJniName(JType jType) { + String jniName = ""; + if (jType.isClass()) { + return "L" + jType.getBaseType() + ";"; + } else if (jType.isArray()) { + jniName = "["; + } - public void setVersion(int version, boolean ext, boolean pack) { - if (version == 0) { - mJavaInterfaceStream = ext ? mJava10ExtInterfaceStream : - mJava10InterfaceStream; - } else if (version == 1) { - mJavaInterfaceStream = ext ? - (pack ? mJava11ExtPackInterfaceStream : - mJava11ExtInterfaceStream) : - mJava11InterfaceStream; - } else { - throw new RuntimeException("Bad version: " + version); + String baseType = jType.getBaseType(); + if (baseType.equals("int")) { + jniName += "I"; + } else if (baseType.equals("float")) { + jniName += "F"; + } else if (baseType.equals("boolean")) { + jniName += "Z"; + } else if (baseType.equals("short")) { + jniName += "S"; + } else if (baseType.equals("long")) { + jniName += "L"; + } else if (baseType.equals("byte")) { + jniName += "B"; } + return jniName; } - public void emitCode(CFunc cfunc, String original) { + + public void emitCode(CFunc cfunc, String original, + PrintStream javaInterfaceStream, + PrintStream javaImplStream, + PrintStream cStream) { JFunc jfunc; String signature; boolean duplicate; - + if (cfunc.hasTypedPointerArg()) { jfunc = JFunc.convert(cfunc, true); @@ -109,12 +64,12 @@ public class JniCodeEmitter implements CodeEmitter { } if (!duplicate) { - emitNativeDeclaration(jfunc, mJavaImplStream); - emitJavaCode(jfunc, mJavaImplStream); + emitNativeDeclaration(jfunc, javaImplStream); + emitJavaCode(jfunc, javaImplStream); } - emitJavaInterfaceCode(jfunc, mJavaInterfaceStream); + emitJavaInterfaceCode(jfunc, javaInterfaceStream); if (!duplicate) { - emitJniCode(jfunc, mCStream); + emitJniCode(jfunc, cStream); } } @@ -129,12 +84,12 @@ public class JniCodeEmitter implements CodeEmitter { } if (!duplicate) { - emitNativeDeclaration(jfunc, mJavaImplStream); + emitNativeDeclaration(jfunc, javaImplStream); } - emitJavaInterfaceCode(jfunc, mJavaInterfaceStream); + emitJavaInterfaceCode(jfunc, javaInterfaceStream); if (!duplicate) { - emitJavaCode(jfunc, mJavaImplStream); - emitJniCode(jfunc, mCStream); + emitJavaCode(jfunc, javaImplStream); + emitJniCode(jfunc, cStream); } } @@ -152,8 +107,8 @@ public class JniCodeEmitter implements CodeEmitter { public void emitJavaCode(JFunc jfunc, PrintStream out) { emitFunction(jfunc, out, false, false); } - - void emitFunctionCall(JFunc jfunc, PrintStream out, String iii, boolean grabArray ) { + + void emitFunctionCall(JFunc jfunc, PrintStream out, String iii, boolean grabArray) { boolean isVoid = jfunc.getType().isVoid(); boolean isPointerFunc = jfunc.getName().endsWith("Pointer") && jfunc.getCFunc().hasPointerArg(); @@ -167,7 +122,7 @@ public class JniCodeEmitter implements CodeEmitter { jfunc.getName() + (isPointerFunc ? "Bounds" : "" ) + "("); - + int numArgs = jfunc.getNumArgs(); for (int i = 0; i < numArgs; i++) { String argName = jfunc.getArgName(i); @@ -177,7 +132,7 @@ public class JniCodeEmitter implements CodeEmitter { String typeName = argType.getBaseType(); typeName = typeName.substring(9, typeName.length() - 6); out.println(iii + indent + "get" + typeName + "Array(" + argName + "),"); - out.print(iii + indent + "getOffset(" + argName + ")"); + out.print(iii + indent + "getOffset(" + argName + ")"); } else { out.print(iii + indent + argName); } @@ -192,41 +147,40 @@ public class JniCodeEmitter implements CodeEmitter { out.println(","); } } - + out.println(iii + ");"); } - void printIfcheckPostamble(PrintStream out, boolean isBuffer, - boolean emitExceptionCheck, String iii) { - printIfcheckPostamble(out, isBuffer, emitExceptionCheck, - "offset", "_remaining", iii); - } + void printIfcheckPostamble(PrintStream out, boolean isBuffer, boolean emitExceptionCheck, + String iii) { + printIfcheckPostamble(out, isBuffer, emitExceptionCheck, + "offset", "_remaining", iii); + } - void printIfcheckPostamble(PrintStream out, boolean isBuffer, - boolean emitExceptionCheck, - String offset, String remaining, String iii) { - out.println(iii + " default:"); - out.println(iii + " _needed = 0;"); - out.println(iii + " break;"); - out.println(iii + "}"); + void printIfcheckPostamble(PrintStream out, boolean isBuffer, boolean emitExceptionCheck, + String offset, String remaining, String iii) { + out.println(iii + " default:"); + out.println(iii + " _needed = 0;"); + out.println(iii + " break;"); + out.println(iii + "}"); - out.println(iii + "if (" + remaining + " < _needed) {"); - if (emitExceptionCheck) { - out.println(iii + indent + "_exception = 1;"); - } - out.println(iii + indent + - (mUseCPlusPlus ? "_env" : "(*_env)") + - "->ThrowNew(" + - (mUseCPlusPlus ? "" : "_env, ") + - "IAEClass, " + - "\"" + - (isBuffer ? - "remaining()" : "length - " + offset) + - " < needed\");"); - out.println(iii + indent + "goto exit;"); - needsExit = true; - out.println(iii + "}"); - } + out.println(iii + "if (" + remaining + " < _needed) {"); + if (emitExceptionCheck) { + out.println(iii + indent + "_exception = 1;"); + } + out.println(iii + indent + + (mUseCPlusPlus ? "_env" : "(*_env)") + + "->ThrowNew(" + + (mUseCPlusPlus ? "" : "_env, ") + + "IAEClass, " + + "\"" + + (isBuffer ? + "remaining()" : "length - " + offset) + + " < needed\");"); + out.println(iii + indent + "goto exit;"); + needsExit = true; + out.println(iii + "}"); + } boolean isNullAllowed(CFunc cfunc) { String[] checks = mChecker.getChecks(cfunc.getName()); @@ -312,115 +266,106 @@ public class JniCodeEmitter implements CodeEmitter { } void emitNativeBoundsChecks(CFunc cfunc, String cname, PrintStream out, - boolean isBuffer, boolean emitExceptionCheck, - String offset, String remaining, String iii) { - CType returnType = cfunc.getType(); - boolean isVoid = returnType.isVoid(); - - String[] checks = mChecker.getChecks(cfunc.getName()); - String checkVar; - String retval = getErrorReturnValue(cfunc); - - boolean lastWasIfcheck = false; - - int index = 1; - if (checks != null) { - boolean remainingDeclared = false; - boolean nullCheckDeclared = false; - boolean offsetChecked = false; - while (index < checks.length) { - if (checks[index].startsWith("check")) { - if (lastWasIfcheck) { - printIfcheckPostamble(out, isBuffer, emitExceptionCheck, - offset, remaining, iii); - } - lastWasIfcheck = false; - if (cname != null && !cname.equals(checks[index + 1])) { - index += 3; - continue; - } - out.println(iii + "if (" + remaining + " < " + - checks[index + 2] + - ") {"); - if (emitExceptionCheck) { - out.println(iii + indent + "_exception = 1;"); - } - String exceptionClassName = "IAEClass"; - // If the "check" keyword was of the form - // "check_<class name>", use the class name in the - // exception to be thrown - int underscore = checks[index].indexOf('_'); - if (underscore >= 0) { - exceptionClassName = checks[index].substring(underscore + 1) + "Class"; - } - out.println(iii + indent + - (mUseCPlusPlus ? "_env" : "(*_env)") + - "->ThrowNew(" + - (mUseCPlusPlus ? "" : "_env, ") + - exceptionClassName + ", " + - "\"" + - (isBuffer ? - "remaining()" : "length - " + offset) + - " < " + checks[index + 2] + - "\");"); - - out.println(iii + indent + "goto exit;"); - needsExit = true; - out.println(iii + "}"); - - index += 3; - } else if (checks[index].equals("ifcheck")) { - String[] matches = checks[index + 4].split(","); - - if (!lastWasIfcheck) { - out.println(iii + "int _needed;"); - out.println(iii + - "switch (" + - checks[index + 3] + - ") {"); + boolean isBuffer, boolean emitExceptionCheck, String offset, String remaining, String iii) { + + String[] checks = mChecker.getChecks(cfunc.getName()); + + boolean lastWasIfcheck = false; + + int index = 1; + if (checks != null) { + while (index < checks.length) { + if (checks[index].startsWith("check")) { + if (lastWasIfcheck) { + printIfcheckPostamble(out, isBuffer, emitExceptionCheck, + offset, remaining, iii); + } + lastWasIfcheck = false; + if (cname != null && !cname.equals(checks[index + 1])) { + index += 3; + continue; + } + out.println(iii + "if (" + remaining + " < " + + checks[index + 2] + + ") {"); + if (emitExceptionCheck) { + out.println(iii + indent + "_exception = 1;"); + } + String exceptionClassName = "IAEClass"; + // If the "check" keyword was of the form + // "check_<class name>", use the class name in the + // exception to be thrown + int underscore = checks[index].indexOf('_'); + if (underscore >= 0) { + exceptionClassName = checks[index].substring(underscore + 1) + "Class"; } - - for (int i = 0; i < matches.length; i++) { - out.println("#if defined(" + matches[i] + ")"); - out.println(iii + - " case " + - matches[i] + - ":"); - out.println("#endif // defined(" + matches[i] + ")"); + out.println(iii + indent + + (mUseCPlusPlus ? "_env" : "(*_env)") + + "->ThrowNew(" + + (mUseCPlusPlus ? "" : "_env, ") + + exceptionClassName + ", " + + "\"" + + (isBuffer ? + "remaining()" : "length - " + offset) + + " < " + checks[index + 2] + + "\");"); + + out.println(iii + indent + "goto exit;"); + needsExit = true; + out.println(iii + "}"); + + index += 3; + } else if (checks[index].equals("ifcheck")) { + String[] matches = checks[index + 4].split(","); + + if (!lastWasIfcheck) { + out.println(iii + "int _needed;"); + out.println(iii + + "switch (" + + checks[index + 3] + + ") {"); + } + + for (int i = 0; i < matches.length; i++) { + out.println("#if defined(" + matches[i] + ")"); + out.println(iii + + " case " + + matches[i] + + ":"); + out.println("#endif // defined(" + matches[i] + ")"); + } + out.println(iii + + " _needed = " + + checks[index + 2] + + ";"); + out.println(iii + + " break;"); + + lastWasIfcheck = true; + index += 5; + } else if (checks[index].equals("return")) { + // ignore + index += 2; + } else if (checks[index].equals("unsupported")) { + // ignore + index += 1; + } else if (checks[index].equals("nullAllowed")) { + // ignore + index += 1; + } else { + System.out.println("Error: unknown keyword \"" + + checks[index] + "\""); + System.exit(0); + } } - out.println(iii + - " _needed = " + - checks[index + 2] + - ";"); - out.println(iii + - " break;"); - - lastWasIfcheck = true; - index += 5; - } else if (checks[index].equals("return")) { - // ignore - index += 2; - } else if (checks[index].equals("unsupported")) { - // ignore - index += 1; - } else if (checks[index].equals("nullAllowed")) { - // ignore - index += 1; - } else { - System.out.println("Error: unknown keyword \"" + - checks[index] + "\""); - System.exit(0); } - } - } - if (lastWasIfcheck) { - printIfcheckPostamble(out, isBuffer, emitExceptionCheck, iii); - } - } + if (lastWasIfcheck) { + printIfcheckPostamble(out, isBuffer, emitExceptionCheck, iii); + } + } - boolean hasNonConstArg(JFunc jfunc, CFunc cfunc, - List<Integer> nonPrimitiveArgs) { + boolean hasNonConstArg(JFunc jfunc, CFunc cfunc, List<Integer> nonPrimitiveArgs) { if (nonPrimitiveArgs.size() > 0) { for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) { int idx = nonPrimitiveArgs.get(i).intValue(); @@ -439,7 +384,7 @@ public class JniCodeEmitter implements CodeEmitter { return false; } - + /** * Emit a function in several variants: * @@ -449,9 +394,7 @@ public class JniCodeEmitter implements CodeEmitter { * if interfaceDecl: public <returntype> func(args); * if !interfaceDecl: public <returntype> func(args) { body } */ - void emitFunction(JFunc jfunc, - PrintStream out, - boolean nativeDecl, boolean interfaceDecl) { + void emitFunction(JFunc jfunc, PrintStream out, boolean nativeDecl, boolean interfaceDecl) { boolean isPointerFunc = jfunc.getName().endsWith("Pointer") && jfunc.getCFunc().hasPointerArg(); @@ -478,12 +421,12 @@ public class JniCodeEmitter implements CodeEmitter { jfunc.getName() + "("); } - + int numArgs = jfunc.getNumArgs(); for (int i = 0; i < numArgs; i++) { String argName = jfunc.getArgName(i); JType argType = jfunc.getArgType(i); - + out.print(indent + indent + argType + " " + argName); if (i == numArgs - 1) { if (isPointerFunc && nativeDecl) { @@ -561,29 +504,43 @@ public class JniCodeEmitter implements CodeEmitter { out.println(); } - public static String getJniName(JType jType) { - String jniName = ""; - if (jType.isClass()) { - return "L" + jType.getBaseType() + ";"; - } else if (jType.isArray()) { - jniName = "["; - } - - String baseType = jType.getBaseType(); - if (baseType.equals("int")) { - jniName += "I"; - } else if (baseType.equals("float")) { - jniName += "F"; - } else if (baseType.equals("boolean")) { - jniName += "Z"; - } else if (baseType.equals("short")) { - jniName += "S"; - } else if (baseType.equals("long")) { - jniName += "L"; - } else if (baseType.equals("byte")) { - jniName += "B"; + public void addNativeRegistration(String s) { + nativeRegistrations.add(s); + } + + public void emitNativeRegistration(PrintStream cStream) { + cStream.println("static const char *classPathName = \"" + + mClassPathName + + "\";"); + cStream.println(); + + cStream.println("static JNINativeMethod methods[] = {"); + + cStream.println("{\"_nativeClassInit\", \"()V\", (void*)nativeClassInit },"); + + Iterator<String> i = nativeRegistrations.iterator(); + while (i.hasNext()) { + cStream.println(i.next()); } - return jniName; + + cStream.println("};"); + cStream.println(); + + + cStream.println("int register_com_google_android_gles_jni_GLImpl(JNIEnv *_env)"); + cStream.println("{"); + cStream.println(indent + + "int err;"); + + cStream.println(indent + + "err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));"); + + cStream.println(indent + "return err;"); + cStream.println("}"); + } + + public JniCodeEmitter() { + super(); } String getJniType(JType jType) { @@ -604,7 +561,7 @@ public class JniCodeEmitter implements CodeEmitter { return "jobject"; } } - + String getJniMangledName(String name) { name = name.replaceAll("_", "_1"); name = name.replaceAll(";", "_2"); @@ -614,7 +571,7 @@ public class JniCodeEmitter implements CodeEmitter { public void emitJniCode(JFunc jfunc, PrintStream out) { CFunc cfunc = jfunc.getCFunc(); - + // Emit comment identifying original C function // // Example: @@ -658,13 +615,13 @@ public class JniCodeEmitter implements CodeEmitter { } // Append signature to function name - String sig = getJniMangledName(signature).replace('.', '_'); + String sig = getJniMangledName(signature).replace('.', '_'); out.print("__" + sig); outName += "__" + sig; - + signature = signature.replace('.', '/'); rsignature = rsignature.replace('.', '/'); - + out.println(); if (rsignature.length() == 0) { rsignature = "V"; @@ -718,13 +675,11 @@ public class JniCodeEmitter implements CodeEmitter { out.print(", jint remaining"); } out.println(") {"); - + int numArrays = 0; int numBuffers = 0; for (int i = 0; i < nonPrimitiveArgs.size(); i++) { int idx = nonPrimitiveArgs.get(i).intValue(); - int cIndex = jfunc.getArgCIndex(idx); - String cname = cfunc.getArgName(cIndex); if (jfunc.getArgType(idx).isArray()) { ++numArrays; } @@ -740,7 +695,7 @@ public class JniCodeEmitter implements CodeEmitter { // Example: // // android::gl::ogles_context_t *ctx; - // + // // jint _exception; // GLenum _returnValue; // @@ -827,15 +782,13 @@ public class JniCodeEmitter implements CodeEmitter { out.println(indent + decl + (decl.endsWith("*") ? "" : " ") + - jfunc.getArgName(idx) + + jfunc.getArgName(idx) + " = (" + decl + ") 0;"); } out.println(); } - String retval = isVoid ? "" : " _returnValue"; - // Emit 'GetPrimitiveArrayCritical' for arrays // Emit 'GetPointer' calls for Buffer pointers int bufArgIdx = 0; @@ -843,7 +796,7 @@ public class JniCodeEmitter implements CodeEmitter { for (int i = 0; i < nonPrimitiveArgs.size(); i++) { int idx = nonPrimitiveArgs.get(i).intValue(); int cIndex = jfunc.getArgCIndex(idx); - + String cname = cfunc.getArgName(cIndex); offset = numArrays <= 1 ? "offset" : cname + "Offset"; @@ -852,7 +805,7 @@ public class JniCodeEmitter implements CodeEmitter { if (jfunc.getArgType(idx).isArray()) { out.println(indent + - "if (!" + + "if (!" + cname + "_ref) {"); if (emitExceptionCheck) { @@ -884,7 +837,7 @@ public class JniCodeEmitter implements CodeEmitter { out.println(indent + "}"); out.println(indent + remaining + " = " + - (mUseCPlusPlus ? "_env" : "(*_env)") + + (mUseCPlusPlus ? "_env" : "(*_env)") + "->GetArrayLength(" + (mUseCPlusPlus ? "" : "_env, ") + cname + "_ref) - " + offset + ";"); @@ -901,7 +854,7 @@ public class JniCodeEmitter implements CodeEmitter { out.println(indent + " " + (mUseCPlusPlus ? "_env" : "(*_env)") + "->GetPrimitiveArrayCritical(" + - (mUseCPlusPlus ? "" : "_env, ") + + (mUseCPlusPlus ? "" : "_env, ") + jfunc.getArgName(idx) + "_ref, (jboolean *)0);"); out.println(indent + @@ -917,7 +870,7 @@ public class JniCodeEmitter implements CodeEmitter { out.println(indent + "if (" + cname + "_buf) {"); out.print(indent); } - + out.println(indent + cname + " = (" + @@ -950,10 +903,10 @@ public class JniCodeEmitter implements CodeEmitter { name.substring(1, name.length()); out.print("ctx->procs."); } - + out.print(name + (isPointerFunc ? "Bounds" : "") + "("); - numArgs = cfunc.getNumArgs(); + numArgs = cfunc.getNumArgs(); if (numArgs == 0) { if (mUseContextPointer) { out.println("ctx);"); @@ -1006,7 +959,7 @@ public class JniCodeEmitter implements CodeEmitter { int cIndex = jfunc.getArgCIndex(idx); if (jfunc.getArgType(idx).isArray()) { - + // If the argument is 'const', GL will not write to it. // In this case, we can use the 'JNI_ABORT' flag to avoid // the need to write back to the Java array @@ -1015,7 +968,7 @@ public class JniCodeEmitter implements CodeEmitter { out.println(indent + indent + (mUseCPlusPlus ? "_env" : "(*_env)") + "->ReleasePrimitiveArrayCritical(" + - (mUseCPlusPlus ? "" : "_env, ") + + (mUseCPlusPlus ? "" : "_env, ") + jfunc.getArgName(idx) + "_ref, " + cfunc.getArgName(cIndex) + "_base,"); @@ -1049,38 +1002,4 @@ public class JniCodeEmitter implements CodeEmitter { out.println(); } - public void addNativeRegistration(String s) { - nativeRegistrations.add(s); - } - - public void emitNativeRegistration() { - mCStream.println("static const char *classPathName = \"" + - mClassPathName + - "\";"); - mCStream.println(); - - mCStream.println("static JNINativeMethod methods[] = {"); - - mCStream.println("{\"_nativeClassInit\", \"()V\", (void*)nativeClassInit },"); - - Iterator<String> i = nativeRegistrations.iterator(); - while (i.hasNext()) { - mCStream.println(i.next()); - } - - mCStream.println("};"); - mCStream.println(); - - - mCStream.println("int register_com_google_android_gles_jni_GLImpl(JNIEnv *_env)"); - mCStream.println("{"); - mCStream.println(indent + - "int err;"); - - mCStream.println(indent + - "err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));"); - - mCStream.println(indent + "return err;"); - mCStream.println("}"); - } } diff --git a/opengl/tools/glgen/src/Jsr239CodeEmitter.java b/opengl/tools/glgen/src/Jsr239CodeEmitter.java new file mode 100644 index 000000000000..eff044755c34 --- /dev/null +++ b/opengl/tools/glgen/src/Jsr239CodeEmitter.java @@ -0,0 +1,74 @@ +import java.io.PrintStream; + +/** + * Emits a Java interface and Java & C implementation for a C function. + * + * <p> The Java interface will have Buffer and array variants for functions that + * have a typed pointer argument. The array variant will convert a single "<type> *data" + * argument to a pair of arguments "<type>[] data, int offset". + */ +public class Jsr239CodeEmitter extends JniCodeEmitter implements CodeEmitter { + + PrintStream mJava10InterfaceStream; + PrintStream mJava10ExtInterfaceStream; + PrintStream mJava11InterfaceStream; + PrintStream mJava11ExtInterfaceStream; + PrintStream mJava11ExtPackInterfaceStream; + PrintStream mJavaImplStream; + PrintStream mCStream; + + PrintStream mJavaInterfaceStream; + + /** + * @param java10InterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 functions + * @param java10ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 extension functions + * @param java11InterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 functions + * @param java11ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension functions + * @param java11ExtPackInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension Pack functions + * @param javaImplStream the PrintStream to which to emit the Java implementation + * @param cStream the PrintStream to which to emit the C implementation + */ + public Jsr239CodeEmitter(String classPathName, + ParameterChecker checker, + PrintStream java10InterfaceStream, + PrintStream java10ExtInterfaceStream, + PrintStream java11InterfaceStream, + PrintStream java11ExtInterfaceStream, + PrintStream java11ExtPackInterfaceStream, + PrintStream javaImplStream, + PrintStream cStream, + boolean useContextPointer) { + mClassPathName = classPathName; + mChecker = checker; + mJava10InterfaceStream = java10InterfaceStream; + mJava10ExtInterfaceStream = java10ExtInterfaceStream; + mJava11InterfaceStream = java11InterfaceStream; + mJava11ExtInterfaceStream = java11ExtInterfaceStream; + mJava11ExtPackInterfaceStream = java11ExtPackInterfaceStream; + mJavaImplStream = javaImplStream; + mCStream = cStream; + mUseContextPointer = useContextPointer; + } + + public void setVersion(int version, boolean ext, boolean pack) { + if (version == 0) { + mJavaInterfaceStream = ext ? mJava10ExtInterfaceStream : + mJava10InterfaceStream; + } else if (version == 1) { + mJavaInterfaceStream = ext ? + (pack ? mJava11ExtPackInterfaceStream : + mJava11ExtInterfaceStream) : + mJava11InterfaceStream; + } else { + throw new RuntimeException("Bad version: " + version); + } + } + + public void emitCode(CFunc cfunc, String original) { + emitCode(cfunc, original, mJavaInterfaceStream, mJavaImplStream, mCStream); + } + + public void emitNativeRegistration() { + emitNativeRegistration(mCStream); + } +} diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java index 7cd6b1742573..90d8c9d4ca5d 100644 --- a/services/java/com/android/server/BatteryService.java +++ b/services/java/com/android/server/BatteryService.java @@ -84,7 +84,7 @@ class BatteryService extends Binder { private static final int CRITICAL_BATTERY_LEVEL = 4; private static final int DUMP_MAX_LENGTH = 24 * 1024; - private static final String[] DUMPSYS_ARGS = new String[] { "-c", "-u" }; + private static final String[] DUMPSYS_ARGS = new String[] { "--checkin", "-u" }; private static final String BATTERY_STATS_SERVICE_NAME = "batteryinfo"; private static final String DUMPSYS_DATA_PATH = "/data/system/"; @@ -247,6 +247,20 @@ class BatteryService extends Binder { logOutlier = true; } + // Separate broadcast is sent for power connected / not connected + // since the standard intent will not wake any applications and some + // applications may want to have smart behavior based on this. + if (mPlugType != 0 && mLastPlugType == 0) { + Intent intent = new Intent(Intent.ACTION_POWER_CONNECTED); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + mContext.sendBroadcast(intent); + } + else if (mPlugType == 0 && mLastPlugType != 0) { + Intent intent = new Intent(Intent.ACTION_POWER_DISCONNECTED); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + mContext.sendBroadcast(intent); + } + mLastBatteryStatus = mBatteryStatus; mLastBatteryHealth = mBatteryHealth; mLastBatteryPresent = mBatteryPresent; diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 938a43d1f83a..75b59eef8005 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -44,6 +44,7 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.database.Cursor; import android.location.Address; +import android.location.IGeocodeProvider; import android.location.IGpsStatusListener; import android.location.ILocationCollector; import android.location.ILocationListener; @@ -128,6 +129,7 @@ public class LocationManagerService extends ILocationManager.Stub { private GpsLocationProvider mGpsLocationProvider; private boolean mGpsNavigating; private LocationProviderProxy mNetworkLocationProvider; + private IGeocodeProvider mGeocodeProvider; private LocationWorkerHandler mLocationHandler; // Handler messages @@ -632,6 +634,15 @@ public class LocationManagerService extends ILocationManager.Stub { } } + public void setGeocodeProvider(IGeocodeProvider provider) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException( + "Installing location providers outside of the system is not supported"); + } + + mGeocodeProvider = provider; + } + private WifiManager.WifiLock getWifiWakelockLocked() { if (mWifiLock == null && mWifiManager != null) { mWifiLock = mWifiManager.createWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, WIFILOCK_KEY); @@ -2074,30 +2085,34 @@ public class LocationManagerService extends ILocationManager.Stub { // Geocoder public String getFromLocation(double latitude, double longitude, int maxResults, - String language, String country, String variant, String appName, List<Address> addrs) { - synchronized (mLocationListeners) { - if (mNetworkLocationProvider != null) { - return mNetworkLocationProvider.getFromLocation(latitude, longitude, maxResults, - language, country, variant, appName, addrs); - } else { - return null; + String language, String country, String variant, String appName, List<Address> addrs) { + if (mGeocodeProvider != null) { + try { + return mGeocodeProvider.getFromLocation(latitude, longitude, maxResults, language, country, + variant, appName, addrs); + } catch (RemoteException e) { + Log.e(TAG, "getFromLocation failed", e); } } + return null; } + public String getFromLocationName(String locationName, - double lowerLeftLatitude, double lowerLeftLongitude, - double upperRightLatitude, double upperRightLongitude, int maxResults, - String language, String country, String variant, String appName, List<Address> addrs) { - synchronized (mLocationListeners) { - if (mNetworkLocationProvider != null) { - return mNetworkLocationProvider.getFromLocationName(locationName, lowerLeftLatitude, - lowerLeftLongitude, upperRightLatitude, upperRightLongitude, maxResults, - language, country, variant, appName, addrs); - } else { - return null; + double lowerLeftLatitude, double lowerLeftLongitude, + double upperRightLatitude, double upperRightLongitude, int maxResults, + String language, String country, String variant, String appName, List<Address> addrs) { + + if (mGeocodeProvider != null) { + try { + return mGeocodeProvider.getFromLocationName(locationName, lowerLeftLatitude, + lowerLeftLongitude, upperRightLatitude, upperRightLongitude, + maxResults, language, country, variant, appName, addrs); + } catch (RemoteException e) { + Log.e(TAG, "getFromLocationName failed", e); } } + return null; } // Mock Providers diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 0b1ddc846be5..b0fcb1c0f55b 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -77,7 +77,6 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.TokenWatcher; import android.provider.Settings; -import android.util.Config; import android.util.EventLog; import android.util.Log; import android.util.SparseIntArray; @@ -137,7 +136,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo static final boolean PROFILE_ORIENTATION = false; static final boolean BLUR = true; - static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; + static final boolean localLOGV = DEBUG; static final int LOG_WM_NO_SURFACE_MEMORY = 31000; @@ -2023,7 +2022,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo wtoken.appFullscreen = fullscreen; wtoken.requestedOrientation = requestedOrientation; mAppTokens.add(addPos, wtoken); - if (Config.LOGV) Log.v(TAG, "Adding new app token: " + wtoken); + if (localLOGV) Log.v(TAG, "Adding new app token: " + wtoken); mTokenMap.put(token.asBinder(), wtoken); mTokenList.add(wtoken); @@ -4801,14 +4800,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo mPaused = true; } else { if (mLastWin == null) { - if (Config.LOGI) Log.i( - TAG, "Key dispatching not paused: no last window."); + Log.i(TAG, "Key dispatching not paused: no last window."); } else if (mFinished) { - if (Config.LOGI) Log.i( - TAG, "Key dispatching not paused: finished last key."); + Log.i(TAG, "Key dispatching not paused: finished last key."); } else { - if (Config.LOGI) Log.i( - TAG, "Key dispatching not paused: window in higher layer."); + Log.i(TAG, "Key dispatching not paused: window in higher layer."); } } */ @@ -7423,7 +7419,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo private boolean mInLayout = false; private final void performLayoutAndPlaceSurfacesLocked() { if (mInLayout) { - if (Config.DEBUG) { + if (DEBUG) { throw new RuntimeException("Recursive call!"); } Log.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout"); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index d676c00b952e..a3c23d3f3af6 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -682,6 +682,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen HashMap<String, IBinder> mAppBindArgs; /** + * Temporary to avoid allocations. Protected by main lock. + */ + final StringBuilder mStringBuilder = new StringBuilder(256); + + /** * Used to control how we initialize the service. */ boolean mStartRunning = false; @@ -778,6 +783,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen long mLastCpuTime = 0; long mLastWriteTime = 0; + long mInitialStartTime = 0; + /** * Set to true after the system has finished booting. */ @@ -1270,7 +1277,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen mBatteryStatsService.getActiveStatistics().writeLocked(); mUsageStatsService = new UsageStatsService( new File( - systemDir, "usagestats.bin").toString()); + systemDir, "usagestats").toString()); mConfiguration.makeDefault(); mProcessStats.init(); @@ -1635,6 +1642,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (r.startTime == 0) { r.startTime = SystemClock.uptimeMillis(); + if (mInitialStartTime == 0) { + mInitialStartTime = r.startTime; + } + } else if (mInitialStartTime == 0) { + mInitialStartTime = SystemClock.uptimeMillis(); } if (app != null && app.thread != null) { @@ -1785,7 +1797,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen Watchdog.getInstance().processStarted(app, app.processName, pid); } - StringBuilder buf = new StringBuilder(128); + StringBuilder buf = mStringBuilder; + buf.setLength(0); buf.append("Start proc "); buf.append(app.processName); buf.append(" for "); @@ -2813,7 +2826,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen HistoryRecord r = new HistoryRecord(this, callerApp, callingUid, intent, resolvedType, aInfo, mConfiguration, resultRecord, resultWho, requestCode, componentSpecified); - r.startTime = SystemClock.uptimeMillis(); HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; @@ -4095,7 +4107,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } - StringBuilder info = new StringBuilder(); + StringBuilder info = mStringBuilder; + info.setLength(0); info.append("ANR (application not responding) in process: "); info.append(app.processName); if (annotation != null) { @@ -4517,7 +4530,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } else if (mStartingProcesses.size() > 0) { app = mStartingProcesses.remove(0); - app.pid = pid; + app.setPid(pid); } else { app = null; } @@ -7877,24 +7890,24 @@ public final class ActivityManagerService extends ActivityManagerNative implemen return; } pw.println("Activities in Current Activity Manager State:"); - dumpHistoryList(pw, mHistory, " ", "History"); + dumpHistoryList(pw, mHistory, " ", "History", true); pw.println(" "); pw.println(" Running activities (most recent first):"); - dumpHistoryList(pw, mLRUActivities, " ", "Running"); + dumpHistoryList(pw, mLRUActivities, " ", "Running", false); if (mWaitingVisibleActivities.size() > 0) { pw.println(" "); pw.println(" Activities waiting for another to become visible:"); - dumpHistoryList(pw, mWaitingVisibleActivities, " ", "Waiting"); + dumpHistoryList(pw, mWaitingVisibleActivities, " ", "Waiting", false); } if (mStoppingActivities.size() > 0) { pw.println(" "); pw.println(" Activities waiting to stop:"); - dumpHistoryList(pw, mStoppingActivities, " ", "Stopping"); + dumpHistoryList(pw, mStoppingActivities, " ", "Stopping", false); } if (mFinishingActivities.size() > 0) { pw.println(" "); pw.println(" Activities waiting to finish:"); - dumpHistoryList(pw, mFinishingActivities, " ", "Finishing"); + dumpHistoryList(pw, mFinishingActivities, " ", "Finishing", false); } pw.println(" "); @@ -7931,8 +7944,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen needSep = true; } ProcessRecord r = procs.valueAt(ia); - pw.println((r.persistent ? " *PERSISTENT* Process [" : " Process [") - + r.processName + "] UID " + procs.keyAt(ia)); + pw.print(r.persistent ? " *PERSISTENT* Process [" : " Process ["); + pw.print(r.processName); pw.print("] UID "); pw.println(procs.keyAt(ia)); r.dump(pw, " "); if (r.persistent) { numPers++; @@ -8360,16 +8373,29 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } private static final void dumpHistoryList(PrintWriter pw, List list, - String prefix, String label) { + String prefix, String label, boolean complete) { TaskRecord lastTask = null; for (int i=list.size()-1; i>=0; i--) { HistoryRecord r = (HistoryRecord)list.get(i); if (lastTask != r.task) { lastTask = r.task; - lastTask.dump(pw, prefix + " "); + if (complete || !r.inHistory) { + lastTask.dump(pw, prefix + " "); + } else { + pw.print(prefix); + pw.print(" "); + pw.println(lastTask); + } + } + if (complete || !r.inHistory) { + pw.print(prefix); pw.print(" "); pw.print(label); + pw.print(" #"); pw.print(i); pw.println(":"); + r.dump(pw, prefix + " "); + } else { + pw.print(prefix); pw.print(" "); pw.print(label); + pw.print(" #"); pw.print(i); pw.print(": "); + pw.println(r); } - pw.println(prefix + " " + label + " #" + i + ":"); - r.dump(pw, prefix + " "); } } @@ -8401,7 +8427,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen private static final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, List list, String prefix, String[] args) { - final boolean isCheckinRequest = scanArgs(args, "-c"); + final boolean isCheckinRequest = scanArgs(args, "--checkin"); long uptime = SystemClock.uptimeMillis(); long realtime = SystemClock.elapsedRealtime(); @@ -8738,7 +8764,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen mPidsSelfLocked.remove(app.pid); mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); } - app.pid = 0; + app.setPid(0); } } diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java index c5907afbd967..e265f43046ca 100644 --- a/services/java/com/android/server/am/BatteryStatsService.java +++ b/services/java/com/android/server/am/BatteryStatsService.java @@ -295,7 +295,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub { boolean isCheckin = false; if (args != null) { for (String arg : args) { - if ("-c".equals(arg)) { + if ("--checkin".equals(arg)) { isCheckin = true; break; } diff --git a/services/java/com/android/server/am/ConnectionRecord.java b/services/java/com/android/server/am/ConnectionRecord.java index 41a783f67b04..b4c7df1f5498 100644 --- a/services/java/com/android/server/am/ConnectionRecord.java +++ b/services/java/com/android/server/am/ConnectionRecord.java @@ -28,7 +28,8 @@ class ConnectionRecord { final HistoryRecord activity; // If non-null, the owning activity. final IServiceConnection conn; // The client connection. final int flags; // Binding options. - + String stringName; // Caching of toString. + void dump(PrintWriter pw, String prefix) { pw.println(prefix + this); pw.println(prefix + "binding=" + binding); @@ -46,9 +47,17 @@ class ConnectionRecord { } public String toString() { - return "ConnectionRecord{" - + Integer.toHexString(System.identityHashCode(this)) - + " " + binding.service.shortName - + ":@" + Integer.toHexString(System.identityHashCode(conn.asBinder())) + "}"; + if (stringName != null) { + return stringName; + } + StringBuilder sb = new StringBuilder(128); + sb.append("ConnectionRecord{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append(' '); + sb.append(binding.service.shortName); + sb.append(":@"); + sb.append(Integer.toHexString(System.identityHashCode(conn.asBinder()))); + sb.append('}'); + return stringName = sb.toString(); } } diff --git a/services/java/com/android/server/am/ContentProviderRecord.java b/services/java/com/android/server/am/ContentProviderRecord.java index 9f37c140bcbe..2b9e0060ef82 100644 --- a/services/java/com/android/server/am/ContentProviderRecord.java +++ b/services/java/com/android/server/am/ContentProviderRecord.java @@ -32,7 +32,8 @@ class ContentProviderRecord extends ContentProviderHolder { int externals; // number of non-framework processes supported by this provider ProcessRecord app; // if non-null, hosting application ProcessRecord launchingApp; // if non-null, waiting for this app to be launched. - + String stringName; + public ContentProviderRecord(ProviderInfo _info, ApplicationInfo ai) { super(_info); uid = ai.uid; @@ -69,8 +70,15 @@ class ContentProviderRecord extends ContentProviderHolder { } public String toString() { - return "ContentProviderRecord{" - + Integer.toHexString(System.identityHashCode(this)) - + " " + info.name + "}"; + if (stringName != null) { + return stringName; + } + StringBuilder sb = new StringBuilder(128); + sb.append("ContentProviderRecord{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append(' '); + sb.append(info.name); + sb.append('}'); + return stringName = sb.toString(); } } diff --git a/services/java/com/android/server/am/HistoryRecord.java b/services/java/com/android/server/am/HistoryRecord.java index 0f62471ed7d3..a2fd62bacc96 100644 --- a/services/java/com/android/server/am/HistoryRecord.java +++ b/services/java/com/android/server/am/HistoryRecord.java @@ -100,46 +100,74 @@ class HistoryRecord extends IApplicationToken.Stub { boolean hasBeenLaunched;// has this activity ever been launched? boolean frozenBeforeDestroy;// has been frozen but not yet destroyed. + String stringName; // for caching of toString(). + void dump(PrintWriter pw, String prefix) { - pw.println(prefix + this); - pw.println(prefix + "packageName=" + packageName - + " processName=" + processName); - pw.println(prefix + "launchedFromUid=" + launchedFromUid - + " app=" + app); - pw.println(prefix + intent); - pw.println(prefix + "frontOfTask=" + frontOfTask + " task=" + task); - pw.println(prefix + "taskAffinity=" + taskAffinity); - pw.println(prefix + "realActivity=" + realActivity); - pw.println(prefix + "dir=" + baseDir + " res=" + resDir + " data=" + dataDir); - pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes) - + " icon=0x" + Integer.toHexString(icon) - + " theme=0x" + Integer.toHexString(theme)); - pw.println(prefix + "stateNotNeeded=" + stateNotNeeded - + " componentSpecified=" + componentSpecified - + " isHomeActivity=" + isHomeActivity); - pw.println(prefix + "configuration=" + configuration); - pw.println(prefix + "resultTo=" + resultTo - + " resultWho=" + resultWho + " resultCode=" + requestCode); - pw.println(prefix + "results=" + results); - pw.println(prefix + "pendingResults=" + pendingResults); - pw.println(prefix + "readUriPermissions=" + readUriPermissions); - pw.println(prefix + "writeUriPermissions=" + writeUriPermissions); - pw.println(prefix + "launchFailed=" + launchFailed - + " haveState=" + haveState + " icicle=" + icicle); - pw.println(prefix + "state=" + state - + " stopped=" + stopped + " finishing=" + finishing); - pw.println(prefix + "keysPaused=" + keysPaused - + " inHistory=" + inHistory + " persistent=" + persistent - + " launchMode=" + launchMode); - pw.println(prefix + "fullscreen=" + fullscreen - + " visible=" + visible - + " frozenBeforeDestroy=" + frozenBeforeDestroy - + " thumbnailNeeded=" + thumbnailNeeded + " idle=" + idle); - pw.println(prefix + "waitingVisible=" + waitingVisible - + " nowVisible=" + nowVisible); - pw.println(prefix + "configDestroy=" + configDestroy - + " configChangeFlags=" + Integer.toHexString(configChangeFlags)); - pw.println(prefix + "connections=" + connections); + pw.print(prefix); pw.println(this); + pw.print(prefix); pw.print("packageName="); pw.print(packageName); + pw.print(" processName="); pw.println(processName); + pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid); + pw.print(" app="); pw.println(app); + pw.print(prefix); pw.println(intent); + pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask); + pw.print(" task="); pw.println(task); + pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity); + pw.print(prefix); pw.print("realActivity="); pw.println(realActivity); + pw.print(prefix); pw.print("dir="); pw.print(baseDir); + pw.print(" res="); pw.print(resDir); + pw.print(" data="); pw.println(dataDir); + pw.print(prefix); pw.print("labelRes=0x"); + pw.print(Integer.toHexString(labelRes)); + pw.print(" icon=0x"); pw.print(Integer.toHexString(icon)); + pw.print(" theme=0x"); pw.println(Integer.toHexString(theme)); + pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded); + pw.print(" componentSpecified="); pw.print(componentSpecified); + pw.print(" isHomeActivity="); pw.println(isHomeActivity); + pw.print(prefix); pw.print("configuration="); pw.println(configuration); + if (resultTo != null || resultWho != null) { + pw.print(prefix); pw.print("resultTo="); pw.print(resultTo); + pw.print(" resultWho="); pw.print(resultWho); + pw.print(" resultCode="); pw.println(requestCode); + } + if (results != null) { + pw.print(prefix); pw.print("results="); pw.println(results); + } + if (pendingResults != null) { + pw.print(prefix); pw.print("pendingResults="); pw.println(pendingResults); + } + if (readUriPermissions != null) { + pw.print(prefix); pw.print("readUriPermissions="); pw.println(readUriPermissions); + } + if (writeUriPermissions != null) { + pw.print(prefix); pw.print("writeUriPermissions="); pw.println(writeUriPermissions); + } + pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed); + pw.print(" haveState="); pw.print(haveState); + pw.print(" icicle="); pw.println(icicle); + pw.print(prefix); pw.print("state="); pw.print(state); + pw.print(" stopped="); pw.print(stopped); + pw.print(" finishing="); pw.println(finishing); + pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused); + pw.print(" inHistory="); pw.print(inHistory); + pw.print(" persistent="); pw.print(persistent); + pw.print(" launchMode="); pw.println(launchMode); + pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen); + pw.print(" visible="); pw.print(visible); + pw.print(" frozenBeforeDestroy="); pw.print(frozenBeforeDestroy); + pw.print(" thumbnailNeeded="); pw.print(thumbnailNeeded); + pw.print(" idle="); pw.println(idle); + if (waitingVisible || nowVisible) { + pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible); + pw.print(" nowVisible="); pw.println(nowVisible); + } + if (configDestroy || configChangeFlags != 0) { + pw.print(prefix); pw.print("configDestroy="); pw.print(configDestroy); + pw.print(" configChangeFlags="); + pw.println(Integer.toHexString(configChangeFlags)); + } + if (connections != null) { + pw.print(prefix); pw.print("connections="); pw.println(connections); + } } HistoryRecord(ActivityManagerService _service, ProcessRecord _caller, @@ -335,15 +363,31 @@ class HistoryRecord extends IApplicationToken.Stub { public void windowsVisible() { synchronized(service) { - if (ActivityManagerService.SHOW_ACTIVITY_START_TIME - && startTime != 0) { - long time = SystemClock.uptimeMillis() - startTime; - EventLog.writeEvent(ActivityManagerService.LOG_ACTIVITY_LAUNCH_TIME, - System.identityHashCode(this), shortComponentName, time); - Log.i(ActivityManagerService.TAG, "Displayed activity " - + shortComponentName - + ": " + time + " ms"); + if (startTime != 0) { + final long curTime = SystemClock.uptimeMillis(); + final long thisTime = curTime - startTime; + final long totalTime = service.mInitialStartTime != 0 + ? (curTime - service.mInitialStartTime) : thisTime; + if (ActivityManagerService.SHOW_ACTIVITY_START_TIME) { + EventLog.writeEvent(ActivityManagerService.LOG_ACTIVITY_LAUNCH_TIME, + System.identityHashCode(this), shortComponentName, + thisTime, totalTime); + StringBuilder sb = service.mStringBuilder; + sb.setLength(0); + sb.append("Displayed activity "); + sb.append(shortComponentName); + sb.append(": "); + sb.append(thisTime); + sb.append(" ms (total "); + sb.append(totalTime); + sb.append(" ms)"); + Log.i(ActivityManagerService.TAG, sb.toString()); + } + if (totalTime > 0) { + service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime); + } startTime = 0; + service.mInitialStartTime = 0; } if (ActivityManagerService.DEBUG_SWITCH) Log.v( ActivityManagerService.TAG, "windowsVisible(): " + this); @@ -453,8 +497,15 @@ class HistoryRecord extends IApplicationToken.Stub { public String toString() { - return "HistoryRecord{" - + Integer.toHexString(System.identityHashCode(this)) - + " " + intent.getComponent().toShortString() + "}"; + if (stringName != null) { + return stringName; + } + StringBuilder sb = new StringBuilder(128); + sb.append("HistoryRecord{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append(' '); + sb.append(intent.getComponent().toShortString()); + sb.append('}'); + return stringName = sb.toString(); } } diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java index a1320dfec15a..d2667e7a837c 100644 --- a/services/java/com/android/server/am/ProcessRecord.java +++ b/services/java/com/android/server/am/ProcessRecord.java @@ -98,44 +98,82 @@ class ProcessRecord implements Watchdog.PssRequestor { boolean waitedForDebugger; // has process show wait for debugger dialog? Dialog waitDialog; // current wait for debugger dialog + String stringName; // caching of toString() result. + // These reports are generated & stored when an app gets into an error condition. // They will be "null" when all is OK. ActivityManager.ProcessErrorStateInfo crashingReport; ActivityManager.ProcessErrorStateInfo notRespondingReport; void dump(PrintWriter pw, String prefix) { - pw.println(prefix + this); - pw.println(prefix + "class=" + info.className); - pw.println(prefix+"manageSpaceActivityName="+info.manageSpaceActivityName); - pw.println(prefix + "dir=" + info.sourceDir + " publicDir=" + info.publicSourceDir - + " data=" + info.dataDir); - pw.println(prefix + "packageList=" + pkgList); - pw.println(prefix + "instrumentationClass=" + instrumentationClass - + " instrumentationProfileFile=" + instrumentationProfileFile); - pw.println(prefix + "instrumentationArguments=" + instrumentationArguments); - pw.println(prefix + "thread=" + thread + " curReceiver=" + curReceiver); - pw.println(prefix + "pid=" + pid + " starting=" + starting - + " lastPss=" + lastPss); - pw.println(prefix + "maxAdj=" + maxAdj + " hiddenAdj=" + hiddenAdj - + " curRawAdj=" + curRawAdj + " setRawAdj=" + setRawAdj - + " curAdj=" + curAdj + " setAdj=" + setAdj); - pw.println(prefix + "isForeground=" + isForeground - + " setIsForeground=" + setIsForeground - + " foregroundServices=" + foregroundServices - + " forcingToForeground=" + forcingToForeground); - pw.println(prefix + "persistent=" + persistent + " removed=" + removed - + " persistentActivities=" + persistentActivities); - pw.println(prefix + "debugging=" + debugging - + " crashing=" + crashing + " " + crashDialog - + " notResponding=" + notResponding + " " + anrDialog - + " bad=" + bad); - pw.println(prefix + "activities=" + activities); - pw.println(prefix + "services=" + services); - pw.println(prefix + "executingServices=" + executingServices); - pw.println(prefix + "connections=" + connections); - pw.println(prefix + "pubProviders=" + pubProviders); - pw.println(prefix + "conProviders=" + conProviders); - pw.println(prefix + "receivers=" + receivers); + pw.print(prefix); pw.println(this); + if (info.className != null) { + pw.print(prefix); pw.print("class="); pw.println(info.className); + } + if (info.manageSpaceActivityName != null) { + pw.print(prefix); pw.print("manageSpaceActivityName="); + pw.println(info.manageSpaceActivityName); + } + pw.print(prefix); pw.print("dir="); pw.print(info.sourceDir); + pw.print(" publicDir="); pw.print(info.publicSourceDir); + pw.print(" data="); pw.println(info.dataDir); + pw.print(prefix); pw.print("packageList="); pw.println(pkgList); + if (instrumentationClass != null || instrumentationProfileFile != null + || instrumentationArguments != null) { + pw.print(prefix); pw.print("instrumentationClass="); + pw.print(instrumentationClass); + pw.print(" instrumentationProfileFile="); + pw.println(instrumentationProfileFile); + pw.print(prefix); pw.print("instrumentationArguments="); + pw.println(instrumentationArguments); + } + pw.print(prefix); pw.print("thread="); pw.print(thread); + pw.print(" curReceiver="); pw.println(curReceiver); + pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting="); + pw.print(starting); pw.print(" lastPss="); pw.println(lastPss); + pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj); + pw.print(" hidden="); pw.print(hiddenAdj); + pw.print(" curRaw="); pw.print(curRawAdj); + pw.print(" setRaw="); pw.print(setRawAdj); + pw.print(" cur="); pw.print(curAdj); + pw.print(" set="); pw.println(setAdj); + pw.print(prefix); pw.print("isForeground="); pw.print(isForeground); + pw.print(" setIsForeground="); pw.print(setIsForeground); + pw.print(" foregroundServices="); pw.print(foregroundServices); + pw.print(" forcingToForeground="); pw.println(forcingToForeground); + pw.print(prefix); pw.print("persistent="); pw.print(persistent); + pw.print(" removed="); pw.print(removed); + pw.print(" persistentActivities="); pw.println(persistentActivities); + if (debugging || crashing || crashDialog != null || notResponding + || anrDialog != null || bad) { + pw.print(prefix); pw.print("debugging="); pw.print(debugging); + pw.print(" crashing="); pw.print(crashing); + pw.print(" "); pw.print(crashDialog); + pw.print(" notResponding="); pw.print(notResponding); + pw.print(" " ); pw.print(anrDialog); + pw.print(" bad="); pw.println(bad); + } + if (activities.size() > 0) { + pw.print(prefix); pw.print("activities="); pw.println(activities); + } + if (services.size() > 0) { + pw.print(prefix); pw.print("services="); pw.println(services); + } + if (executingServices.size() > 0) { + pw.print(prefix); pw.print("executingServices="); pw.println(executingServices); + } + if (connections.size() > 0) { + pw.print(prefix); pw.print("connections="); pw.println(connections); + } + if (pubProviders.size() > 0) { + pw.print(prefix); pw.print("pubProviders="); pw.println(pubProviders); + } + if (conProviders.size() > 0) { + pw.print(prefix); pw.print("conProviders="); pw.println(conProviders); + } + if (receivers.size() > 0) { + pw.print(prefix); pw.print("receivers="); pw.println(receivers); + } } ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread, @@ -154,6 +192,11 @@ class ProcessRecord implements Watchdog.PssRequestor { persistentActivities = 0; } + public void setPid(int _pid) { + pid = _pid; + stringName = null; + } + /** * This method returns true if any of the activities within the process record are interesting * to the user. See HistoryRecord.isInterestingToUserLocked() @@ -188,9 +231,20 @@ class ProcessRecord implements Watchdog.PssRequestor { } public String toString() { - return "ProcessRecord{" - + Integer.toHexString(System.identityHashCode(this)) - + " " + pid + ":" + processName + "/" + info.uid + "}"; + if (stringName != null) { + return stringName; + } + StringBuilder sb = new StringBuilder(128); + sb.append("ProcessRecord{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append(' '); + sb.append(pid); + sb.append(':'); + sb.append(processName); + sb.append('/'); + sb.append(info.uid); + sb.append('}'); + return stringName = sb.toString(); } /* diff --git a/services/java/com/android/server/am/ReceiverList.java b/services/java/com/android/server/am/ReceiverList.java index 6ac527bd7ed2..b8bf30c05268 100644 --- a/services/java/com/android/server/am/ReceiverList.java +++ b/services/java/com/android/server/am/ReceiverList.java @@ -39,6 +39,8 @@ class ReceiverList extends ArrayList<BroadcastFilter> BroadcastRecord curBroadcast = null; boolean linkedToDeath = false; + String stringName; + ReceiverList(ActivityManagerService _owner, ProcessRecord _app, int _pid, int _uid, IIntentReceiver _receiver) { owner = _owner; @@ -82,11 +84,21 @@ class ReceiverList extends ArrayList<BroadcastFilter> } public String toString() { - return "ReceiverList{" - + Integer.toHexString(System.identityHashCode(this)) - + " " + pid + " " + (app != null ? app.processName : "(unknown name)") - + "/" + uid + " client " - + Integer.toHexString(System.identityHashCode(receiver.asBinder())) - + "}"; + if (stringName != null) { + return stringName; + } + StringBuilder sb = new StringBuilder(128); + sb.append("ReceiverList{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append(' '); + sb.append(pid); + sb.append(' '); + sb.append((app != null ? app.processName : "(unknown name)")); + sb.append('/'); + sb.append(uid); + sb.append(" client "); + sb.append(Integer.toHexString(System.identityHashCode(receiver.asBinder()))); + sb.append('}'); + return stringName = sb.toString(); } } diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java index 4b90600f8eed..a8fc76165c2c 100644 --- a/services/java/com/android/server/am/ServiceRecord.java +++ b/services/java/com/android/server/am/ServiceRecord.java @@ -77,6 +77,8 @@ class ServiceRecord extends Binder { long restartTime; // time of last restart. long nextRestartTime; // time when restartDelay will expire. + String stringName; // caching of toString + void dump(PrintWriter pw, String prefix) { pw.println(prefix + this); pw.println(prefix + "intent=" + intent.getIntent()); @@ -159,8 +161,15 @@ class ServiceRecord extends Binder { } public String toString() { - return "ServiceRecord{" - + Integer.toHexString(System.identityHashCode(this)) - + " " + shortName + "}"; + if (stringName != null) { + return stringName; + } + StringBuilder sb = new StringBuilder(128); + sb.append("ServiceRecord{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append(' '); + sb.append(shortName); + sb.append('}'); + return stringName = sb.toString(); } } diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java index 3922f39f52ba..b6f91589fae6 100755 --- a/services/java/com/android/server/am/UsageStatsService.java +++ b/services/java/com/android/server/am/UsageStatsService.java @@ -37,11 +37,11 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TimeZone; /** * This service collects the statistics associated with usage @@ -53,6 +53,23 @@ public final class UsageStatsService extends IUsageStats.Stub { public static final String SERVICE_NAME = "usagestats"; private static final boolean localLOGV = false; private static final String TAG = "UsageStats"; + + // Current on-disk Parcel version + private static final int VERSION = 1004; + + private static final int CHECKIN_VERSION = 3; + + private static final String FILE_PREFIX = "usage-"; + + private static final int FILE_WRITE_INTERVAL = 30*60*1000; //ms + + private static final int MAX_NUM_FILES = 5; + + private static final int NUM_LAUNCH_TIME_BINS = 10; + private static final int[] LAUNCH_TIME_BINS = { + 250, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000 + }; + static IUsageStats sService; private Context mContext; // structure used to maintain statistics since the last checkin. @@ -66,16 +83,48 @@ public final class UsageStatsService extends IUsageStats.Stub { // Order of locks is mFileLock followed by mStatsLock to avoid deadlocks private String mResumedPkg; private File mFile; + private String mFileLeaf; //private File mBackupFile; - private long mLastWriteRealTime; - private int _FILE_WRITE_INTERVAL = 30*60*1000; //ms - private static final String _PREFIX_DELIMIT="."; - private String mFilePrefix; + private long mLastWriteElapsedTime; + private File mDir; private Calendar mCal; - private static final int _MAX_NUM_FILES = 10; - private long mLastTime; + private int mLastWriteDay; + + static class TimeStats { + int[] times = new int[NUM_LAUNCH_TIME_BINS]; + + TimeStats() { + } + + void add(int val) { + final int[] bins = LAUNCH_TIME_BINS; + for (int i=0; i<NUM_LAUNCH_TIME_BINS-1; i++) { + if (val < bins[i]) { + times[i]++; + return; + } + } + times[NUM_LAUNCH_TIME_BINS-1]++; + } + + TimeStats(Parcel in) { + final int[] localTimes = times; + for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) { + localTimes[i] = in.readInt(); + } + } + + void writeToParcel(Parcel out) { + final int[] localTimes = times; + for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) { + out.writeInt(localTimes[i]); + } + } + } private class PkgUsageStatsExtended { + final HashMap<String, TimeStats> mLaunchTimes + = new HashMap<String, TimeStats>(); int mLaunchCount; long mUsageTime; long mPausedTime; @@ -85,44 +134,106 @@ public final class UsageStatsService extends IUsageStats.Stub { mLaunchCount = 0; mUsageTime = 0; } + + PkgUsageStatsExtended(Parcel in) { + mLaunchCount = in.readInt(); + mUsageTime = in.readLong(); + if (localLOGV) Log.v(TAG, "Launch count: " + mLaunchCount + + ", Usage time:" + mUsageTime); + + final int N = in.readInt(); + if (localLOGV) Log.v(TAG, "Reading comps: " + N); + for (int i=0; i<N; i++) { + String comp = in.readString(); + if (localLOGV) Log.v(TAG, "Component: " + comp); + TimeStats times = new TimeStats(in); + mLaunchTimes.put(comp, times); + } + } + void updateResume() { mLaunchCount ++; mResumedTime = SystemClock.elapsedRealtime(); } + void updatePause() { mPausedTime = SystemClock.elapsedRealtime(); mUsageTime += (mPausedTime - mResumedTime); } + + void addLaunchTime(String comp, int millis) { + TimeStats times = mLaunchTimes.get(comp); + if (times == null) { + times = new TimeStats(); + mLaunchTimes.put(comp, times); + } + times.add(millis); + } + + void writeToParcel(Parcel out) { + out.writeInt(mLaunchCount); + out.writeLong(mUsageTime); + final int N = mLaunchTimes.size(); + out.writeInt(N); + if (N > 0) { + for (Map.Entry<String, TimeStats> ent : mLaunchTimes.entrySet()) { + out.writeString(ent.getKey()); + TimeStats times = ent.getValue(); + times.writeToParcel(out); + } + } + } + void clear() { + mLaunchTimes.clear(); mLaunchCount = 0; mUsageTime = 0; } } - UsageStatsService(String fileName) { + UsageStatsService(String dir) { mStats = new HashMap<String, PkgUsageStatsExtended>(); mStatsLock = new Object(); mFileLock = new Object(); - mFilePrefix = fileName; - mCal = Calendar.getInstance(); + mDir = new File(dir); + mCal = Calendar.getInstance(TimeZone.getTimeZone("GMT+0")); + + mDir.mkdir(); + + // Remove any old usage files from previous versions. + File parentDir = mDir.getParentFile(); + String fList[] = parentDir.list(); + if (fList != null) { + String prefix = mDir.getName() + "."; + int i = fList.length; + while (i > 0) { + i--; + if (fList[i].startsWith(prefix)) { + Log.i(TAG, "Deleting old usage file: " + fList[i]); + (new File(parentDir, fList[i])).delete(); + } + } + } + // Update current stats which are binned by date - String uFileName = getCurrentDateStr(mFilePrefix); - mFile = new File(uFileName); + mFileLeaf = getCurrentDateStr(FILE_PREFIX); + mFile = new File(mDir, mFileLeaf); readStatsFromFile(); - mLastWriteRealTime = SystemClock.elapsedRealtime(); - mLastTime = new Date().getTime(); + mLastWriteElapsedTime = SystemClock.elapsedRealtime(); + // mCal was set by getCurrentDateStr(), want to use that same time. + mLastWriteDay = mCal.get(Calendar.DAY_OF_YEAR); } /* * Utility method to convert date into string. */ private String getCurrentDateStr(String prefix) { - mCal.setTime(new Date()); + mCal.setTimeInMillis(System.currentTimeMillis()); StringBuilder sb = new StringBuilder(); if (prefix != null) { sb.append(prefix); - sb.append("."); } + sb.append(mCal.get(Calendar.YEAR)); int mm = mCal.get(Calendar.MONTH) - Calendar.JANUARY +1; if (mm < 10) { sb.append("0"); @@ -133,7 +244,6 @@ public final class UsageStatsService extends IUsageStats.Stub { sb.append("0"); } sb.append(dd); - sb.append(mCal.get(Calendar.YEAR)); return sb.toString(); } @@ -166,11 +276,20 @@ public final class UsageStatsService extends IUsageStats.Stub { private void readStatsFLOCK(File file) throws IOException { Parcel in = getParcelForFile(file); - while (in.dataAvail() > 0) { + int vers = in.readInt(); + if (vers != VERSION) { + Log.w(TAG, "Usage stats version changed; dropping"); + return; + } + int N = in.readInt(); + while (N > 0) { + N--; String pkgName = in.readString(); - PkgUsageStatsExtended pus = new PkgUsageStatsExtended(); - pus.mLaunchCount = in.readInt(); - pus.mUsageTime = in.readLong(); + if (pkgName == null) { + break; + } + if (localLOGV) Log.v(TAG, "Reading package #" + N + ": " + pkgName); + PkgUsageStatsExtended pus = new PkgUsageStatsExtended(in); synchronized (mStatsLock) { mStats.put(pkgName, pus); } @@ -178,27 +297,18 @@ public final class UsageStatsService extends IUsageStats.Stub { } private ArrayList<String> getUsageStatsFileListFLOCK() { - File dir = getUsageFilesDir(); - if (dir == null) { - Log.w(TAG, "Couldnt find writable directory for usage stats file"); - return null; - } // Check if there are too many files in the system and delete older files - String fList[] = dir.list(); + String fList[] = mDir.list(); if (fList == null) { return null; } - File pre = new File(mFilePrefix); - String filePrefix = pre.getName(); - // file name followed by dot - int prefixLen = filePrefix.length()+1; ArrayList<String> fileList = new ArrayList<String>(); for (String file : fList) { - int index = file.indexOf(filePrefix); - if (index == -1) { + if (!file.startsWith(FILE_PREFIX)) { continue; } if (file.endsWith(".bak")) { + (new File(mDir, file)).delete(); continue; } fileList.add(file); @@ -206,20 +316,7 @@ public final class UsageStatsService extends IUsageStats.Stub { return fileList; } - private File getUsageFilesDir() { - if (mFilePrefix == null) { - return null; - } - File pre = new File(mFilePrefix); - return new File(pre.getParent()); - } - private void checkFileLimitFLOCK() { - File dir = getUsageFilesDir(); - if (dir == null) { - Log.w(TAG, "Couldnt find writable directory for usage stats file"); - return; - } // Get all usage stats output files ArrayList<String> fileList = getUsageStatsFileListFLOCK(); if (fileList == null) { @@ -227,49 +324,54 @@ public final class UsageStatsService extends IUsageStats.Stub { return; } int count = fileList.size(); - if (count <= _MAX_NUM_FILES) { + if (count <= MAX_NUM_FILES) { return; } // Sort files Collections.sort(fileList); - count -= _MAX_NUM_FILES; + count -= MAX_NUM_FILES; // Delete older files for (int i = 0; i < count; i++) { String fileName = fileList.get(i); - File file = new File(dir, fileName); - Log.i(TAG, "Deleting file : "+fileName); + File file = new File(mDir, fileName); + Log.i(TAG, "Deleting usage file : " + fileName); file.delete(); } } - private void writeStatsToFile() { + private void writeStatsToFile(boolean force) { synchronized (mFileLock) { - long currTime = new Date().getTime(); - boolean dayChanged = ((currTime - mLastTime) >= (24*60*60*1000)); - long currRealTime = SystemClock.elapsedRealtime(); - if (((currRealTime-mLastWriteRealTime) < _FILE_WRITE_INTERVAL) && - (!dayChanged)) { - // wait till the next update - return; + mCal.setTimeInMillis(System.currentTimeMillis()); + final int curDay = mCal.get(Calendar.DAY_OF_YEAR); + // Determine if the day changed... note that this will be wrong + // if the year has changed but we are in the same day of year... + // we can probably live with this. + final boolean dayChanged = curDay != mLastWriteDay; + long currElapsedTime = SystemClock.elapsedRealtime(); + if (!force) { + if (((currElapsedTime-mLastWriteElapsedTime) < FILE_WRITE_INTERVAL) && + (!dayChanged)) { + // wait till the next update + return; + } } // Get the most recent file - String todayStr = getCurrentDateStr(mFilePrefix); + mFileLeaf = getCurrentDateStr(FILE_PREFIX); // Copy current file to back up File backupFile = new File(mFile.getPath() + ".bak"); mFile.renameTo(backupFile); try { - checkFileLimitFLOCK(); - mFile.createNewFile(); // Write mStats to file writeStatsFLOCK(); - mLastWriteRealTime = currRealTime; - mLastTime = currTime; + mLastWriteElapsedTime = currElapsedTime; if (dayChanged) { + mLastWriteDay = curDay; // clear stats synchronized (mStats) { mStats.clear(); } - mFile = new File(todayStr); + mFile = new File(mDir, mFileLeaf); + checkFileLimitFLOCK(); } // Delete the backup file if (backupFile != null) { @@ -278,6 +380,7 @@ public final class UsageStatsService extends IUsageStats.Stub { } catch (IOException e) { Log.w(TAG, "Failed writing stats to file:" + mFile); if (backupFile != null) { + mFile.delete(); backupFile.renameTo(mFile); } } @@ -286,22 +389,26 @@ public final class UsageStatsService extends IUsageStats.Stub { private void writeStatsFLOCK() throws IOException { FileOutputStream stream = new FileOutputStream(mFile); - Parcel out = Parcel.obtain(); - writeStatsToParcelFLOCK(out); - stream.write(out.marshall()); - out.recycle(); - stream.flush(); - stream.close(); + try { + Parcel out = Parcel.obtain(); + writeStatsToParcelFLOCK(out); + stream.write(out.marshall()); + out.recycle(); + stream.flush(); + } finally { + stream.close(); + } } private void writeStatsToParcelFLOCK(Parcel out) { synchronized (mStatsLock) { + out.writeInt(VERSION); Set<String> keys = mStats.keySet(); + out.writeInt(keys.size()); for (String key : keys) { PkgUsageStatsExtended pus = mStats.get(key); out.writeString(key); - out.writeInt(pus.mLaunchCount); - out.writeLong(pus.mUsageTime); + pus.writeToParcel(out); } } } @@ -355,6 +462,10 @@ public final class UsageStatsService extends IUsageStats.Stub { return; } if (localLOGV) Log.i(TAG, "paused component:"+pkgName); + + // Persist current data to file if needed. + writeStatsToFile(false); + synchronized (mStatsLock) { PkgUsageStatsExtended pus = mStats.get(pkgName); if (pus == null) { @@ -364,8 +475,25 @@ public final class UsageStatsService extends IUsageStats.Stub { } pus.updatePause(); } - // Persist data to file - writeStatsToFile(); + } + + public void noteLaunchTime(ComponentName componentName, int millis) { + enforceCallingPermission(); + String pkgName; + if ((componentName == null) || + ((pkgName = componentName.getPackageName()) == null)) { + return; + } + + // Persist current data to file if needed. + writeStatsToFile(false); + + synchronized (mStatsLock) { + PkgUsageStatsExtended pus = mStats.get(pkgName); + if (pus != null) { + pus.addLaunchTime(componentName.getClassName(), millis); + } + } } public void enforceCallingPermission() { @@ -432,27 +560,25 @@ public final class UsageStatsService extends IUsageStats.Stub { } } - private void collectDumpInfoFLOCK(PrintWriter pw, String[] args) { + private void collectDumpInfoFLOCK(PrintWriter pw, boolean isCompactOutput, + boolean deleteAfterPrint) { List<String> fileList = getUsageStatsFileListFLOCK(); if (fileList == null) { return; } - final boolean isCheckinRequest = scanArgs(args, "-c"); Collections.sort(fileList); - File usageFile = new File(mFilePrefix); - String dirName = usageFile.getParent(); - File dir = new File(dirName); - String filePrefix = usageFile.getName(); - // file name followed by dot - int prefixLen = filePrefix.length()+1; - String todayStr = getCurrentDateStr(null); for (String file : fileList) { - File dFile = new File(dir, file); - String dateStr = file.substring(prefixLen); + if (deleteAfterPrint && file.equalsIgnoreCase(mFileLeaf)) { + // In this mode we don't print the current day's stats, since + // they are incomplete. + continue; + } + File dFile = new File(mDir, file); + String dateStr = file.substring(FILE_PREFIX.length()); try { Parcel in = getParcelForFile(dFile); - collectDumpInfoFromParcelFLOCK(in, pw, dateStr, isCheckinRequest); - if (isCheckinRequest && !todayStr.equalsIgnoreCase(dateStr)) { + collectDumpInfoFromParcelFLOCK(in, pw, dateStr, isCompactOutput); + if (deleteAfterPrint) { // Delete old file after collecting info only for checkin requests dFile.delete(); } @@ -466,40 +592,101 @@ public final class UsageStatsService extends IUsageStats.Stub { } private void collectDumpInfoFromParcelFLOCK(Parcel in, PrintWriter pw, - String date, boolean isCheckinRequest) { - StringBuilder sb = new StringBuilder(); - sb.append("Date:"); + String date, boolean isCompactOutput) { + StringBuilder sb = new StringBuilder(512); + if (isCompactOutput) { + sb.append("D:"); + sb.append(CHECKIN_VERSION); + sb.append(','); + } else { + sb.append("Date: "); + } + sb.append(date); - boolean first = true; - while (in.dataAvail() > 0) { + + int vers = in.readInt(); + if (vers != VERSION) { + sb.append(" (old data version)"); + pw.println(sb.toString()); + return; + } + + pw.println(sb.toString()); + int N = in.readInt(); + + while (N > 0) { + N--; String pkgName = in.readString(); - int launchCount = in.readInt(); - long usageTime = in.readLong(); - if (isCheckinRequest) { - if (!first) { - sb.append(","); - } + if (pkgName == null) { + break; + } + sb.setLength(0); + PkgUsageStatsExtended pus = new PkgUsageStatsExtended(in); + if (isCompactOutput) { + sb.append("P:"); sb.append(pkgName); sb.append(","); - sb.append(launchCount); + sb.append(pus.mLaunchCount); sb.append(","); - sb.append(usageTime); - sb.append("ms"); - } else { - if (first) { - sb.append("\n"); + sb.append(pus.mUsageTime); + sb.append('\n'); + final int NC = pus.mLaunchTimes.size(); + if (NC > 0) { + for (Map.Entry<String, TimeStats> ent : pus.mLaunchTimes.entrySet()) { + sb.append("A:"); + sb.append(ent.getKey()); + TimeStats times = ent.getValue(); + for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) { + sb.append(","); + sb.append(times.times[i]); + } + sb.append('\n'); + } } - sb.append("pkg="); + + } else { + sb.append(" "); sb.append(pkgName); - sb.append(", launchCount="); - sb.append(launchCount); - sb.append(", usageTime="); - sb.append(usageTime); - sb.append(" ms\n"); + sb.append(": "); + sb.append(pus.mLaunchCount); + sb.append(" times, "); + sb.append(pus.mUsageTime); + sb.append(" ms"); + sb.append('\n'); + final int NC = pus.mLaunchTimes.size(); + if (NC > 0) { + for (Map.Entry<String, TimeStats> ent : pus.mLaunchTimes.entrySet()) { + sb.append(" "); + sb.append(ent.getKey()); + TimeStats times = ent.getValue(); + int lastBin = 0; + boolean first = true; + for (int i=0; i<NUM_LAUNCH_TIME_BINS-1; i++) { + if (times.times[i] != 0) { + sb.append(first ? ": " : ", "); + sb.append(lastBin); + sb.append('-'); + sb.append(LAUNCH_TIME_BINS[i]); + sb.append('='); + sb.append(times.times[i]); + first = false; + } + lastBin = LAUNCH_TIME_BINS[i]; + } + if (times.times[NUM_LAUNCH_TIME_BINS-1] != 0) { + sb.append(first ? ": " : ", "); + sb.append(">="); + sb.append(lastBin); + sb.append('='); + sb.append(times.times[NUM_LAUNCH_TIME_BINS-1]); + } + sb.append('\n'); + } + } } - first = false; + + pw.write(sb.toString()); } - pw.write(sb.toString()); } /** @@ -524,8 +711,19 @@ public final class UsageStatsService extends IUsageStats.Stub { * The data persisted to file is parsed and the stats are computed. */ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + final boolean isCheckinRequest = scanArgs(args, "--checkin"); + final boolean isCompactOutput = isCheckinRequest || scanArgs(args, "-c"); + final boolean deleteAfterPrint = isCheckinRequest || scanArgs(args, "-d"); + + // Make sure the current stats are written to the file. This + // doesn't need to be done if we are deleting files after printing, + // since it that case we won't print the current stats. + if (!deleteAfterPrint) { + writeStatsToFile(true); + } + synchronized (mFileLock) { - collectDumpInfoFLOCK(pw, args); + collectDumpInfoFLOCK(pw, isCompactOutput, deleteAfterPrint); } } diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java index ed90d321a4b2..3f210ca82564 100644 --- a/telephony/java/com/android/internal/telephony/Phone.java +++ b/telephony/java/com/android/internal/telephony/Phone.java @@ -113,9 +113,12 @@ public interface Phone { static final String APN_TYPE_DEFAULT = "default"; /** APN type for MMS traffic */ static final String APN_TYPE_MMS = "mms"; + /** APN type for SUPL assisted GPS */ + static final String APN_TYPE_SUPL = "supl"; // "Features" accessible through the connectivity manager static final String FEATURE_ENABLE_MMS = "enableMMS"; + static final String FEATURE_ENABLE_SUPL = "enableSUPL"; /** * Return codes for <code>enableApnType()</code> @@ -170,7 +173,7 @@ public interface Phone { int NT_MODE_EVDO_NO_CDMA = 6; /* EvDo only */ int NT_MODE_GLOBAL = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) AVAILABLE Application Settings menu*/ - int PREFERRED_NT_MODE = NT_MODE_GLOBAL; + int PREFERRED_NT_MODE = NT_MODE_GSM_ONLY; // Used for CDMA roaming mode diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java index 3db0499a618e..86e2f0449da4 100644 --- a/telephony/java/com/android/internal/telephony/PhoneFactory.java +++ b/telephony/java/com/android/internal/telephony/PhoneFactory.java @@ -108,26 +108,23 @@ public class PhoneFactory { sCommandsInterface = new RIL(context, networkMode, cdmaSubscription); switch(networkMode) { - case RILConstants.NETWORK_MODE_WCDMA_PREF: - case RILConstants.NETWORK_MODE_GSM_ONLY: - case RILConstants.NETWORK_MODE_WCDMA_ONLY: - case RILConstants.NETWORK_MODE_GSM_UMTS: - sProxyPhone = new PhoneProxy(new GSMPhone(context, - sCommandsInterface, sPhoneNotifier)); - Log.i(LOG_TAG, "Creating GSMPhone"); - break; case RILConstants.NETWORK_MODE_CDMA: case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: + case RILConstants.NETWORK_MODE_GLOBAL: sProxyPhone = new PhoneProxy(new CDMAPhone(context, sCommandsInterface, sPhoneNotifier)); Log.i(LOG_TAG, "Creating CDMAPhone"); break; - case RILConstants.NETWORK_MODE_GLOBAL: + case RILConstants.NETWORK_MODE_WCDMA_PREF: + case RILConstants.NETWORK_MODE_GSM_ONLY: + case RILConstants.NETWORK_MODE_WCDMA_ONLY: + case RILConstants.NETWORK_MODE_GSM_UMTS: default: - sProxyPhone = new PhoneProxy(new CDMAPhone(context, + sProxyPhone = new PhoneProxy(new GSMPhone(context, sCommandsInterface, sPhoneNotifier)); - Log.i(LOG_TAG, "Creating CDMAPhone"); + Log.i(LOG_TAG, "Creating GSMPhone"); + break; } sMadeDefaults = true; } @@ -160,5 +157,3 @@ public class PhoneFactory { } } } - - diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index f5d3b32cd43a..636a2234d60c 100644 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ b/telephony/java/com/android/internal/telephony/RIL.java @@ -565,22 +565,18 @@ public final class RIL extends BaseCommands implements CommandsInterface { mNetworkMode = networkMode; //At startup mPhoneType is first set from networkMode switch(networkMode) { - case RILConstants.NETWORK_MODE_WCDMA_PREF: - case RILConstants.NETWORK_MODE_GSM_ONLY: - case RILConstants.NETWORK_MODE_WCDMA_ONLY: - case RILConstants.NETWORK_MODE_GSM_UMTS: - mPhoneType = RILConstants.GSM_PHONE; - break; case RILConstants.NETWORK_MODE_CDMA: case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: - mPhoneType = RILConstants.CDMA_PHONE; - break; case RILConstants.NETWORK_MODE_GLOBAL: mPhoneType = RILConstants.CDMA_PHONE; break; + case RILConstants.NETWORK_MODE_WCDMA_PREF: + case RILConstants.NETWORK_MODE_GSM_ONLY: + case RILConstants.NETWORK_MODE_WCDMA_ONLY: + case RILConstants.NETWORK_MODE_GSM_UMTS: default: - mPhoneType = RILConstants.CDMA_PHONE; + mPhoneType = RILConstants.GSM_PHONE; } PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 028aad71f3b4..9c63627b62c1 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -51,7 +51,7 @@ public interface RILConstants { int NETWORK_MODE_EVDO_NO_CDMA = 6; /* EvDo only */ int NETWORK_MODE_GLOBAL = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) AVAILABLE Application Settings menu*/ - int PREFERRED_NETWORK_MODE = NETWORK_MODE_GLOBAL; + int PREFERRED_NETWORK_MODE = NETWORK_MODE_GSM_ONLY; /* CDMA subscription source. See ril.h RIL_REQUEST_CDMA_SET_SUBSCRIPTION */ int SUBSCRIPTION_FROM_RUIM = 0; /* CDMA subscription from RUIM when available */ diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java index 7c324511b2b9..1aad38d2aa82 100644 --- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java +++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java @@ -20,20 +20,7 @@ import android.util.Log; import com.android.internal.telephony.SmsHeader; import java.util.Arrays; -import static android.telephony.SmsMessage.ENCODING_7BIT; -import static android.telephony.SmsMessage.ENCODING_16BIT; -import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES; -import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER; -import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS; -import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER; import static android.telephony.SmsMessage.MessageClass; -import static com.android.internal.telephony.SmsAddress.TON_ABBREVIATED; -import static com.android.internal.telephony.SmsAddress.TON_ALPHANUMERIC; -import static com.android.internal.telephony.SmsAddress.TON_INTERNATIONAL; -import static com.android.internal.telephony.SmsAddress.TON_NATIONAL; -import static com.android.internal.telephony.SmsAddress.TON_NETWORK; -import static com.android.internal.telephony.SmsAddress.TON_SUBSCRIBER; -import static com.android.internal.telephony.SmsAddress.TON_UNKNOWN; /** * Base class declaring the specific methods and members for SmsMessage. @@ -385,4 +372,3 @@ public abstract class SmsMessageBase { } } - diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java index c139619771df..8ffb7ecc44c7 100644..100755 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java @@ -475,6 +475,11 @@ public class CDMAPhone extends PhoneBase { // we report data connected ret = DataState.CONNECTED; + } else if (mSST == null) { + // Radio Technology Change is ongoning, dispose() and removeReferences() have + // already been called + + ret = DataState.DISCONNECTED; } else if (mSST.getCurrentCdmaDataConnectionState() == ServiceState.RADIO_TECHNOLOGY_UNKNOWN) { // If we're out of service, open TCP sockets may still work diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index ed617efaa95a..87e8b6207d37 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -228,6 +228,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { Log.d(LOG_TAG, "Request to enableApnType("+type+")"); if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) { return Phone.APN_ALREADY_ACTIVE; + } else if (TextUtils.equals(type, Phone.APN_TYPE_SUPL)) { + Log.w(LOG_TAG, "Phone.APN_TYPE_SUPL not enabled for CDMA"); + return Phone.APN_REQUEST_FAILED; } else { return Phone.APN_REQUEST_FAILED; } diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index e4b474a884dc..2f26bdcbb6a5 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -27,7 +27,6 @@ import com.android.internal.telephony.SmsHeader; import com.android.internal.telephony.SmsMessageBase; import com.android.internal.telephony.cdma.sms.BearerData; import com.android.internal.telephony.cdma.sms.CdmaSmsAddress; -import com.android.internal.telephony.cdma.sms.SmsDataCoding; import com.android.internal.telephony.cdma.sms.SmsEnvelope; import com.android.internal.telephony.cdma.sms.UserData; @@ -50,23 +49,6 @@ import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER; import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS; import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER; import static android.telephony.SmsMessage.MessageClass; -import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_NONE; -import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_TEMPORARY; -import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_PERMANENT; -import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_DELIVER; -import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_SUBMIT; -import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_CANCELLATION; -import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_DELIVERY_ACK; -import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_USER_ACK; -import static com.android.internal.telephony.cdma.sms.BearerData.MESSAGE_TYPE_READ_ACK; -import static com.android.internal.telephony.cdma.sms.CdmaSmsAddress.SMS_ADDRESS_MAX; -import static com.android.internal.telephony.cdma.sms.CdmaSmsAddress.SMS_SUBADDRESS_MAX; -import static com.android.internal.telephony.cdma.sms.SmsEnvelope.SMS_BEARER_DATA_MAX; -import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_7BIT_ASCII; -import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_GSM_7BIT_ALPHABET; -import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_IA5; -import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_OCTET; -import static com.android.internal.telephony.cdma.sms.UserData.UD_ENCODING_UNICODE_16; /** * A Short Message Service message. @@ -186,7 +168,7 @@ public class SmsMessage extends SmsMessageBase { // ignore subaddress p.readInt(); //p_cur->sSubAddress.subaddressType - p.readByte(); //p_cur->sSubAddress.odd + p.readInt(); //p_cur->sSubAddress.odd count = p.readByte(); //p_cur->sSubAddress.number_of_digits //p_cur->sSubAddress.digits[digitCount] : for (int index=0; index < count; index++) { @@ -309,15 +291,15 @@ public class SmsMessage extends SmsMessageBase { int septetCount = GsmAlphabet.countGsmSeptets(message, true); // User Data (and length) - uData.userData = message.getBytes(); + uData.payload = message.getBytes(); - if (uData.userData.length > MAX_USER_DATA_SEPTETS) { + if (uData.payload.length > MAX_USER_DATA_SEPTETS) { // Message too long return null; } // desired TP-Data-Coding-Scheme - uData.userDataEncoding = UserData.UD_ENCODING_GSM_7BIT_ALPHABET; + uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET; // paddingBits not needed for UD_ENCODING_GSM_7BIT_ALPHABET @@ -341,15 +323,15 @@ public class SmsMessage extends SmsMessageBase { return null; } - uData.userData = textPart; + uData.payload = textPart; - if (uData.userData.length > MAX_USER_DATA_BYTES) { + if (uData.payload.length > MAX_USER_DATA_BYTES) { // Message too long return null; } // TP-Data-Coding-Scheme - uData.userDataEncoding = UserData.UD_ENCODING_UNICODE_16; + uData.msgEncoding = UserData.ENCODING_UNICODE_16; // sms header if(headerData != null) { @@ -425,8 +407,8 @@ public class SmsMessage extends SmsMessageBase { // TP-Data-Coding-Scheme // No class, 8 bit data - uData.userDataEncoding = UserData.UD_ENCODING_OCTET; - uData.userData = data; + uData.msgEncoding = UserData.ENCODING_OCTET; + uData.payload = data; byte[] msgData = sms.getEnvelope(destinationAddress, statusReportRequested, uData, true, true); @@ -619,21 +601,21 @@ public class SmsMessage extends SmsMessageBase { * Parses a SMS message from its BearerData stream. (mobile-terminated only) */ protected void parseSms() { - mBearerData = SmsDataCoding.decodeCdmaSms(mEnvelope.bearerData); - messageRef = mBearerData.messageID; + mBearerData = BearerData.decode(mEnvelope.bearerData); + messageRef = mBearerData.messageId; // TP-Message-Type-Indicator // (See 3GPP2 C.S0015-B, v2, 4.5.1) int messageType = mBearerData.messageType; switch (messageType) { - case MESSAGE_TYPE_USER_ACK: - case MESSAGE_TYPE_READ_ACK: - case MESSAGE_TYPE_DELIVER: + case BearerData.MESSAGE_TYPE_USER_ACK: + case BearerData.MESSAGE_TYPE_READ_ACK: + case BearerData.MESSAGE_TYPE_DELIVER: // Deliver (mobile-terminated only) parseSmsDeliver(); break; - case MESSAGE_TYPE_DELIVERY_ACK: + case BearerData.MESSAGE_TYPE_DELIVERY_ACK: parseSmsDeliveryAck(); break; @@ -699,22 +681,22 @@ public class SmsMessage extends SmsMessageBase { return; } - encodingType = uData.userDataEncoding; + encodingType = uData.msgEncoding; // insert DCS-decoding here when type is supported by ril-library - userData = uData.userData; + userData = uData.payload; userDataHeader = uData.userDataHeader; switch (encodingType) { - case UD_ENCODING_GSM_7BIT_ALPHABET: - case UD_ENCODING_UNICODE_16: + case UserData.ENCODING_GSM_7BIT_ALPHABET: + case UserData.ENCODING_UNICODE_16: // user data was already decoded by wmsts-library messageBody = new String(userData); break; // data and unsupported encodings: - case UD_ENCODING_OCTET: + case UserData.ENCODING_OCTET: default: messageBody = null; break; @@ -771,7 +753,7 @@ public class SmsMessage extends SmsMessageBase { if (useNewId) { setNextMessageId(); } - mBearerData.messageID = nextMessageId; + mBearerData.messageId = nextMessageId; // Set the reply options (See C.S0015-B, v2.0, 4.5.11) if(statusReportRequested) { @@ -795,7 +777,7 @@ public class SmsMessage extends SmsMessageBase { // ** encode BearerData ** byte[] encodedBearerData = null; try { - encodedBearerData = SmsDataCoding.encodeCdmaSms(mBearerData); + encodedBearerData = BearerData.encode(mBearerData); } catch (Exception e) { Log.e(LOG_TAG, "doGetSubmitPdu: EncodeCdmaSMS function in JNI interface failed: " + e.getMessage()); diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java index fec95297f76d..8e67387b476f 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java @@ -16,7 +16,52 @@ package com.android.internal.telephony.cdma.sms; +import android.util.Log; + +import com.android.internal.telephony.GsmAlphabet; +import com.android.internal.telephony.SmsHeader; +import com.android.internal.telephony.cdma.sms.UserData; + +import com.android.internal.util.HexDump; +import com.android.internal.util.BitwiseInputStream; +import com.android.internal.util.BitwiseOutputStream; + +/** + * XXX + * + * + */ public final class BearerData{ + private final static String LOG_TAG = "SMS"; + + /** + * Bearer Data Subparameter Indentifiers + * (See 3GPP2 C.S0015-B, v2.0, table 4.5-1) + */ + private final static byte SUBPARAM_MESSAGE_IDENTIFIER = 0x00; + private final static byte SUBPARAM_USER_DATA = 0x01; + private final static byte SUBPARAM_USER_REPONSE_CODE = 0x02; + private final static byte SUBPARAM_MESSAGE_CENTER_TIME_STAMP = 0x03; + //private final static byte SUBPARAM_VALIDITY_PERIOD_ABSOLUTE = 0x04; + //private final static byte SUBPARAM_VALIDITY_PERIOD_RELATIVE = 0x05; + //private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE = 0x06; + //private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE = 0x07; + //private final static byte SUBPARAM_PRIORITY_INDICATOR = 0x08; + //private final static byte SUBPARAM_PRIVACY_INDICATOR = 0x09; + private final static byte SUBPARAM_REPLY_OPTION = 0x0A; + private final static byte SUBPARAM_NUMBER_OF_MESSAGES = 0x0B; + //private final static byte SUBPARAM_ALERT_ON_MESSAGE_DELIVERY = 0x0C; + //private final static byte SUBPARAM_LANGUAGE_INDICATOR = 0x0D; + private final static byte SUBPARAM_CALLBACK_NUMBER = 0x0E; + //private final static byte SUBPARAM_MESSAGE_DISPLAY_MODE = 0x0F; + //private final static byte SUBPARAM_MULTIPLE_ENCODING_USER_DATA = 0x10; + //private final static byte SUBPARAM_MESSAGE_DEPOSIT_INDEX = 0x11; + //private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA = 0x12; + //private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS = 0x13; + private final static byte SUBPARAM_MESSAGE_STATUS = 0x14; + //private final static byte SUBPARAM_TP_FAILURE_CAUSE = 0x15; + //private final static byte SUBPARAM_ENHANCED_VMN = 0x16; + //private final static byte SUBPARAM_ENHANCED_VMN_ACK = 0x17; // For completeness the following fields are listed, though not used yet. /** @@ -94,9 +139,6 @@ public final class BearerData{ public static final int ERROR_UNDEFINED = 0xFF; public static final int STATUS_UNDEFINED = 0xFF; - /** Bit-mask indicating used fields for SmsDataCoding */ - public int mask; - /** * 4-bit value indicating the message type in accordance to * table 4.5.1-1 @@ -109,7 +151,7 @@ public final class BearerData{ * (Special rules apply for WAP-messages.) * (See 3GPP2 C.S0015-B, v2, 4.5.1) */ - public int messageID; + public int messageId; /** * 1-bit value that indicates whether a User Data Header is present. @@ -188,5 +230,440 @@ public final class BearerData{ */ public int messageStatus = STATUS_UNDEFINED; -} + private static class CodingException extends Exception { + public CodingException(String s) { + super(s); + } + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("BearerData:\n"); + builder.append(" messageType: " + messageType + "\n"); + builder.append(" messageId: " + (int)messageId + "\n"); + builder.append(" hasUserDataHeader: " + hasUserDataHeader + "\n"); + builder.append(" timeStamp: " + timeStamp + "\n"); + builder.append(" userAckReq: " + userAckReq + "\n"); + builder.append(" deliveryAckReq: " + deliveryAckReq + "\n"); + builder.append(" readAckReq: " + readAckReq + "\n"); + builder.append(" reportReq: " + reportReq + "\n"); + builder.append(" numberOfMessages: " + numberOfMessages + "\n"); + builder.append(" callbackNumber: " + callbackNumber + "\n"); + builder.append(" displayMode: " + displayMode + "\n"); + builder.append(" errorClass: " + errorClass + "\n"); + builder.append(" messageStatus: " + messageStatus + "\n"); + builder.append(" userData: " + userData + "\n"); + return builder.toString(); + } + + private static void encodeMessageId(BearerData bData, BitwiseOutputStream outStream) + throws BitwiseOutputStream.AccessException + { + outStream.write(8, 3); + outStream.write(4, bData.messageType); + outStream.write(8, bData.messageId >> 8); + outStream.write(8, bData.messageId); + outStream.write(1, bData.hasUserDataHeader ? 1 : 0); + outStream.skip(3); + } + + private static void encodeUserData(BearerData bData, BitwiseOutputStream outStream) + throws BitwiseOutputStream.AccessException + { + int dataBits = (bData.userData.payload.length * 8) - bData.userData.paddingBits; + byte[] headerData = null; + if (bData.hasUserDataHeader) { + headerData = bData.userData.userDataHeader.toByteArray(); + dataBits += headerData.length * 8; + } + int paramBits = dataBits + 13; + if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) || + (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) { + paramBits += 8; + } + int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0); + int paddingBits = (paramBytes * 8) - paramBits; + outStream.write(8, paramBytes); + outStream.write(5, bData.userData.msgEncoding); + if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) || + (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) { + outStream.write(8, bData.userData.msgType); + } + outStream.write(8, bData.userData.numFields); + if (headerData != null) outStream.writeByteArray(headerData.length * 8, headerData); + outStream.writeByteArray(dataBits, bData.userData.payload); + if (paddingBits > 0) outStream.write(paddingBits, 0); + } + + private static void encodeReplyOption(BearerData bData, BitwiseOutputStream outStream) + throws BitwiseOutputStream.AccessException + { + outStream.write(8, 1); + outStream.write(1, bData.userAckReq ? 1 : 0); + outStream.write(1, bData.deliveryAckReq ? 1 : 0); + outStream.write(1, bData.readAckReq ? 1 : 0); + outStream.write(1, bData.reportReq ? 1 : 0); + outStream.write(4, 0); + } + + private static byte[] encodeDtmfSmsAddress(String address) { + int digits = address.length(); + int dataBits = digits * 4; + int dataBytes = (dataBits / 8); + dataBytes += (dataBits % 8) > 0 ? 1 : 0; + byte[] rawData = new byte[dataBytes]; + for (int i = 0; i < digits; i++) { + char c = address.charAt(i); + int val = 0; + if ((c >= '1') && (c <= '9')) val = c - '0'; + else if (c == '0') val = 10; + else if (c == '*') val = 11; + else if (c == '#') val = 12; + else return null; + rawData[i / 2] |= val << (4 - ((i % 2) * 4)); + } + return rawData; + } + + private static void encodeCdmaSmsAddress(CdmaSmsAddress addr) throws CodingException { + if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { + try { + addr.origBytes = addr.address.getBytes("US-ASCII"); + } catch (java.io.UnsupportedEncodingException ex) { + throw new CodingException("invalid SMS address, cannot convert to ASCII"); + } + } else { + addr.origBytes = encodeDtmfSmsAddress(addr.address); + } + } + + private static void encodeCallbackNumber(BearerData bData, BitwiseOutputStream outStream) + throws BitwiseOutputStream.AccessException, CodingException + { + CdmaSmsAddress addr = bData.callbackNumber; + encodeCdmaSmsAddress(addr); + int paramBits = 9; + int dataBits = 0; + if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { + paramBits += 7; + dataBits = addr.numberOfDigits * 8; + } else { + dataBits = addr.numberOfDigits * 4; + } + paramBits += dataBits; + int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0); + int paddingBits = (paramBytes * 8) - paramBits; + outStream.write(8, paramBytes); + outStream.write(1, addr.digitMode); + if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { + outStream.write(3, addr.ton); + outStream.write(4, addr.numberPlan); + } + outStream.write(8, addr.numberOfDigits); + outStream.writeByteArray(dataBits, addr.origBytes); + if (paddingBits > 0) outStream.write(paddingBits, 0); + } + + private static void encodeMsgStatus(BearerData bData, BitwiseOutputStream outStream) + throws BitwiseOutputStream.AccessException + { + outStream.write(8, 1); + outStream.write(2, bData.errorClass); + outStream.write(6, bData.messageStatus); + } + private static void encodeMsgCount(BearerData bData, BitwiseOutputStream outStream) + throws BitwiseOutputStream.AccessException + { + outStream.write(8, 1); + outStream.write(8, bData.numberOfMessages); + } + + private static void encodeMsgCenterTimeStamp(BearerData bData, BitwiseOutputStream outStream) + throws BitwiseOutputStream.AccessException + { + outStream.write(8, 6); + outStream.writeByteArray(6 * 8, bData.timeStamp); + } + + /** + * Create serialized representation for BearerData object. + * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details) + * + * @param bearerData an instance of BearerData. + * + * @return data byta array of raw encoded SMS bearer data. + */ + public static byte[] encode(BearerData bData) { + try { + BitwiseOutputStream outStream = new BitwiseOutputStream(200); + outStream.write(8, SUBPARAM_MESSAGE_IDENTIFIER); + encodeMessageId(bData, outStream); + if (bData.userData != null) { + outStream.write(8, SUBPARAM_USER_DATA); + encodeUserData(bData, outStream); + } + if (bData.callbackNumber != null) { + outStream.write(8, SUBPARAM_CALLBACK_NUMBER); + encodeCallbackNumber(bData, outStream); + } + if (bData.userAckReq || bData.deliveryAckReq || bData.readAckReq || bData.reportReq) { + outStream.write(8, SUBPARAM_REPLY_OPTION); + encodeReplyOption(bData, outStream); + } + if (bData.numberOfMessages != 0) { + outStream.write(8, SUBPARAM_NUMBER_OF_MESSAGES); + encodeMsgCount(bData, outStream); + } + if (bData.timeStamp != null) { + outStream.write(8, SUBPARAM_MESSAGE_CENTER_TIME_STAMP); + encodeMsgCenterTimeStamp(bData, outStream); + } + return outStream.toByteArray(); + } catch (BitwiseOutputStream.AccessException ex) { + Log.e(LOG_TAG, "BearerData encode failed: " + ex); + } catch (CodingException ex) { + Log.e(LOG_TAG, "BearerData encode failed: " + ex); + } + return null; + } + + private static void decodeMessageId(BearerData bData, BitwiseInputStream inStream) + throws BitwiseInputStream.AccessException, CodingException + { + if (inStream.read(8) != 3) { + throw new CodingException("MESSAGE_IDENTIFIER subparam size incorrect"); + } + bData.messageType = inStream.read(4); + bData.messageId = inStream.read(8) << 8; + bData.messageId |= inStream.read(8); + bData.hasUserDataHeader = (inStream.read(1) == 1); + inStream.skip(3); + } + + private static void decodeUserData(BearerData bData, BitwiseInputStream inStream) + throws BitwiseInputStream.AccessException + { + byte paramBytes = inStream.read(8); + bData.userData = new UserData(); + bData.userData.msgEncoding = inStream.read(5); + bData.userData.msgType = 0; + int consumedBits = 5; + if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) || + (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) { + bData.userData.msgType = inStream.read(8); + consumedBits += 8; + } + bData.userData.numFields = inStream.read(8); + consumedBits += 8; + int dataBits = (paramBytes * 8) - consumedBits; + bData.userData.payload = inStream.readByteArray(dataBits); + } + + private static String decodePayloadStr(byte[] data, int offset, int numFields, String format) + throws CodingException + { + try { + return new String(data, offset, numFields, format); + } catch (java.io.UnsupportedEncodingException ex) { + throw new CodingException("invalid ASCII user data code"); + } + } + + private static void decodeUserDataPayload(UserData userData, boolean hasUserDataHeader) + throws CodingException + { + int offset = 0; + if (hasUserDataHeader) { + int UdhLen = userData.payload[0]; + byte[] headerData = new byte[UdhLen]; + System.arraycopy(userData.payload, 1, headerData, 0, UdhLen); + userData.userDataHeader = SmsHeader.parse(headerData); + } + switch (userData.msgEncoding) { + case UserData.ENCODING_GSM_7BIT_ALPHABET: + userData.payloadStr = GsmAlphabet.gsm7BitPackedToString(userData.payload, + offset, userData.numFields); + break; + case UserData.ENCODING_7BIT_ASCII: + userData.payloadStr = decodePayloadStr(userData.payload, offset, + userData.numFields, "US-ASCII"); + break; + case UserData.ENCODING_UNICODE_16: + userData.payloadStr = decodePayloadStr(userData.payload, offset, + userData.numFields * 2, "UTF-16"); + break; + default: + throw new CodingException("unsupported user data encoding (" + + userData.msgEncoding + ")"); + } + } + + private static void decodeReplyOption(BearerData bData, BitwiseInputStream inStream) + throws BitwiseInputStream.AccessException, CodingException + { + byte paramBytes = inStream.read(8); + if (paramBytes != 1) { + throw new CodingException("REPLY_OPTION subparam size incorrect"); + } + bData.userAckReq = (inStream.read(1) == 1); + bData.deliveryAckReq = (inStream.read(1) == 1); + bData.readAckReq = (inStream.read(1) == 1); + bData.reportReq = (inStream.read(1) == 1); + inStream.skip(4); + } + + private static void decodeMsgCount(BearerData bData, BitwiseInputStream inStream) + throws BitwiseInputStream.AccessException, CodingException + { + if (inStream.read(8) != 1) { + throw new CodingException("NUMBER_OF_MESSAGES subparam size incorrect"); + } + bData.numberOfMessages = inStream.read(8); + } + + private static String decodeDtmfSmsAddress(byte[] rawData, int numFields) + throws CodingException + { + /* DTMF 4-bit digit encoding, defined in at + * 3GPP2 C.S005-D, v2.0, table 2.7.1.3.2.4-4 */ + StringBuffer strBuf = new StringBuffer(numFields); + for (int i = 0; i < numFields; i++) { + int val = 0x0F & (rawData[i / 2] >>> (4 - ((i % 2) * 4))); + if ((val >= 1) && (val <= 9)) strBuf.append(Integer.toString(val, 10)); + else if (val == 10) strBuf.append('0'); + else if (val == 11) strBuf.append('*'); + else if (val == 12) strBuf.append('#'); + else throw new CodingException("invalid SMS address DTMF code (" + val + ")"); + } + return strBuf.toString(); + } + + private static void decodeSmsAddress(CdmaSmsAddress addr) throws CodingException { + if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { + try { + /* As specified in 3GPP2 C.S0015-B, v2, 4.5.15 -- actually + * just 7-bit ASCII encoding, with the MSB being zero. */ + addr.address = new String(addr.origBytes, 0, addr.origBytes.length, "US-ASCII"); + } catch (java.io.UnsupportedEncodingException ex) { + throw new CodingException("invalid SMS address ASCII code"); + } + } else { + addr.address = decodeDtmfSmsAddress(addr.origBytes, addr.numberOfDigits); + } + } + + private static void decodeCallbackNumber(BearerData bData, BitwiseInputStream inStream) + throws BitwiseInputStream.AccessException, CodingException + { + byte paramBytes = inStream.read(8); + CdmaSmsAddress addr = new CdmaSmsAddress(); + addr.digitMode = inStream.read(1); + byte fieldBits = 4; + byte consumedBits = 1; + if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { + addr.ton = inStream.read(3); + addr.numberPlan = inStream.read(4); + fieldBits = 8; + consumedBits += 7; + } + addr.numberOfDigits = inStream.read(8); + consumedBits += 8; + int remainingBits = (paramBytes * 8) - consumedBits; + int dataBits = addr.numberOfDigits * fieldBits; + int paddingBits = remainingBits - dataBits; + if (remainingBits < dataBits) { + throw new CodingException("CALLBACK_NUMBER subparam encoding size error (" + + "remainingBits " + remainingBits + ", dataBits " + + dataBits + ", paddingBits " + paddingBits + ")"); + } + addr.origBytes = inStream.readByteArray(dataBits); + inStream.skip(paddingBits); + decodeSmsAddress(addr); + bData.callbackNumber = addr; + } + + private static void decodeMsgStatus(BearerData bData, BitwiseInputStream inStream) + throws BitwiseInputStream.AccessException, CodingException + { + if (inStream.read(8) != 1) { + throw new CodingException("MESSAGE_STATUS subparam size incorrect"); + } + bData.errorClass = inStream.read(2); + bData.messageStatus = inStream.read(6); + } + + private static void decodeMsgCenterTimeStamp(BearerData bData, + BitwiseInputStream inStream) + throws BitwiseInputStream.AccessException, CodingException + { + if (inStream.read(8) != 6) { + throw new CodingException("MESSAGE_CENTER_TIME_STAMP subparam size incorrect"); + } + bData.timeStamp = inStream.readByteArray(6 * 8); + } + + /** + * Create BearerData object from serialized representation. + * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details) + * + * @param smsData byte array of raw encoded SMS bearer data. + * + * @return an instance of BearerData. + */ + public static BearerData decode(byte[] smsData) { + try { + BitwiseInputStream inStream = new BitwiseInputStream(smsData); + BearerData bData = new BearerData(); + int foundSubparamMask = 0; + while (inStream.available() > 0) { + int subparamId = inStream.read(8); + int subparamIdBit = 1 << subparamId; + if ((foundSubparamMask & subparamIdBit) != 0) { + throw new CodingException("illegal duplicate subparameter (" + + subparamId + ")"); + } + foundSubparamMask |= subparamIdBit; + switch (subparamId) { + case SUBPARAM_MESSAGE_IDENTIFIER: + decodeMessageId(bData, inStream); + break; + case SUBPARAM_USER_DATA: + decodeUserData(bData, inStream); + break; + case SUBPARAM_REPLY_OPTION: + decodeReplyOption(bData, inStream); + break; + case SUBPARAM_NUMBER_OF_MESSAGES: + decodeMsgCount(bData, inStream); + break; + case SUBPARAM_CALLBACK_NUMBER: + decodeCallbackNumber(bData, inStream); + break; + case SUBPARAM_MESSAGE_STATUS: + decodeMsgStatus(bData, inStream); + break; + case SUBPARAM_MESSAGE_CENTER_TIME_STAMP: + decodeMsgCenterTimeStamp(bData, inStream); + break; + default: + throw new CodingException("unsupported bearer data subparameter (" + + subparamId + ")"); + } + } + if ((foundSubparamMask & (1 << SUBPARAM_MESSAGE_IDENTIFIER)) == 0) { + throw new CodingException("missing MESSAGE_IDENTIFIER subparam"); + } + if (bData.userData != null) { + decodeUserDataPayload(bData.userData, bData.hasUserDataHeader); + } + return bData; + } catch (BitwiseInputStream.AccessException ex) { + Log.e(LOG_TAG, "BearerData decode failed: " + ex); + } catch (CodingException ex) { + Log.e(LOG_TAG, "BearerData decode failed: " + ex); + } + return null; + } +} diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java index 1643cab46b01..440debbd354e 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java @@ -17,6 +17,7 @@ package com.android.internal.telephony.cdma.sms; import com.android.internal.telephony.SmsAddress; +import com.android.internal.util.HexDump; public class CdmaSmsAddress extends SmsAddress { /** @@ -95,4 +96,18 @@ public class CdmaSmsAddress extends SmsAddress { public CdmaSmsAddress(){ } + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("CdmaSmsAddress:\n"); + builder.append(" digitMode: " + digitMode + "\n"); + builder.append(" numberMode: " + numberMode + "\n"); + builder.append(" numberPlan: " + numberPlan + "\n"); + builder.append(" numberOfDigits: " + numberOfDigits + "\n"); + builder.append(" ton: " + ton + "\n"); + builder.append(" address: " + address + "\n"); + builder.append(" origBytes: " + HexDump.toHexString(origBytes) + "\n"); + return builder.toString(); + } + } diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsDataCoding.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsDataCoding.java deleted file mode 100644 index 6ba7463a3047..000000000000 --- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsDataCoding.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (C) 2007 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.telephony.cdma.sms; - -import com.android.internal.telephony.SmsHeader; - -/* - * The SMSDataCoding class encodes and decodes CDMA SMS messages. - */ -public class SmsDataCoding { - private final static String TAG = "CDMA_SMS_JNI"; - - private final static int CDMA_SMS_WMS_MASK_BD_NULL = 0x00000000; - private final static int CDMA_SMS_WMS_MASK_BD_MSG_ID = 0x00000001; - private final static int CDMA_SMS_WMS_MASK_BD_USER_DATA = 0x00000002; -// private final static int CDMA_SMS_WMS_MASK_BD_USER_RESP = 0x00000004; - private final static int CDMA_SMS_WMS_MASK_BD_MC_TIME = 0x00000008; -// private final static int CDMA_SMS_WMS_MASK_BD_VALID_ABS = 0x00000010; -// private final static int CDMA_SMS_WMS_MASK_BD_VALID_REL = 0x00000020; -// private final static int CDMA_SMS_WMS_MASK_BD_DEFER_ABS = 0x00000040; -// private final static int CDMA_SMS_WMS_MASK_BD_DEFER_REL = 0x00000080; -// private final static int CDMA_SMS_WMS_MASK_BD_PRIORITY = 0x00000100; -// private final static int CDMA_SMS_WMS_MASK_BD_PRIVACY = 0x00000200; -// private final static int CDMA_SMS_WMS_MASK_BD_REPLY_OPTION = 0x00000400; - private final static int CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS = 0x00000800; -// private final static int CDMA_SMS_WMS_MASK_BD_ALERT = 0x00001000; -// private final static int CDMA_SMS_WMS_MASK_BD_LANGUAGE = 0x00002000; - private final static int CDMA_SMS_WMS_MASK_BD_CALLBACK = 0x00004000; - private final static int CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE = 0x00008000; -// private final static int CDMA_SMS_WMS_MASK_BD_SCPT_DATA = 0x00010000; -// private final static int CDMA_SMS_WMS_MASK_BD_SCPT_RESULT = 0x00020000; -// private final static int CDMA_SMS_WMS_MASK_BD_DEPOSIT_INDEX = 0x00040000; -// private final static int CDMA_SMS_WMS_MASK_BD_DELIVERY_STATUS = 0x00080000; -// private final static int CDMA_SMS_WMS_MASK_BD_IP_ADDRESS = 0x10000000; -// private final static int CDMA_SMS_WMS_MASK_BD_RSN_NO_NOTIFY = 0x20000000; -// private final static int CDMA_SMS_WMS_MASK_BD_OTHER = 0x40000000; - - /** - * Successful operation. - */ - private static final int JNI_CDMA_SMS_SUCCESS = 0; - - /** - * General failure. - */ - private static final int JNI_CDMA_SMS_FAILURE = 1; - - /** - * Data length is out of length. - */ - private static final int JNI_CDMA_SMS_DATA_LEN_OUT_OF_RANGE = 2; - - /** - * Class name unknown. - */ - private static final int JNI_CDMA_SMS_CLASS_UNKNOWN = 3; - - /** - * Field ID unknown. - */ - private static final int JNI_CDMA_SMS_FIELD_ID_UNKNOWN = 4; - - /** - * Memory allocation failed. - */ - private static final int JNI_CDMA_SMS_OUT_OF_MEMORY = 5; - - /** - * Encode SMS. - * - * @param bearerData an instance of BearerData. - * - * @return the encoded SMS as byte[]. - */ - public static byte[] encodeCdmaSms(BearerData bearerData) { - byte[] encodedSms; - - if( nativeCdmaSmsConstructClientBD() == JNI_CDMA_SMS_FAILURE){ - return null; - } - - // check bearer data and generate bit mask - generateBearerDataBitMask(bearerData); - encodedSms = startEncoding(bearerData); - - if( nativeCdmaSmsDestructClientBD() == JNI_CDMA_SMS_FAILURE){ - return null; - } - return encodedSms; - } - - /** - * Decode SMS. - * - * @param SmsData the encoded SMS. - * - * @return an instance of BearerData. - */ - public static BearerData decodeCdmaSms(byte[] SmsData) { - BearerData bearerData; - - if( nativeCdmaSmsConstructClientBD() == JNI_CDMA_SMS_FAILURE){ - return null; - } - - bearerData = startDecoding(SmsData); - - if( nativeCdmaSmsDestructClientBD() == JNI_CDMA_SMS_FAILURE){ - return null; - } - return bearerData; - } - - private static void generateBearerDataBitMask(BearerData bearerData) { - // initial - bearerData.mask = CDMA_SMS_WMS_MASK_BD_NULL; - - // check message type - if (bearerData.messageType != 0){ - bearerData.mask |= CDMA_SMS_WMS_MASK_BD_MSG_ID; - } - - // check mUserData - if (bearerData.userData != null){ - bearerData.mask |= CDMA_SMS_WMS_MASK_BD_USER_DATA; - } - - // check mTimeStamp - if (bearerData.timeStamp != null){ - bearerData.mask |= CDMA_SMS_WMS_MASK_BD_MC_TIME; - } - - // check mNumberOfMessages - if (bearerData.numberOfMessages > 0){ - bearerData.mask |= CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS; - } - - // check mCallbackNumber - if(bearerData.callbackNumber != null){ - bearerData.mask |= CDMA_SMS_WMS_MASK_BD_CALLBACK; - } - - // check DisplayMode - if(bearerData.displayMode == BearerData.DISPLAY_DEFAULT || - bearerData.displayMode == BearerData.DISPLAY_IMMEDIATE || - bearerData.displayMode == BearerData.DISPLAY_USER){ - bearerData.mask |= CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE; - } - } - - private static byte[] startEncoding(BearerData bearerData) { - int m_id; - byte[] m_data; - int dataLength; - byte[] encodedSms; - int nbrOfHeaders = 0; - - if( nativeCdmaSmsSetBearerDataPrimitives(bearerData) == JNI_CDMA_SMS_FAILURE){ - return null; - } - - if ((bearerData.mask & CDMA_SMS_WMS_MASK_BD_USER_DATA) == CDMA_SMS_WMS_MASK_BD_USER_DATA){ - if( nativeCdmaSmsSetUserData(bearerData.userData) == JNI_CDMA_SMS_FAILURE){ - return null; - } - - if (bearerData.userData.userDataHeader != null){ - nbrOfHeaders = bearerData.userData.userDataHeader.nbrOfHeaders; - } - - for (int i = 0; i < nbrOfHeaders; i++) { - m_id = bearerData.userData.userDataHeader.getElements().get(i).getID(); - m_data = bearerData.userData.userDataHeader.getElements().get(i).getData(); - dataLength = m_data.length; - if( nativeCdmaSmsSetUserDataHeader(m_id, m_data, dataLength, i) - == JNI_CDMA_SMS_FAILURE){ - return null; - } - } - } - - if ((bearerData.mask & CDMA_SMS_WMS_MASK_BD_CALLBACK) == CDMA_SMS_WMS_MASK_BD_CALLBACK) { - if( nativeCdmaSmsSetSmsAddress(bearerData.callbackNumber) == JNI_CDMA_SMS_FAILURE){ - return null; - } - } - - /* call native method to encode SMS */ - encodedSms = nativeCdmaSmsEncodeSms(); - - return encodedSms; - } - - private static BearerData startDecoding(byte[] SmsData) { - BearerData bData = new BearerData(); - byte[] udhData; - - /* call native method to decode SMS */ - if( nativeCdmaSmsDecodeSms(SmsData) == JNI_CDMA_SMS_FAILURE){ - return null; - } - - if( nativeCdmaSmsGetBearerDataPrimitives(bData) == JNI_CDMA_SMS_FAILURE){ - return null; - } - - if ((bData.mask & CDMA_SMS_WMS_MASK_BD_USER_DATA) == CDMA_SMS_WMS_MASK_BD_USER_DATA) { - bData.userData = new UserData(); - if( nativeCdmaSmsGetUserData(bData.userData) == JNI_CDMA_SMS_FAILURE){ - return null; - } - - udhData = nativeCdmaSmsGetUserDataHeader(); - if (udhData != null) { - bData.userData.userDataHeader = SmsHeader.parse(udhData); - } - } - - if ((bData.mask & CDMA_SMS_WMS_MASK_BD_CALLBACK) == CDMA_SMS_WMS_MASK_BD_CALLBACK) { - bData.callbackNumber = new CdmaSmsAddress(); - if( nativeCdmaSmsGetSmsAddress(bData.callbackNumber) == JNI_CDMA_SMS_FAILURE){ - return null; - } - } - - return bData; - } - - // native methods - - /** - * native method: Allocate memory for clientBD structure - * - * @return #JNI_CDMA_SMS_SUCCESS if succeed. - * #JNI_CDMA_SMS_FAILURE if fail. - */ - private static native int nativeCdmaSmsConstructClientBD(); - - /** - * native method: Free memory used for clientBD structure - * - * @return #JNI_CDMA_SMS_SUCCESS if succeed. - * #JNI_CDMA_SMS_FAILURE if fail. - */ - private static native int nativeCdmaSmsDestructClientBD(); - - /** - * native method: fill clientBD structure with bearerData primitives - * - * @param bearerData an instance of BearerData. - * - * @return #JNI_CDMA_SMS_SUCCESS if succeed. - * #JNI_CDMA_SMS_FAILURE if fail. - */ - private static native int nativeCdmaSmsSetBearerDataPrimitives(BearerData bearerData); - - /** - * native method: fill bearerData primitives with clientBD variables - * - * @param bearerData an instance of BearerData. - * - * @return #JNI_CDMA_SMS_SUCCESS if succeed. - * #JNI_CDMA_SMS_FAILURE if fail. - */ - private static native int nativeCdmaSmsGetBearerDataPrimitives(BearerData bearerData); - - /** - * native method: fill clientBD.user_data with UserData primitives - * - * @param userData an instance of UserData. - * - * @return #JNI_CDMA_SMS_SUCCESS if succeed. - * #JNI_CDMA_SMS_FAILURE if fail. - */ - private static native int nativeCdmaSmsSetUserData(UserData userData); - - /** - * native method: fill UserData primitives with clientBD.user_data - * - * @param userData an instance of UserData. - * - * @return #JNI_CDMA_SMS_SUCCESS if succeed. - * #JNI_CDMA_SMS_FAILURE if fail. - */ - private static native int nativeCdmaSmsGetUserData(UserData userData); - - /** - * native method: fill clientBD.user_data.headers with UserDataHeader primitives - * - * @param ID ID of element. - * @param data element data. - * @param dataLength data length - * @param index index of element - * - * @return #JNI_CDMA_SMS_SUCCESS if succeed. - * #JNI_CDMA_SMS_FAILURE if fail. - */ - private static native int nativeCdmaSmsSetUserDataHeader( - int ID, byte[] data, int dataLength, int index); - - /** - * native method: fill UserDataHeader primitives with clientBD.user_data.headers - * - * @return user data headers - */ - private static native byte[] nativeCdmaSmsGetUserDataHeader(); - - /** - * native method: fill clientBD.callback with SmsAddress primitives - * - * @param smsAddr an instance of SmsAddress. - * - * @return #JNI_CDMA_SMS_SUCCESS if succeed. - * #JNI_CDMA_SMS_FAILURE if fail. - */ - private static native int nativeCdmaSmsSetSmsAddress(CdmaSmsAddress smsAddr); - - /** - * native method: fill SmsAddress primitives with clientBD.callback - * - * @param smsAddr an instance of SmsAddress. - * - * @return #JNI_CDMA_SMS_SUCCESS if succeed. - * #JNI_CDMA_SMS_FAILURE if fail. - */ - private static native int nativeCdmaSmsGetSmsAddress(CdmaSmsAddress smsAddr); - - /** - * native method: call encoding functions and get encoded SMS - * - * @return the encoded SMS - */ - private static native byte[] nativeCdmaSmsEncodeSms(); - - /** - * native method: call decode functions - * - * @param encodedSMS encoded SMS. - * - * @return #JNI_CDMA_SMS_SUCCESS if succeed. - * #JNI_CDMA_SMS_FAILURE if fail. - */ - private static native int nativeCdmaSmsDecodeSms(byte[] encodedSMS); - - /** - * Load the shared library to link the native methods. - */ - static { - try { - System.loadLibrary("cdma_sms_jni"); - } - catch (UnsatisfiedLinkError ule) { - System.err.println("WARNING: Could not load cdma_sms_jni.so"); - } - } -} - diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java index e7614694eae7..bd6fbb48448d 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java @@ -17,24 +17,25 @@ package com.android.internal.telephony.cdma.sms; import com.android.internal.telephony.SmsHeader; +import com.android.internal.util.HexDump; public class UserData{ /** - * Supported user data encoding types + * User data encoding types * (See 3GPP2 C.R1001-F, v1.0, table 9.1-1) */ - public static final int UD_ENCODING_OCTET = 0x00; - //public static final int UD_ENCODING_EXTENDED_PROTOCOL = 0x01; - public static final int UD_ENCODING_7BIT_ASCII = 0x02; - public static final int UD_ENCODING_IA5 = 0x03; - public static final int UD_ENCODING_UNICODE_16 = 0x04; - //public static final int UD_ENCODING_SHIFT_JIS = 0x05; - //public static final int UD_ENCODING_KOREAN = 0x06; - //public static final int UD_ENCODING_LATIN_HEBREW = 0x07; - //public static final int UD_ENCODING_LATIN = 0x08; - public static final int UD_ENCODING_GSM_7BIT_ALPHABET = 0x09; - //public static final int UD_ENCODING_GSM_DCS = 0x0A; + public static final int ENCODING_OCTET = 0x00; + public static final int ENCODING_IS91_EXTENDED_PROTOCOL = 0x01; + public static final int ENCODING_7BIT_ASCII = 0x02; + //public static final int ENCODING_IA5 = 0x03; + public static final int ENCODING_UNICODE_16 = 0x04; + //public static final int ENCODING_SHIFT_JIS = 0x05; + //public static final int ENCODING_KOREAN = 0x06; + //public static final int ENCODING_LATIN_HEBREW = 0x07; + //public static final int ENCODING_LATIN = 0x08; + public static final int ENCODING_GSM_7BIT_ALPHABET = 0x09; + public static final int ENCODING_GSM_DCS = 0x0A; /** * Contains the data header of the user data @@ -44,20 +45,37 @@ public class UserData{ /** * Contains the data encoding type for the SMS message */ - public int userDataEncoding; + public int msgEncoding; - // needed when encoding is IS91 or DCS (not supported yet): - //public int messageType; + // XXX needed when encoding is IS91 or DCS (not supported yet): + public int msgType; /** * Number of invalid bits in the last byte of data. */ public int paddingBits; + public int numFields; + /** * Contains the user data of a SMS message * (See 3GPP2 C.S0015-B, v2, 4.5.2) */ - public byte[] userData; + public byte[] payload; + public String payloadStr; + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("UserData:\n"); + builder.append(" msgEncoding: " + msgEncoding + "\n"); + builder.append(" msgType: " + msgType + "\n"); + builder.append(" paddingBits: " + paddingBits + "\n"); + builder.append(" numFields: " + (int)numFields + "\n"); + builder.append(" userDataHeader: " + userDataHeader + "\n"); + builder.append(" payload: " + HexDump.toHexString(payload)); + builder.append(" payloadStr: " + payloadStr); + return builder.toString(); + } } diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java index d1ae997239ec..a2d3c5e38047 100644..100755 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java @@ -316,6 +316,11 @@ public class GSMPhone extends PhoneBase { // we report data connected ret = DataState.CONNECTED; + } else if (mSST == null) { + // Radio Technology Change is ongoning, dispose() and removeReferences() have + // already been called + + ret = DataState.DISCONNECTED; } else if (mSST.getCurrentGprsState() != ServiceState.STATE_IN_SERVICE) { // If we're out of service, open TCP sockets may still work diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index e2da7cb71cc1..9ca46108dcd5 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -131,7 +131,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { private static int APN_DEFAULT_ID = 0; private static int APN_MMS_ID = 1; - private static int APN_NUM_TYPES = 2; + private static int APN_SUPL_ID = 2; + private static int APN_NUM_TYPES = 3; private boolean[] dataEnabled = new boolean[APN_NUM_TYPES]; @@ -322,8 +323,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { /** * Ensure that we are connected to an APN of the specified type. - * @param type the APN type (currently the only valid value - * is {@link Phone#APN_TYPE_MMS}) + * @param type the APN type (currently the only valid values + * are {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}) * @return the result of the operation. Success is indicated by * a return value of either {@code Phone.APN_ALREADY_ACTIVE} or * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a broadcast @@ -331,9 +332,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { * the APN has been established. */ protected int enableApnType(String type) { - if (!TextUtils.equals(type, Phone.APN_TYPE_MMS)) { + if (!TextUtils.equals(type, Phone.APN_TYPE_MMS) && + !TextUtils.equals(type, Phone.APN_TYPE_SUPL)) { return Phone.APN_REQUEST_FAILED; } + // If already active, return Log.d(LOG_TAG, "enableApnType("+type+")"); if (isApnTypeActive(type)) { @@ -366,12 +369,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { * The APN of the specified type is no longer needed. Ensure that if * use of the default APN has not been explicitly disabled, we are connected * to the default APN. - * @param type the APN type. The only valid value currently is {@link Phone#APN_TYPE_MMS}. + * @param type the APN type. The only valid values are currently + * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}. * @return */ protected int disableApnType(String type) { Log.d(LOG_TAG, "disableApnType("+type+")"); - if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) { + if ((TextUtils.equals(type, Phone.APN_TYPE_MMS) || + TextUtils.equals(type, Phone.APN_TYPE_SUPL)) + && isEnabled(type)) { removeMessages(EVENT_RESTORE_DEFAULT_APN); setEnabled(type, false); if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { @@ -439,6 +445,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { return dataEnabled[APN_DEFAULT_ID]; } else if (TextUtils.equals(apnType, Phone.APN_TYPE_MMS)) { return dataEnabled[APN_MMS_ID]; + } else if (TextUtils.equals(apnType, Phone.APN_TYPE_SUPL)) { + return dataEnabled[APN_SUPL_ID]; } else { return false; } @@ -450,9 +458,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { dataEnabled[APN_DEFAULT_ID] = enable; } else if (TextUtils.equals(apnType, Phone.APN_TYPE_MMS)) { dataEnabled[APN_MMS_ID] = enable; + } else if (TextUtils.equals(apnType, Phone.APN_TYPE_SUPL)) { + dataEnabled[APN_SUPL_ID] = enable; } Log.d(LOG_TAG, "dataEnabled[DEFAULT_APN]=" + dataEnabled[APN_DEFAULT_ID] + - " dataEnabled[MMS_APN]=" + dataEnabled[APN_MMS_ID]); + " dataEnabled[MMS_APN]=" + dataEnabled[APN_MMS_ID] + + " dataEnabled[SUPL_APN]=" + dataEnabled[APN_SUPL_ID]); } /** @@ -476,13 +487,14 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { return trySetupData(Phone.REASON_DATA_ENABLED); } else if (!enable) { setEnabled(Phone.APN_TYPE_DEFAULT, false); - // Don't tear down if there is an active APN and it handles MMS. + // Don't tear down if there is an active APN and it handles MMS or SUPL. // TODO: This isn't very general. - if (!isApnTypeActive(Phone.APN_TYPE_MMS) || !isEnabled(Phone.APN_TYPE_MMS)) { - cleanUpConnection(true, Phone.REASON_DATA_DISABLED); - return true; + if ((isApnTypeActive(Phone.APN_TYPE_MMS) && isEnabled(Phone.APN_TYPE_MMS)) || + (isApnTypeActive(Phone.APN_TYPE_SUPL) && isEnabled(Phone.APN_TYPE_SUPL))) { + return false; } - return false; + cleanUpConnection(true, Phone.REASON_DATA_DISABLED); + return true; } else { // isEnabled && enable return true; @@ -513,7 +525,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { * {@code true} otherwise. */ public boolean getAnyDataEnabled() { - return dataEnabled[APN_DEFAULT_ID] || dataEnabled[APN_MMS_ID]; + return dataEnabled[APN_DEFAULT_ID] || dataEnabled[APN_MMS_ID] || dataEnabled[APN_SUPL_ID]; } /** @@ -1316,7 +1328,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { * rather an app that inadvertantly fails to reset to the * default APN, or that dies before doing so. */ - if (dataEnabled[APN_MMS_ID]) { + if (dataEnabled[APN_MMS_ID] || dataEnabled[APN_SUPL_ID]) { removeMessages(EVENT_RESTORE_DEFAULT_APN); sendMessageDelayed(obtainMessage(EVENT_RESTORE_DEFAULT_APN), getRestoreDefaultApnDelay()); diff --git a/telephony/jni/cdmasms/Android.mk b/telephony/jni/cdmasms/Android.mk deleted file mode 100644 index b0c96b4361a2..000000000000 --- a/telephony/jni/cdmasms/Android.mk +++ /dev/null @@ -1,24 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - cdma_sms_jni.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libutils \ - libandroid_runtime \ - libnativehelper - -LOCAL_MODULE:= libcdma_sms_jni - -LOCAL_C_INCLUDES += \ - $(JNI_H_INCLUDE) \ - hardware/ril/include/telephony - -LOCAL_C_INCLUDES += hardware/ril/reference-cdma-sms -LOCAL_SHARED_LIBRARIES += libreference-cdma-sms -LOCAL_CFLAGS += -DREFERENCE_CDMA_SMS - -LOCAL_PRELINK_MODULE := false -include $(BUILD_SHARED_LIBRARY) diff --git a/telephony/jni/cdmasms/cdma_sms_jni.cpp b/telephony/jni/cdmasms/cdma_sms_jni.cpp deleted file mode 100644 index 2a8e8254f33f..000000000000 --- a/telephony/jni/cdmasms/cdma_sms_jni.cpp +++ /dev/null @@ -1,1300 +0,0 @@ -/* - * Copyright (C) 2008 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. - */ - -/** - * @file cdma_sms_jni.cpp - * - * This file implement the Java Native Interface - * for encoding and decoding of SMS - */ - - -#include <nativehelper/jni.h> -#include <nativehelper/JNIHelp.h> -#include <android_runtime/AndroidRuntime.h> -#include <cdma_sms_jni.h> - - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -#include <reference-cdma-sms.h> - -#ifdef __cplusplus -} -#endif //__cplusplus - -#undef LOG_TAG -#define LOG_TAG "CDMA" -#include <utils/Log.h> - -static RIL_CDMA_SMS_ClientBd *clientBdData = NULL; - - -static jint getObjectIntField(JNIEnv * env, jobject obj, const char *name, jint * value) -{ - jclass clazz; - jfieldID field; - -#ifdef DBG_LOG_LEVEL_B - LOGD("getObjectIntField():"); -#endif - - clazz = env->GetObjectClass(obj); - if (NULL == clazz) { - jniThrowException(env, "java/lang/Exception", NULL); - return JNI_FAILURE; - } - - field = env->GetFieldID(clazz, name, "I"); - env->DeleteLocalRef(clazz); - - if (NULL == field) { - jniThrowException(env, "java/lang/NoSuchFieldException", name); - return JNI_FAILURE; - } - - *value = env->GetIntField(obj, field); - -#ifdef DBG_LOG_LEVEL_B - LOGD(" %s = %d\n", name, *value); -#endif - - return JNI_SUCCESS; -} - -static jint setObjectIntField(JNIEnv * env, jobject obj, const char *name, jint value) -{ - jclass clazz; - jfieldID field; - -#ifdef DBG_LOG_LEVEL_B - LOGD("setObjectIntField(): %s = %d\n", name, value); -#endif - - clazz = env->GetObjectClass(obj); - if (NULL == clazz) { - jniThrowException(env, "java/lang/Exception", NULL); - return JNI_FAILURE; - } - - field = env->GetFieldID(clazz, name, "I"); - env->DeleteLocalRef(clazz); - - if (NULL == field) { - jniThrowException(env, "java/lang/NoSuchFieldException", name); - return JNI_FAILURE; - } - - env->SetIntField(obj, field, value); - - return JNI_SUCCESS; -} - -static jint getObjectByteField(JNIEnv * env, jobject obj, const char *name, jbyte * value) -{ - jclass clazz; - jfieldID field; - -#ifdef DBG_LOG_LEVEL_B - LOGD("getObjectByteField():"); -#endif - - clazz = env->GetObjectClass(obj); - if (NULL == clazz) { - jniThrowException(env, "java/lang/Exception", NULL); - return JNI_FAILURE; - } - - field = env->GetFieldID(clazz, name, "B"); - env->DeleteLocalRef(clazz); - - if (NULL == field) { - jniThrowException(env, "java/lang/NoSuchFieldException", name); - return JNI_FAILURE; - } - - *value = env->GetByteField(obj, field); - -#ifdef DBG_LOG_LEVEL_B - LOGD(" %s = %02x\n", name, *value); -#endif - - return JNI_SUCCESS; -} - -static jint setObjectByteField(JNIEnv * env, jobject obj, const char *name, jbyte value) -{ - jclass clazz; - jfieldID field; -#ifdef DBG_LOG_LEVEL_B - LOGD("setObjectByteField(): %s = 0x%02x\n", name, value); -#endif - - clazz = env->GetObjectClass(obj); - if (NULL == clazz) { - jniThrowException(env, "java/lang/Exception", NULL); - return JNI_FAILURE; - } - - field = env->GetFieldID(clazz, name, "B"); - env->DeleteLocalRef(clazz); - - if (NULL == field) { - jniThrowException(env, "java/lang/NoSuchFieldException", name); - return JNI_FAILURE; - } - - env->SetByteField(obj, field, value); - - return JNI_SUCCESS; -} - -static jint getObjectBooleanField(JNIEnv * env, jobject obj, const char *name, jboolean * value) -{ - jclass clazz; - jfieldID field; - -#ifdef DBG_LOG_LEVEL_B - LOGD("getObjectBooleanField():"); -#endif - - clazz = env->GetObjectClass(obj); - if (NULL == clazz) { - jniThrowException(env, "java/lang/Exception", NULL); - return JNI_FAILURE; - } - - field = env->GetFieldID(clazz, name, "Z"); - env->DeleteLocalRef(clazz); - - if (NULL == field) { - jniThrowException(env, "java/lang/NoSuchFieldException", name); - return JNI_FAILURE; - } - - *value = env->GetBooleanField(obj, field); - -#ifdef DBG_LOG_LEVEL_B - LOGD(" %s = %d\n", name, *value); -#endif - - return JNI_SUCCESS; -} - -static jint setObjectBooleanField(JNIEnv * env, jobject obj, const char *name, jboolean value) -{ - jclass clazz; - jfieldID field; - -#ifdef DBG_LOG_LEVEL_B - LOGD("setObjectBooleanField(): %s = %d\n", name, value); -#endif - - clazz = env->GetObjectClass(obj); - if (NULL == clazz) { - jniThrowException(env, "java/lang/Exception", NULL); - return JNI_FAILURE; - } - - field = env->GetFieldID(clazz, name, "Z"); - env->DeleteLocalRef(clazz); - - if (NULL == field) { - jniThrowException(env, "java/lang/NoSuchFieldException", name); - return JNI_FAILURE; - } - - env->SetBooleanField(obj, field, value); - - return JNI_SUCCESS; -} - -static jint getObjectByteArrayField(JNIEnv * env, jobject obj, const char *name, jbyte* arrData, int* length) -{ - jclass clazz; - jfieldID field; - jbyte * data_buf; - -#ifdef DBG_LOG_LEVEL_B - LOGD("getObjectByteArrayField(): %s\n", name); -#endif - - clazz = env->GetObjectClass(obj); - if (NULL == clazz) { - jniThrowException(env, "java/lang/Exception", NULL); - return JNI_FAILURE; - } - - field = env->GetFieldID(clazz, name, "[B"); - env->DeleteLocalRef(clazz); - - if (NULL == field) { - jniThrowException(env, "java/lang/NoSuchFieldException", name); - return JNI_FAILURE; - } - - jbyteArray buffer = (jbyteArray)(env->GetObjectField(obj, field)); - if (buffer != NULL) { - int len = env->GetArrayLength(buffer); - data_buf = env->GetByteArrayElements(buffer, NULL); - for (int i=0; i<len; i++) { - *arrData++ = data_buf[i]; -#ifdef DBG_LOG_LEVEL_B - LOGD(" [%d] = 0x%02x\n", i, data_buf[i]); -#endif - } - *length = len; - } else { - jniThrowException(env, "java/lang/NullPointerException", NULL); - return JNI_FAILURE; - } - - return JNI_SUCCESS; -} - -static jint setObjectByteArrayField(JNIEnv * env, jobject obj, const char *name, jbyte* arrData, int length) -{ - jclass clazz; - jfieldID field; - jbyte* byte_buf; - -#ifdef DBG_LOG_LEVEL_B - LOGD("setObjectByteArrayField(): %s\n", name); -#endif - - clazz = env->GetObjectClass(obj); - if (NULL == clazz) { - jniThrowException(env, "java/lang/Exception", NULL); - return JNI_FAILURE; - } - - field = env->GetFieldID(clazz, name, "[B"); - env->DeleteLocalRef(clazz); - - if (NULL == field) { - jniThrowException(env, "java/lang/NoSuchFieldException", name); - return JNI_FAILURE; - } - - jbyteArray buffer = (jbyteArray)(env->GetObjectField(obj, field)); - if (buffer == NULL) { -#ifdef DBG_LOG_LEVEL_B - LOGD("setObjectByteArrayField(): %s = null\n", name); -#endif - buffer = env->NewByteArray(length); - env->SetObjectField(obj, field, buffer); - } - - if (buffer != NULL) { -#ifdef DBG_LOG_LEVEL_B - for (int i=0; i<length; i++) { - LOGD(" [%d] = 0x%02x\n", i, arrData[i]); - } -#endif - env->SetByteArrayRegion(buffer, 0, length, arrData); - } else { - jniThrowException(env, "java/lang/NullPointerException", NULL); - return JNI_FAILURE; - } - - return JNI_SUCCESS; -} - - -/* native interface */ -JNIEXPORT jint JNICALL -Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsConstructClientBD - (JNIEnv * env, jobject obj) -{ -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsConstructClientBD()...\n"); -#endif - - clientBdData = (RIL_CDMA_SMS_ClientBd *)malloc(sizeof(RIL_CDMA_SMS_ClientBd)); - if (NULL == clientBdData) { - jniThrowException(env, "java/lang/OutOfMemoryError", "clientBdData memory allocation failed"); - return JNI_FAILURE; - } - memset(clientBdData, 0, sizeof(RIL_CDMA_SMS_ClientBd)); - return JNI_SUCCESS; -} - - -/* native interface */ -JNIEXPORT jint JNICALL -Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDestructClientBD - (JNIEnv * env, jobject obj) -{ -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsDestructClientBD()...\n"); -#endif - - if (clientBdData == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "clientBdData is null"); - return JNI_FAILURE; - } - free(clientBdData); - return JNI_SUCCESS; -} - - -/* native interface */ -JNIEXPORT jint JNICALL -Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetBearerDataPrimitives - (JNIEnv * env, jobject obj, jobject bearerData) -{ - jbyteArray mc_time = NULL; - jbyte mctime_buffer[6]; - int length; - jint intData; - jbyte byteData; - jboolean booleanData; - -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsSetBearerDataPrimitives()...\n"); -#endif - - // mask - if (getObjectIntField(env, bearerData, "mask", &intData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->mask = intData; -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->mask = 0x%x\n", clientBdData->mask); -#endif - - // message_id.type - if (getObjectByteField(env, bearerData, "messageType", &byteData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->message_id.type = (RIL_CDMA_SMS_BdMessageType)(byteData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->message_id.type = 0x%02x\n", clientBdData->message_id.type); -#endif - - // message_id.id_number - if ((clientBdData->mask & WMS_MASK_BD_MSG_ID) == WMS_MASK_BD_MSG_ID) { - if (getObjectIntField(env, bearerData, "messageID", &intData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->message_id.id_number = (RIL_CDMA_SMS_MessageNumber)(intData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->message_id.id_number = %d\n", clientBdData->message_id.id_number); -#endif - } - - // message_id.udh_present - if (getObjectBooleanField(env, bearerData, "hasUserDataHeader", &booleanData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->message_id.udh_present = (unsigned char)(booleanData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->message_id.udh_present = %d\n", clientBdData->message_id.udh_present); -#endif - - // user_response - // TODO - - // mc_time - if ((clientBdData->mask & WMS_MASK_BD_MC_TIME) == WMS_MASK_BD_MC_TIME) { - if (getObjectByteArrayField(env, bearerData, "timeStamp", mctime_buffer, &length) != JNI_SUCCESS) - return JNI_FAILURE; - if (mctime_buffer != NULL) { - clientBdData->mc_time.year = mctime_buffer[0]; - clientBdData->mc_time.month = mctime_buffer[1]; - clientBdData->mc_time.day = mctime_buffer[2]; - clientBdData->mc_time.hour = mctime_buffer[3]; - clientBdData->mc_time.minute = mctime_buffer[4]; - clientBdData->mc_time.second = mctime_buffer[5]; -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->mc_time.year = %d\n", clientBdData->mc_time.year); - LOGD("clientBdData->mc_time.month = %d\n", clientBdData->mc_time.month); - LOGD("clientBdData->mc_time.day = %d\n", clientBdData->mc_time.day); - LOGD("clientBdData->mc_time.hour = %d\n", clientBdData->mc_time.hour); - LOGD("clientBdData->mc_time.minute = %d\n", clientBdData->mc_time.minute); - LOGD("clientBdData->mc_time.second = %d\n", clientBdData->mc_time.second); -#endif - } - } - - // clientBdData->mc_time.timezone - // TODO - - // validity_absolute; - // TODO - - // validity_relative; - // TODO - - // deferred_absolute - // TODO - - // deferred_relative; - // TODO - - // priority - // TODO - - // privacy - // TODO - - if ((clientBdData->mask & WMS_MASK_BD_REPLY_OPTION) == WMS_MASK_BD_REPLY_OPTION) { - // reply_option.user_ack_requested - if (getObjectBooleanField(env, bearerData, "userAckReq", &booleanData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->reply_option.user_ack_requested = (unsigned char)(booleanData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->reply_option.user_ack_requested = %d\n", clientBdData->reply_option.user_ack_requested); -#endif - // reply_option.user_ack_requested - if (getObjectBooleanField(env, bearerData, "deliveryAckReq", &booleanData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->reply_option.delivery_ack_requested = (unsigned char)(booleanData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->reply_option.delivery_ack_requested = %d\n", clientBdData->reply_option.delivery_ack_requested); -#endif - // reply_option.user_ack_requested - if (getObjectBooleanField(env, bearerData, "readAckReq", &booleanData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->reply_option.read_ack_requested = (unsigned char)(booleanData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->reply_option.read_ack_requested = %d\n", clientBdData->reply_option.read_ack_requested); -#endif - } - - // num_messages - if ((clientBdData->mask & WMS_MASK_BD_NUM_OF_MSGS) == WMS_MASK_BD_NUM_OF_MSGS) { - if (getObjectIntField(env, bearerData, "numberOfMessages", &intData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->num_messages = (unsigned char)(intData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->num_messages = %d\n", clientBdData->num_messages); -#endif - } - - // alert_mode - // TODO - - // language - // TODO - - // display_mode - if ((clientBdData->mask & WMS_MASK_BD_DISPLAY_MODE) == WMS_MASK_BD_DISPLAY_MODE) { - if (getObjectByteField(env, bearerData, "displayMode", &byteData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->display_mode = (RIL_CDMA_SMS_DisplayMode)(byteData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->display_mode = 0x%02x\n", clientBdData->display_mode); -#endif - } - - // delivery_status - if ((clientBdData->mask & WMS_MASK_BD_DELIVERY_STATUS) == WMS_MASK_BD_DELIVERY_STATUS) { - // delivery_status.error_class - if (getObjectIntField(env, bearerData, "errorClass", &intData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->delivery_status.error_class = (RIL_CDMA_SMS_ErrorClass)(intData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->delivery_status.error_class = %d\n", clientBdData->delivery_status.error_class); -#endif - // delivery_status.status - if (getObjectIntField(env, bearerData, "messageStatus", &intData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->delivery_status.status = (RIL_CDMA_SMS_DeliveryStatusE)(intData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->delivery_status.status = %d\n", clientBdData->delivery_status.status); -#endif - } - - // deposit_index - // TODO - - // ip_address - // TODO - - // rsn_no_notify - // TODO - - // other - // TODO - - return JNI_SUCCESS; -} - - -/* native interface */ -JNIEXPORT jint JNICALL -Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetBearerDataPrimitives - (JNIEnv * env, jobject obj, jobject bearerData) -{ - jclass BearerDataClass; - jfieldID field; - jbyte mctime_buffer[6]; - jbyteArray addr_array; - int length; - -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsGetBearerDataPrimitives()...\n"); -#endif - - // mask -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->mask = 0x%x\n", clientBdData->mask); -#endif - if (setObjectIntField(env, bearerData, "mask", clientBdData->mask) != JNI_SUCCESS) - return JNI_FAILURE; - - // message_id.type -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->message_id.type = 0x%02x\n", clientBdData->message_id.type); -#endif - if (setObjectByteField(env, bearerData, "messageType", (jbyte)clientBdData->message_id.type) != JNI_SUCCESS) - return JNI_FAILURE; - - // message_id.id_number - if ((clientBdData->mask & WMS_MASK_BD_MSG_ID) == WMS_MASK_BD_MSG_ID) { -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->message_id.id_number = %d\n", clientBdData->message_id.id_number); -#endif - if (setObjectIntField(env, bearerData, "messageID", clientBdData->message_id.id_number) != JNI_SUCCESS) - return JNI_FAILURE; - } - - // message_id.udh_present -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->message_id.udh_present = %d\n", clientBdData->message_id.udh_present); -#endif - if (setObjectBooleanField(env, bearerData, "hasUserDataHeader", (jboolean)clientBdData->message_id.udh_present) != JNI_SUCCESS) - return JNI_FAILURE; - - // user_response - // TODO - - // mc_time - if ((clientBdData->mask & WMS_MASK_BD_MC_TIME) == WMS_MASK_BD_MC_TIME) { - jclass clazz= env->GetObjectClass(bearerData); - if (NULL == clazz) - return JNI_FAILURE; - jfieldID field = env->GetFieldID(clazz, "timeStamp", "[B"); - env->DeleteLocalRef(clazz); - - addr_array = env->NewByteArray((jsize)6); - env->SetObjectField(bearerData, field, addr_array); - -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->mc_time.year = %d\n", clientBdData->mc_time.year); - LOGD("clientBdData->mc_time.month = %d\n", clientBdData->mc_time.month); - LOGD("clientBdData->mc_time.day = %d\n", clientBdData->mc_time.day); - LOGD("clientBdData->mc_time.hour = %d\n", clientBdData->mc_time.hour); - LOGD("clientBdData->mc_time.minute = %d\n", clientBdData->mc_time.minute); - LOGD("clientBdData->mc_time.second = %d\n", clientBdData->mc_time.second); -#endif - mctime_buffer[0] = clientBdData->mc_time.year; - mctime_buffer[1] = clientBdData->mc_time.month; - mctime_buffer[2] = clientBdData->mc_time.day; - mctime_buffer[3] = clientBdData->mc_time.hour; - mctime_buffer[4] = clientBdData->mc_time.minute; - mctime_buffer[5] = clientBdData->mc_time.second; - length = sizeof(mctime_buffer) / sizeof(jbyte); - if (setObjectByteArrayField(env, bearerData, "timeStamp", mctime_buffer, length) != JNI_SUCCESS) - return JNI_FAILURE; - } - - // clientBdData->mc_time.timezone - // TODO - - // validity_absolute; - // TODO - - // validity_relative; - // TODO - - // deferred_absolute - // TODO - - // deferred_relative; - // TODO - - // priority - // TODO - - // privacy - // TODO - - if ((clientBdData->mask & WMS_MASK_BD_REPLY_OPTION) == WMS_MASK_BD_REPLY_OPTION) { - // reply_option.user_ack_requested -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->reply_option.user_ack_requested = %d\n", clientBdData->reply_option.user_ack_requested); -#endif - if (setObjectBooleanField(env, bearerData, "userAckReq", (jboolean)clientBdData->reply_option.user_ack_requested) != JNI_SUCCESS) - return JNI_FAILURE; - - // reply_option.user_ack_requested -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->reply_option.delivery_ack_requested = %d\n", clientBdData->reply_option.delivery_ack_requested); -#endif - if (setObjectBooleanField(env, bearerData, "deliveryAckReq", (jboolean)clientBdData->reply_option.delivery_ack_requested) != JNI_SUCCESS) - return JNI_FAILURE; - - // reply_option.user_ack_requested -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->reply_option.read_ack_requested = %d\n", clientBdData->reply_option.read_ack_requested); -#endif - if (setObjectBooleanField(env, bearerData, "readAckReq", (jboolean)clientBdData->reply_option.read_ack_requested) != JNI_SUCCESS) - return JNI_FAILURE; - } - - // num_messages - if ((clientBdData->mask & WMS_MASK_BD_NUM_OF_MSGS) == WMS_MASK_BD_NUM_OF_MSGS) { -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->num_messages = %d\n", clientBdData->num_messages); -#endif - if (setObjectIntField(env, bearerData, "numberOfMessages", (int)clientBdData->num_messages) != JNI_SUCCESS) - return JNI_FAILURE; - } - - // alert_mode - // TODO - - // language - // TODO - - // display_mode - if ((clientBdData->mask & WMS_MASK_BD_DISPLAY_MODE) == WMS_MASK_BD_DISPLAY_MODE) { -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->display_mode = 0x%02x\n", clientBdData->display_mode); -#endif - if (setObjectByteField(env, bearerData, "displayMode", (jbyte)clientBdData->display_mode) != JNI_SUCCESS) - return JNI_FAILURE; - } - - // delivery_status - if ((clientBdData->mask & WMS_MASK_BD_DELIVERY_STATUS) == WMS_MASK_BD_DELIVERY_STATUS) { -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->delivery_status.error_class = %d\n", clientBdData->delivery_status.error_class); -#endif - // delivery_status.error_class - if (setObjectIntField(env, bearerData, "errorClass", (int)clientBdData->delivery_status.error_class) != JNI_SUCCESS) - return JNI_FAILURE; -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->delivery_status.status = %d\n", clientBdData->delivery_status.status); -#endif - // delivery_status.status - if (setObjectIntField(env, bearerData, "messageStatus", (int)clientBdData->delivery_status.status) != JNI_SUCCESS) - return JNI_FAILURE; - } - - // deposit_index - // TODO - - // ip_address - // TODO - - // rsn_no_notify - // TODO - - // other - // TODO - - return JNI_SUCCESS; -} - - -/* native interface */ -JNIEXPORT jint JNICALL -Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserData - (JNIEnv * env, jobject obj, jobject userData) -{ - jclass UserDataClass; - jfieldID field; - jbyteArray arrData = NULL; - jbyte data_buf[RIL_CDMA_SMS_USER_DATA_MAX]; - int length; - jint intData; - jbyte byteData; - jboolean booleanData; - -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsSetUserData()...\n"); -#endif - - // set num_headers to 0 here, increment later - clientBdData->user_data.num_headers = 0; - - // user_data.encoding - if (getObjectIntField(env, userData, "userDataEncoding", &intData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->user_data.encoding = (RIL_CDMA_SMS_UserDataEncoding)(intData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.encoding = %d\n", clientBdData->user_data.encoding); -#endif - - // is91ep_type - // TODO - - // user_data.padding_bits - if (getObjectIntField(env, userData, "paddingBits", &intData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->user_data.padding_bits = (unsigned char)(intData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.padding_bits = %d\n", clientBdData->user_data.padding_bits); -#endif - - // user_data.data - if (getObjectByteArrayField(env, userData, "userData", data_buf, &length) != JNI_SUCCESS ) - return JNI_FAILURE; - for (int i = 0; i < length; i++) { - clientBdData->user_data.data[i] = data_buf[i]; -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.data[%d] = 0x%02x\n", i, clientBdData->user_data.data[i]); -#endif - } - - // user_data.data_len - // TODO - - // number_of_digits - clientBdData->user_data.number_of_digits = (unsigned char)(length); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.number_of_digits = %d\n", clientBdData->user_data.number_of_digits); -#endif - - return JNI_SUCCESS; -} - - -/* native interface */ -JNIEXPORT jint JNICALL -Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserData - (JNIEnv * env, jobject obj, jobject userData) -{ - jclass UserDataClass; - jfieldID field; - jbyte *data_buf; - int length; - -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsGetUserData()...\n"); -#endif - - // user_data.num_headers -// if (setObjectIntField(env, userData, "mNumberOfHeaders", (int)clientBdData->user_data.num_headers) != JNI_SUCCESS) -// return JNI_FAILURE; - - // user_data.encoding -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.encoding = %d\n", clientBdData->user_data.encoding); -#endif - if (setObjectIntField(env, userData, "userDataEncoding", clientBdData->user_data.encoding) != JNI_SUCCESS) - return JNI_FAILURE; - - // is91ep_type - // TODO - - // user_data.data_len -// if (setObjectIntField(env, userData, "mDataLength", (int)clientBdData->user_data.data_len) != JNI_SUCCESS) -// return JNI_FAILURE; - - // user_data.padding_bits -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.padding_bits = %d\n", clientBdData->user_data.padding_bits); -#endif - if (setObjectIntField(env, userData, "paddingBits", (int)clientBdData->user_data.padding_bits) != JNI_SUCCESS) - return JNI_FAILURE; - - // user_data.data -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.data_len = %d\n", clientBdData->user_data.data_len); -#endif - length = clientBdData->user_data.data_len; -#ifdef DBG_LOG_LEVEL_A - for (int i = 0; i < length; i++) { - LOGD("clientBdData->user_data.data[%d] = 0x%02x\n", i, clientBdData->user_data.data[i]); - } -#endif - data_buf = (jbyte*)clientBdData->user_data.data; - if (setObjectByteArrayField(env, userData, "userData", data_buf, length) != JNI_SUCCESS) - return JNI_FAILURE; - - // number_of_digits - // TODO - - return JNI_SUCCESS; -} - - -/* native interface */ -JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserDataHeader - (JNIEnv * env, jobject obj, jint ID, jbyteArray data, jint length, jint index) -{ - jbyte data_buf[length]; - -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsSetUserDataHeader()...\n"); -#endif - - env->GetByteArrayRegion(data, 0, length, data_buf); - - // user_data.headers[index].header_id - clientBdData->user_data.headers[index].header_id = (RIL_CDMA_SMS_UdhId)(ID); - - // user_data.headers[index].u - // TODO: add support for all udh id's - switch(clientBdData->user_data.headers[index].header_id) - { - case RIL_CDMA_SMS_UDH_CONCAT_8: - clientBdData->user_data.headers[index].u.concat_8.msg_ref = data_buf[0]; - clientBdData->user_data.headers[index].u.concat_8.total_sm = data_buf[1]; - clientBdData->user_data.headers[index].u.concat_8.seq_num = data_buf[2]; -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.headers[%d].u.concat_8.msg_ref = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.msg_ref); - LOGD("clientBdData->user_data.headers[%d].u.concat_8.total_sm = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.total_sm); - LOGD("clientBdData->user_data.headers[%d].u.concat_8.seq_num = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.seq_num); -#endif - break; - case RIL_CDMA_SMS_UDH_SPECIAL_SM: - clientBdData->user_data.headers[index].u.special_sm.msg_waiting = (RIL_CDMA_SMS_GWMsgWaiting)( - (data_buf[0] << 23) | (data_buf[1] << 15) | - (data_buf[2] << 7) | data_buf[3]); - clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind = (RIL_CDMA_SMS_GWMsgWaitingKind)( - (data_buf[4] << 23) | (data_buf[5] << 15) | - (data_buf[6] << 7) | data_buf[7]); - clientBdData->user_data.headers[index].u.special_sm.message_count = data_buf[8]; -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting); - LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting_kind = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind); - LOGD("clientBdData->user_data.headers[%d].u.special_sm.message_count = 0x%02x\n", index, clientBdData->user_data.headers[index].u.special_sm.message_count); -#endif - break; - case RIL_CDMA_SMS_UDH_PORT_8: - clientBdData->user_data.headers[index].u.wap_8.dest_port = data_buf[0]; - clientBdData->user_data.headers[index].u.wap_8.orig_port = data_buf[1]; -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.headers[%d].u.wap_8.dest_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.dest_port); - LOGD("clientBdData->user_data.headers[%d].u.wap_8.orig_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.orig_port); -#endif - break; - case RIL_CDMA_SMS_UDH_PORT_16: - clientBdData->user_data.headers[index].u.wap_16.dest_port = (data_buf[0] << 7) | data_buf[1]; // unsigned short - clientBdData->user_data.headers[index].u.wap_16.orig_port = (data_buf[2] << 7) | data_buf[3]; // unsigned short -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.headers[%d].u.wap_16.dest_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.dest_port); - LOGD("clientBdData->user_data.headers[%d].u.wap_16.orig_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.orig_port); -#endif - break; - case RIL_CDMA_SMS_UDH_CONCAT_16: - clientBdData->user_data.headers[index].u.concat_16.msg_ref = (data_buf[0] << 7) | data_buf[1]; // unsigned short - clientBdData->user_data.headers[index].u.concat_16.total_sm = data_buf[2]; - clientBdData->user_data.headers[index].u.concat_16.seq_num = data_buf[3]; -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.headers[%d].u.concat_16.msg_ref = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.msg_ref); - LOGD("clientBdData->user_data.headers[%d].u.concat_16.total_sm = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.total_sm); - LOGD("clientBdData->user_data.headers[%d].u.concat_16.seq_num = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.seq_num); -#endif - break; - default: - break; - } - - // increment num_of_headers - clientBdData->user_data.num_headers++; - - return JNI_SUCCESS; -} - - -/* native interface */ -JNIEXPORT jbyteArray JNICALL -Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserDataHeader - (JNIEnv * env, jobject obj) -{ - jbyteArray arrData = NULL; - jbyte data_buf[sizeof(clientBdData->user_data.headers)]; - int length = 0; - -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsGetUserDataHeader()...\n"); -#endif - -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.num_headers = %d, size = %d\n", clientBdData->user_data.num_headers, sizeof(clientBdData->user_data.headers)); -#endif - - for (int index = 0; index < clientBdData->user_data.num_headers; index++) { - // user_data.headers[index].header_id - data_buf[length++] = (jbyte)clientBdData->user_data.headers[index].header_id; -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.headers[%d].header_id = %d", index, clientBdData->user_data.headers[index].header_id); -#endif - - // user_data.headers[index].u - // TODO: add support for all udh id's - switch(clientBdData->user_data.headers[index].header_id) - { - case RIL_CDMA_SMS_UDH_CONCAT_8: -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.headers[%d].u.concat_8.msg_ref = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.msg_ref); - LOGD("clientBdData->user_data.headers[%d].u.concat_8.total_sm = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.total_sm); - LOGD("clientBdData->user_data.headers[%d].u.concat_8.seq_num = 0x%02x\n", index, clientBdData->user_data.headers[index].u.concat_8.seq_num); -#endif - data_buf[length++] = 3; - data_buf[length++] = clientBdData->user_data.headers[index].u.concat_8.msg_ref; - data_buf[length++] = clientBdData->user_data.headers[index].u.concat_8.total_sm; - data_buf[length++] = clientBdData->user_data.headers[index].u.concat_8.seq_num; - break; - case RIL_CDMA_SMS_UDH_SPECIAL_SM: -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting); - LOGD("clientBdData->user_data.headers[%d].u.special_sm.msg_waiting_kind = 0x%04x\n", index, clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind); - LOGD("clientBdData->user_data.headers[%d].u.special_sm.message_count = 0x%02x\n", index, clientBdData->user_data.headers[index].u.special_sm.message_count); -#endif - data_buf[length++] = 9; - data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0xFF000000) >> 23; // int - data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0x00FF0000) >> 15; - data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0x0000FF00) >> 7; - data_buf[length++] = clientBdData->user_data.headers[index].u.special_sm.msg_waiting & 0x000000FF; - data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0xFF000000) >> 23; // int - data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0x00FF0000) >> 15; - data_buf[length++] = (clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0x0000FF00) >> 7; - data_buf[length++] = clientBdData->user_data.headers[index].u.special_sm.msg_waiting_kind & 0x000000FF; - data_buf[length++] = clientBdData->user_data.headers[index].u.special_sm.message_count; - break; - case RIL_CDMA_SMS_UDH_PORT_8: -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.headers[%d].u.wap_8.dest_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.dest_port); - LOGD("clientBdData->user_data.headers[%d].u.wap_8.orig_port = 0x%02x\n", index, clientBdData->user_data.headers[index].u.wap_8.orig_port); -#endif - data_buf[length++] = 2; - data_buf[length++] = clientBdData->user_data.headers[index].u.wap_8.dest_port; - data_buf[length++] = clientBdData->user_data.headers[index].u.wap_8.orig_port; - break; - case RIL_CDMA_SMS_UDH_PORT_16: -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.headers[%d].u.wap_16.dest_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.dest_port); - LOGD("clientBdData->user_data.headers[%d].u.wap_16.orig_port = 0x%04x\n", index, clientBdData->user_data.headers[index].u.wap_16.orig_port); -#endif - data_buf[length++] = 4; - data_buf[length++] = (clientBdData->user_data.headers[index].u.wap_16.dest_port & 0xFF00) >> 7; // unsigned short - data_buf[length++] = clientBdData->user_data.headers[index].u.wap_16.dest_port & 0x00FF; - data_buf[length++] = (clientBdData->user_data.headers[index].u.wap_16.orig_port & 0xFF00) >> 7; // unsigned short - data_buf[length++] = clientBdData->user_data.headers[index].u.wap_16.orig_port & 0x00FF; - break; - case RIL_CDMA_SMS_UDH_CONCAT_16: -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->user_data.headers[%d].u.concat_16.msg_ref = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.msg_ref); - LOGD("clientBdData->user_data.headers[%d].u.concat_16.total_sm = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.total_sm); - LOGD("clientBdData->user_data.headers[%d].u.concat_16.seq_num = 0x%04x\n", index, clientBdData->user_data.headers[index].u.concat_16.seq_num); -#endif - data_buf[length++] = 4; - data_buf[length++] = (clientBdData->user_data.headers[index].u.concat_16.msg_ref & 0xFF00) >> 7; // unsigned short - data_buf[length++] = clientBdData->user_data.headers[index].u.concat_16.msg_ref & 0x00FF; - data_buf[length++] = clientBdData->user_data.headers[index].u.concat_16.total_sm; - data_buf[length++] = clientBdData->user_data.headers[index].u.concat_16.seq_num; - break; - default: - break; - } - } - - if (length != 0) { - arrData = env->NewByteArray((jsize)length); - env->SetByteArrayRegion(arrData, 0, length, data_buf); - } - - return arrData; -} - - -/* native interface */ -JNIEXPORT jint JNICALL -Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetSmsAddress - (JNIEnv * env, jobject obj, jobject smsAddress) -{ - jclass SmsAddressClass; - jfieldID field; - jbyteArray arrData = NULL; - jbyte byte_buf[RIL_CDMA_SMS_ADDRESS_MAX]; - int length; - jint intData; - jbyte byteData; - jboolean booleanData; - -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsSetSmsAddress()...\n"); -#endif - - // callback.digit_mode - if (getObjectByteField(env, smsAddress, "digitMode", &byteData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->callback.digit_mode = (RIL_CDMA_SMS_DigitMode)(byteData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->callback.digit_mode = 0x%02x\n", clientBdData->callback.digit_mode); -#endif - - // callback.number_mode - if (getObjectByteField(env, smsAddress, "numberMode", &byteData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->callback.number_mode = (RIL_CDMA_SMS_NumberMode)(byteData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->callback.number_mode = 0x%02x\n", clientBdData->callback.number_mode); -#endif - - // callback.number_type - if (getObjectIntField(env, smsAddress, "ton", &intData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->callback.number_type = (RIL_CDMA_SMS_NumberType)(intData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->callback.number_type = %d\n", clientBdData->callback.number_type); -#endif - - // callback.number_plan - if (getObjectByteField(env, smsAddress, "numberPlan", &byteData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->callback.number_plan = (RIL_CDMA_SMS_NumberPlan)(byteData); -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->callback.number_plan = 0x%02x\n", clientBdData->callback.number_plan); -#endif - - // callback.number_of_digits - if (getObjectByteField(env, smsAddress, "numberOfDigits", &byteData) != JNI_SUCCESS) - return JNI_FAILURE; - clientBdData->callback.number_of_digits = byteData; -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->callback.number_of_digits = %d\n",clientBdData->callback.number_of_digits); -#endif - - // callback.digits - if (getObjectByteArrayField(env, smsAddress, "origBytes", byte_buf, &length) != JNI_SUCCESS) - return JNI_FAILURE; - for (int i = 0; i < clientBdData->callback.number_of_digits; i++) { - clientBdData->callback.digits[i] = byte_buf[i]; -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->callback.digits[%d] = 0x%02x\n", i, clientBdData->callback.digits[i]); -#endif - } - - return JNI_SUCCESS; -} - - -/* native interface */ -JNIEXPORT jint JNICALL -Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetSmsAddress - (JNIEnv * env, jobject obj, jobject smsAddress) -{ - jclass SmsAddressClass; - jfieldID field; - jbyteArray arrData = NULL; - jbyte *byte_buf; - int length; - -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsGetSmsAddress()...\n"); -#endif - - // callback.digit_mode -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->callback.digit_mode = 0x%02x\n", clientBdData->callback.digit_mode); -#endif - if (setObjectByteField(env, smsAddress, "digitMode", (jbyte)clientBdData->callback.digit_mode) != JNI_SUCCESS) - return JNI_FAILURE; - - // callback.number_mode -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->callback.number_mode = 0x%02x\n", clientBdData->callback.number_mode); -#endif - if (setObjectByteField(env, smsAddress, "numberMode", (jbyte)clientBdData->callback.number_mode) != JNI_SUCCESS) - return JNI_FAILURE; - - // callback.number_type -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->callback.number_type = %d\n", clientBdData->callback.number_type); -#endif - if (setObjectIntField(env, smsAddress, "ton", (jint)clientBdData->callback.number_type) != JNI_SUCCESS) - return JNI_FAILURE; - - // callback.number_plan -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->callback.number_plan = 0x%02x\n", clientBdData->callback.number_plan); -#endif - if (setObjectByteField(env, smsAddress, "numberPlan", (jbyte)clientBdData->callback.number_plan) != JNI_SUCCESS) - return JNI_FAILURE; - - // callback.number_of_digits -#ifdef DBG_LOG_LEVEL_A - LOGD("clientBdData->callback.number_of_digits = %d\n", clientBdData->callback.number_of_digits); -#endif - if (setObjectByteField(env, smsAddress, "numberOfDigits", (jbyte)clientBdData->callback.number_of_digits) != JNI_SUCCESS) - return JNI_FAILURE; - - // callback.digits - byte_buf = (jbyte*)clientBdData->callback.digits; - length = clientBdData->callback.number_of_digits; -#ifdef DBG_LOG_LEVEL_A - for (int i = 0; i < length; i++) { - LOGD("clientBdData->callback.digits[%d] = 0x%02x\n", i, clientBdData->callback.digits[i]); - } -#endif - - if (setObjectByteArrayField(env, smsAddress, "origBytes", byte_buf, length) != JNI_SUCCESS) - return JNI_FAILURE; - - return JNI_SUCCESS; -} - - -/* native interface */ -JNIEXPORT jbyteArray JNICALL -Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsEncodeSms - (JNIEnv * env, jobject obj) -{ - RIL_CDMA_Encoded_SMS *encoded_sms = (RIL_CDMA_Encoded_SMS *)malloc(sizeof(RIL_CDMA_Encoded_SMS)); - jbyte* data_buf; - jint result = JNI_SUCCESS; - jbyteArray encodedSMS; - -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsEncodeSms(): entry\n"); -#endif - - if (NULL == encoded_sms) { - jniThrowException(env, "java/lang/NullPointerException", "encoded_sms is null"); - return NULL; - } - memset(encoded_sms, 0, sizeof(RIL_CDMA_Encoded_SMS)); - - // call CDMA SMS encode function - if(wmsts_ril_cdma_encode_sms(clientBdData, encoded_sms) != RIL_E_SUCCESS) { - jniThrowException(env, "java/lang/Exception", "CDMA SMS Encoding failed"); - return NULL; - } - -#ifdef DBG_LOG_LEVEL_A - LOGD(" EncodeSMS: length = %i\n", encoded_sms->length); -#endif - encodedSMS = env->NewByteArray((jsize)encoded_sms->length); - env->SetByteArrayRegion(encodedSMS, 0, encoded_sms->length, (jbyte*)encoded_sms->data); - free(encoded_sms); - - return encodedSMS; -} - - -/* native interface */ -JNIEXPORT jint JNICALL -Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDecodeSms - (JNIEnv * env, jobject obj, jbyteArray encodedSMS) -{ - RIL_CDMA_Encoded_SMS *encoded_sms = (RIL_CDMA_Encoded_SMS *)malloc(sizeof(RIL_CDMA_Encoded_SMS)); - jbyte* data_buf; - jint result = JNI_SUCCESS; - jsize length; - -#ifdef DBG_LOG_LEVEL_B - LOGD("nativeCdmaSmsDecodeSms(): entry\n"); -#endif - - if (NULL == encoded_sms) { - jniThrowException(env, "java/lang/NullPointerException", "encoded_sms is null"); - return JNI_FAILURE; - } - memset(encoded_sms, 0, sizeof(RIL_CDMA_Encoded_SMS)); - - length = env->GetArrayLength(encodedSMS); - if (length < 0 || length > 255) { - jniThrowException(env, "java/lang/ArrayIndexOutOfBounds", "wrong encoded SMS data length"); - return JNI_FAILURE; - } - encoded_sms->length = length; -#ifdef DBG_LOG_LEVEL_A - LOGD(" DecodeSMS: arrayLength = %d\n", encoded_sms->length); -#endif - data_buf = env->GetByteArrayElements(encodedSMS, NULL); - encoded_sms->data = (unsigned char*)data_buf; - env->ReleaseByteArrayElements(encodedSMS, data_buf, 0); - - // call CDMA SMS decode function - if(wmsts_ril_cdma_decode_sms(encoded_sms, clientBdData) != RIL_E_SUCCESS) { - jniThrowException(env, "java/lang/Exception", "CDMA SMS Decoding failed"); - result = JNI_FAILURE; - } - - free(encoded_sms); - - return result; -} - - -// --------------------------------------------------------------------------- - -static const char *classPathName = "com/android/internal/telephony/cdma/sms/SmsDataCoding"; - -static JNINativeMethod methods[] = { - /* name, signature, funcPtr */ - {"nativeCdmaSmsConstructClientBD", "()I", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsConstructClientBD }, - {"nativeCdmaSmsDestructClientBD", "()I", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDestructClientBD }, - {"nativeCdmaSmsSetBearerDataPrimitives", "(Lcom/android/internal/telephony/cdma/sms/BearerData;)I", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetBearerDataPrimitives }, - {"nativeCdmaSmsGetBearerDataPrimitives", "(Lcom/android/internal/telephony/cdma/sms/BearerData;)I", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetBearerDataPrimitives }, - {"nativeCdmaSmsSetUserData", "(Lcom/android/internal/telephony/cdma/sms/UserData;)I", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserData }, - {"nativeCdmaSmsGetUserData", "(Lcom/android/internal/telephony/cdma/sms/UserData;)I", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserData }, - {"nativeCdmaSmsSetUserDataHeader", "(I[BII)I", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserDataHeader }, - {"nativeCdmaSmsGetUserDataHeader", "()[B", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserDataHeader }, - {"nativeCdmaSmsSetSmsAddress", "(Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetSmsAddress }, - {"nativeCdmaSmsGetSmsAddress", "(Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetSmsAddress }, - {"nativeCdmaSmsEncodeSms", "()[B", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsEncodeSms }, - {"nativeCdmaSmsDecodeSms", "([B)I", - (void*)Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDecodeSms }, -}; - -int register_android_cdma_sms_methods(JNIEnv *_env) -{ - return android::AndroidRuntime::registerNativeMethods( - _env, classPathName, methods, NELEM(methods)); -} - -// --------------------------------------------------------------------------- - -jint JNI_OnLoad(JavaVM* vm, void* reserved) -{ - JNIEnv* env = NULL; - jint result = -1; - - if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { - LOGE("ERROR: GetEnv failed\n"); - goto bail; - } - assert(env != NULL); - - if (register_android_cdma_sms_methods(env) < 0) { - LOGE("ERROR: CDMA SMS native registration failed\n"); - goto bail; - } - - /* success -- return valid version number */ - result = JNI_VERSION_1_4; - -bail: - return result; -} diff --git a/telephony/jni/cdmasms/cdma_sms_jni.h b/telephony/jni/cdmasms/cdma_sms_jni.h deleted file mode 100644 index 253c006cd9a5..000000000000 --- a/telephony/jni/cdmasms/cdma_sms_jni.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2008 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. - */ - -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include <jni.h> -/* Header for class com_android_internal_telephony_cdma_sms_SmsDataCoding */ - -#ifndef _Included_com_android_internal_telephony_cdma_sms_SmsDataCoding -#define _Included_com_android_internal_telephony_cdma_sms_SmsDataCoding -#ifdef __cplusplus -extern "C" { -#endif -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NULL -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NULL 0L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MSG_ID -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MSG_ID 1L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_USER_DATA -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_USER_DATA 2L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MC_TIME -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_MC_TIME 8L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_NUM_OF_MSGS 2048L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_CALLBACK -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_CALLBACK 16384L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_CDMA_SMS_WMS_MASK_BD_DISPLAY_MODE 32768L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_SUCCESS -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_SUCCESS 0L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FAILURE -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FAILURE 1L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_DATA_LEN_OUT_OF_RANGE -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_DATA_LEN_OUT_OF_RANGE 2L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_CLASS_UNKNOWN -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_CLASS_UNKNOWN 3L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FIELD_ID_UNKNOWN -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FIELD_ID_UNKNOWN 4L -#undef com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_OUT_OF_MEMORY -#define com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_OUT_OF_MEMORY 5L -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsConstructClientBD - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsConstructClientBD - (JNIEnv *, jobject); - -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsDestructClientBD - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDestructClientBD - (JNIEnv *, jobject); - -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsSetBearerDataPrimitives - * Signature: (Lcom/android/internal/telephony/cdma/sms/BearerData;)I - */ -JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetBearerDataPrimitives - (JNIEnv *, jobject, jobject); - -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsGetBearerDataPrimitives - * Signature: (Lcom/android/internal/telephony/cdma/sms/BearerData;)I - */ -JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetBearerDataPrimitives - (JNIEnv *, jobject, jobject); - -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsSetUserData - * Signature: (Lcom/android/internal/telephony/cdma/sms/UserData;)I - */ -JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserData - (JNIEnv *, jobject, jobject); - -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsGetUserData - * Signature: (Lcom/android/internal/telephony/cdma/sms/UserData;)I - */ -JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserData - (JNIEnv *, jobject, jobject); - -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsSetUserDataHeader - * Signature: (I[BII)I - */ -JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetUserDataHeader - (JNIEnv *, jobject, jint, jbyteArray, jint, jint); - -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsGetUserDataHeader - * Signature: ()[B - */ -JNIEXPORT jbyteArray JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetUserDataHeader - (JNIEnv *, jobject); - -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsSetSmsAddress - * Signature: (Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I - */ -JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsSetSmsAddress - (JNIEnv *, jobject, jobject); - -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsGetSmsAddress - * Signature: (Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;)I - */ -JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsGetSmsAddress - (JNIEnv *, jobject, jobject); - -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsEncodeSms - * Signature: ()[B - */ -JNIEXPORT jbyteArray JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsEncodeSms - (JNIEnv *, jobject); - -/* - * Class: com_android_internal_telephony_cdma_sms_SmsDataCoding - * Method: nativeCdmaSmsDecodeSms - * Signature: ([B)I - */ -JNIEXPORT jint JNICALL Java_com_android_internal_telephony_cdma_sms_SmsDataCoding_nativeCdmaSmsDecodeSms - (JNIEnv *, jobject, jbyteArray); - -/** - * CDMA SMS return value defines - */ -#define JNI_SUCCESS \ -com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_SUCCESS /**< Successful operation */ -#define JNI_FAILURE \ -com_android_internal_telephony_cdma_sms_SmsDataCoding_JNI_CDMA_SMS_FAILURE /**< General failure */ - -#ifdef __cplusplus -} -#endif -#endif diff --git a/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java b/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java new file mode 100644 index 000000000000..2c9075c0265c --- /dev/null +++ b/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2006 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.unit_tests; + +import com.android.internal.util.BitwiseInputStream; +import com.android.internal.util.BitwiseOutputStream; +import com.android.internal.util.HexDump; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +public class BitwiseStreamsTest extends AndroidTestCase { + private final static String LOG_TAG = "BitwiseStreamsTest"; + + @SmallTest + public void testOne() throws Exception { + int offset = 3; + byte[] inBuf = HexDump.hexStringToByteArray("FFDD"); + BitwiseOutputStream outStream = new BitwiseOutputStream(30); + outStream.skip(offset); + for (int i = 0; i < inBuf.length; i++) outStream.write(8, inBuf[i]); + byte[] outBuf = outStream.toByteArray(); + BitwiseInputStream inStream = new BitwiseInputStream(outBuf); + byte[] inBufDup = new byte[inBuf.length]; + inStream.skip(offset); + for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8); + assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); + } + + @SmallTest + public void testTwo() throws Exception { + int offset = 3; + byte[] inBuf = HexDump.hexStringToByteArray("11d4f29c0e9ad3c36e72584e064d9b53"); + BitwiseOutputStream outStream = new BitwiseOutputStream(30); + outStream.skip(offset); + for (int i = 0; i < inBuf.length; i++) outStream.write(8, inBuf[i]); + BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray()); + inStream.skip(offset); + byte[] inBufDup = new byte[inBuf.length]; + for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8); + assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); + } + + @SmallTest + public void testThree() throws Exception { + int offset = 4; + byte[] inBuf = HexDump.hexStringToByteArray("00031040900112488ea794e0"); + BitwiseOutputStream outStream = new BitwiseOutputStream(30); + outStream.skip(offset); + for (int i = 0; i < inBuf.length; i++) outStream.write(8, inBuf[i]); + BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray()); + inStream.skip(offset); + byte[] inBufDup = new byte[inBuf.length]; + for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8); + assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); + } + + @SmallTest + public void testFour() throws Exception { + int offset = 7; + byte[] inBuf = HexDump.hexStringToByteArray("00031040900112488ea794e0"); + BitwiseOutputStream outStream = new BitwiseOutputStream(30); + outStream.skip(offset); + for (int i = 0; i < inBuf.length; i++) { + outStream.write(5, inBuf[i] >>> 3); + outStream.write(3, inBuf[i] & 0x07); + } + BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray()); + inStream.skip(offset); + byte[] inBufDup = new byte[inBuf.length]; + for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8); + assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); + } +} diff --git a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java new file mode 100644 index 000000000000..723512c3a765 --- /dev/null +++ b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2006 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.unit_tests; + +import com.android.internal.telephony.GsmAlphabet; +import com.android.internal.telephony.SmsHeader; +import com.android.internal.telephony.cdma.sms.BearerData; +import com.android.internal.telephony.cdma.sms.UserData; +import com.android.internal.telephony.cdma.sms.CdmaSmsAddress; +import com.android.internal.util.BitwiseInputStream; +import com.android.internal.util.BitwiseOutputStream; +import com.android.internal.util.HexDump; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +import java.util.Iterator; + +import android.util.Log; + +public class CdmaSmsTest extends AndroidTestCase { + private final static String LOG_TAG = "Cdma_Sms_Test"; + + private static UserData makeUserData(String msg) { + UserData userData = new UserData(); + byte[] payload; + try { + payload = GsmAlphabet.stringToGsm7BitPacked(msg); + userData.payload = new byte[payload.length - 1]; + for (int i = 0; i < userData.payload.length; i++) userData.payload[i] = payload[i + 1]; + userData.numFields = payload[0]; + userData.paddingBits = (userData.payload.length * 8) - (userData.numFields * 7); + userData.paddingBits = 0; // XXX this is better, wtf? + userData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET; + } catch (com.android.internal.telephony.EncodeException ex) { + assertEquals(1, 0); + } + return userData; + } + + @SmallTest + public void testStandardSms() throws Exception { + String pdu = "00031040900112488ea794e074d69e1b7392c270326cde9e98"; + BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu)); + assertEquals("Test standard SMS", bearerData.userData.payloadStr); + } + + @SmallTest + public void testStandardSmsFeedback() throws Exception { + BearerData bearerData = new BearerData(); + bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; + bearerData.messageId = 0; + bearerData.hasUserDataHeader = false; + String payloadStr = "Test standard SMS"; + bearerData.userData = makeUserData(payloadStr); + byte []encodedSms = BearerData.encode(bearerData); + BearerData revBearerData = BearerData.decode(encodedSms); + assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType); + assertEquals(0, revBearerData.messageId); + assertEquals(false, revBearerData.hasUserDataHeader); + assertEquals(UserData.ENCODING_GSM_7BIT_ALPHABET, revBearerData.userData.msgEncoding); + assertEquals(payloadStr.length(), revBearerData.userData.numFields); + assertEquals(payloadStr, revBearerData.userData.payloadStr); + } + + @SmallTest + public void testAltUserDataFeedback() throws Exception { + try { + BearerData bearerData = new BearerData(); + bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; + bearerData.messageId = 0; + bearerData.hasUserDataHeader = false; + UserData userData = new UserData(); + String str1 = "test ascii user data encoding"; + userData.payload = str1.getBytes("US-ASCII"); + userData.numFields = str1.length(); + userData.paddingBits = 0; + userData.msgEncoding = UserData.ENCODING_7BIT_ASCII; + bearerData.userData = userData; + byte []encodedSms = BearerData.encode(bearerData); + BearerData revBearerData = BearerData.decode(encodedSms); + assertEquals(str1, revBearerData.userData.payloadStr); + String str2 = "\u0160u\u1E5B\u0301r\u1ECFg\uD835\uDC1At\u00E9\u4E002\u3042"; + userData.payload = str2.getBytes("UTF-16"); + userData.numFields = str2.length() + 1; + userData.msgEncoding = UserData.ENCODING_UNICODE_16; + encodedSms = BearerData.encode(bearerData); + revBearerData = BearerData.decode(encodedSms); + assertEquals(str2, revBearerData.userData.payloadStr); + } catch (java.io.UnsupportedEncodingException ex) { + throw new RuntimeException("user data encoding error"); + } + } + + @SmallTest + public void testReplyOption() throws Exception { + String pdu1 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87450080a0180"; + BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); + assertEquals("Test Acknowledgement 1", bd1.userData.payloadStr); + assertEquals(true, bd1.userAckReq); + assertEquals(false, bd1.deliveryAckReq); + assertEquals(false, bd1.readAckReq); + assertEquals(false, bd1.reportReq); + String pdu2 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87490080a0140"; + BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2)); + assertEquals("Test Acknowledgement 2", bd2.userData.payloadStr); + assertEquals(false, bd2.userAckReq); + assertEquals(true, bd2.deliveryAckReq); + assertEquals(false, bd2.readAckReq); + assertEquals(false, bd2.reportReq); + String pdu3 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d874d0080a0120"; + BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3)); + assertEquals("Test Acknowledgement 3", bd3.userData.payloadStr); + assertEquals(false, bd3.userAckReq); + assertEquals(false, bd3.deliveryAckReq); + assertEquals(true, bd3.readAckReq); + assertEquals(false, bd3.reportReq); + String pdu4 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87510080a0110"; + BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4)); + assertEquals("Test Acknowledgement 4", bd4.userData.payloadStr); + assertEquals(false, bd4.userAckReq); + assertEquals(false, bd4.deliveryAckReq); + assertEquals(false, bd4.readAckReq); + assertEquals(true, bd4.reportReq); + } + + @SmallTest + public void testReplyOptionFeedback() throws Exception { + BearerData bearerData = new BearerData(); + bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; + bearerData.messageId = 0; + bearerData.hasUserDataHeader = false; + bearerData.userData = makeUserData("test reply option"); + bearerData.userAckReq = true; + byte []encodedSms = BearerData.encode(bearerData); + BearerData revBearerData = BearerData.decode(encodedSms); + assertEquals(true, revBearerData.userAckReq); + assertEquals(false, revBearerData.deliveryAckReq); + assertEquals(false, revBearerData.readAckReq); + assertEquals(false, revBearerData.reportReq); + bearerData.userAckReq = false; + bearerData.deliveryAckReq = true; + encodedSms = BearerData.encode(bearerData); + revBearerData = BearerData.decode(encodedSms); + assertEquals(false, revBearerData.userAckReq); + assertEquals(true, revBearerData.deliveryAckReq); + assertEquals(false, revBearerData.readAckReq); + assertEquals(false, revBearerData.reportReq); + bearerData.deliveryAckReq = false; + bearerData.readAckReq = true; + encodedSms = BearerData.encode(bearerData); + revBearerData = BearerData.decode(encodedSms); + assertEquals(false, revBearerData.userAckReq); + assertEquals(false, revBearerData.deliveryAckReq); + assertEquals(true, revBearerData.readAckReq); + assertEquals(false, revBearerData.reportReq); + bearerData.readAckReq = false; + bearerData.reportReq = true; + encodedSms = BearerData.encode(bearerData); + revBearerData = BearerData.decode(encodedSms); + assertEquals(false, revBearerData.userAckReq); + assertEquals(false, revBearerData.deliveryAckReq); + assertEquals(false, revBearerData.readAckReq); + assertEquals(true, revBearerData.reportReq); + } + + @SmallTest + public void testNumberOfMessages() throws Exception { + String pdu1 = "000310409001124896a794e07595f69f199540ea759a0dc8e00b0163"; + BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); + assertEquals("Test Voice mail 99", bd1.userData.payloadStr); + assertEquals(99, bd1.numberOfMessages); + String pdu2 = "00031040900113489ea794e07595f69f199540ea759a0988c0600b0164"; + BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2)); + assertEquals("Test Voice mail 100", bd2.userData.payloadStr); + assertEquals(100, bd2.numberOfMessages); + } + + @SmallTest + public void testNumberOfMessagesFeedback() throws Exception { + BearerData bearerData = new BearerData(); + bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; + bearerData.messageId = 0; + bearerData.hasUserDataHeader = false; + bearerData.userData = makeUserData("test message count"); + bearerData.numberOfMessages = 27; + byte []encodedSms = BearerData.encode(bearerData); + BearerData revBearerData = BearerData.decode(encodedSms); + assertEquals(bearerData.numberOfMessages, revBearerData.numberOfMessages); + } + + @SmallTest + public void testCallbackNum() throws Exception { + String pdu1 = "00031040900112488ea794e070d436cb638bc5e035ce2f97900e06910431323334"; + BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); + assertEquals("Test Callback nbr", bd1.userData.payloadStr); + assertEquals(CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR, bd1.callbackNumber.digitMode); + assertEquals(CdmaSmsAddress.TON_INTERNATIONAL_OR_IP, bd1.callbackNumber.ton); + assertEquals(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK, bd1.callbackNumber.numberMode); + assertEquals(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY, bd1.callbackNumber.numberPlan); + assertEquals("1234", bd1.callbackNumber.address); + } + + @SmallTest + public void testCallbackNumFeedback() throws Exception { + BearerData bearerData = new BearerData(); + bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; + bearerData.messageId = 0; + bearerData.hasUserDataHeader = false; + bearerData.userData = makeUserData("test callback number"); + CdmaSmsAddress addr = new CdmaSmsAddress(); + addr.digitMode = CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR; + addr.ton = CdmaSmsAddress.TON_NATIONAL_OR_EMAIL; + addr.numberMode = CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK; + addr.numberPlan = CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN; + addr.address = "8005551212"; + addr.numberOfDigits = (byte)addr.address.length(); + bearerData.callbackNumber = addr; + byte []encodedSms = BearerData.encode(bearerData); + BearerData revBearerData = BearerData.decode(encodedSms); + CdmaSmsAddress revAddr = revBearerData.callbackNumber; + assertEquals(addr.digitMode, revAddr.digitMode); + assertEquals(addr.ton, revAddr.ton); + assertEquals(addr.numberMode, revAddr.numberMode); + assertEquals(addr.numberPlan, revAddr.numberPlan); + assertEquals(addr.numberOfDigits, revAddr.numberOfDigits); + assertEquals(addr.address, revAddr.address); + addr.address = "8*55#1012"; + addr.numberOfDigits = (byte)addr.address.length(); + addr.digitMode = CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF; + encodedSms = BearerData.encode(bearerData); + revBearerData = BearerData.decode(encodedSms); + revAddr = revBearerData.callbackNumber; + assertEquals(addr.digitMode, revAddr.digitMode); + assertEquals(addr.numberOfDigits, revAddr.numberOfDigits); + assertEquals(addr.address, revAddr.address); + } + + @SmallTest + public void testMsgCenterTimeStampFeedback() throws Exception { + BearerData bearerData = new BearerData(); + bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; + bearerData.messageId = 0; + bearerData.hasUserDataHeader = false; + bearerData.userData = makeUserData("test message center timestamp"); + bearerData.timeStamp = HexDump.hexStringToByteArray("112233445566"); + byte []encodedSms = BearerData.encode(bearerData); + BearerData revBearerData = BearerData.decode(encodedSms); + assertEquals(HexDump.toHexString(bearerData.timeStamp), + HexDump.toHexString(revBearerData.timeStamp)); + } + + // XXX test messageId + + // String pdu1 = "0003104090010d4866a794e07055965b91d040300c0100"; sid 12 + // String pdu1 = "0003104090011748bea794e0731436ef3bd7c2e0352eef27a1c263fe58080d0101"; sid 13 + // Log.d(LOG_TAG, "revBearerData -- " + revBearerData); + +} |