am 7755cdd6: Remove unused/debugging code from MP4 file writer
Merge commit '7755cdd69690ccbb42c6fd47b3e9c4594d4ade82' into gingerbread-plus-aosp
* commit '7755cdd69690ccbb42c6fd47b3e9c4594d4ade82':
Remove unused/debugging code from MP4 file writer
diff --git a/api/current.xml b/api/current.xml
index f7a5954..dbad5c1 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -22831,6 +22831,18 @@
<parameter name="context" type="android.content.Context">
</parameter>
</constructor>
+<constructor name="AlertDialog.Builder"
+ type="android.app.AlertDialog.Builder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="theme" type="int">
+</parameter>
+</constructor>
<method name="create"
return="android.app.AlertDialog"
abstract="false"
@@ -56487,6 +56499,42 @@
<parameter name="table" type="java.lang.String">
</parameter>
</method>
+<method name="queryNumEntries"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="db" type="android.database.sqlite.SQLiteDatabase">
+</parameter>
+<parameter name="table" type="java.lang.String">
+</parameter>
+<parameter name="selection" type="java.lang.String">
+</parameter>
+</method>
+<method name="queryNumEntries"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="db" type="android.database.sqlite.SQLiteDatabase">
+</parameter>
+<parameter name="table" type="java.lang.String">
+</parameter>
+<parameter name="selection" type="java.lang.String">
+</parameter>
+<parameter name="selectionArgs" type="java.lang.String[]">
+</parameter>
+</method>
<method name="readExceptionFromParcel"
return="void"
abstract="false"
@@ -208755,6 +208803,32 @@
<parameter name="object" type="T">
</parameter>
</method>
+<method name="addAll"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="collection" type="java.util.Collection<? extends T>">
+</parameter>
+</method>
+<method name="addAll"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="items" type="T...">
+</parameter>
+</method>
<method name="clear"
return="void"
abstract="false"
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 7a7f8ed..9fe1fb8 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -49,6 +49,9 @@
#include "BootAnimation.h"
+#define USER_BOOTANIMATION_FILE "/data/local/bootanimation.zip"
+#define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip"
+
namespace android {
// ---------------------------------------------------------------------------
@@ -244,12 +247,12 @@
mFlingerSurfaceControl = control;
mFlingerSurface = s;
- mAndroidAnimation = false;
- status_t err = mZip.open("/data/local/bootanimation.zip");
- if (err != NO_ERROR) {
- err = mZip.open("/system/media/bootanimation.zip");
- if (err != NO_ERROR) {
- mAndroidAnimation = true;
+ mAndroidAnimation = true;
+ if ((access(USER_BOOTANIMATION_FILE, R_OK) == 0) ||
+ (access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0)) {
+ if ((mZip.open(USER_BOOTANIMATION_FILE) != NO_ERROR) ||
+ (mZip.open(SYSTEM_BOOTANIMATION_FILE) != NO_ERROR)) {
+ mAndroidAnimation = false;
}
}
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 2714de5..61a8fc3 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -265,12 +265,22 @@
public static class Builder {
private final AlertController.AlertParams P;
+ private int mTheme;
/**
* Constructor using a context for this builder and the {@link AlertDialog} it creates.
*/
public Builder(Context context) {
+ this(context, com.android.internal.R.style.Theme_Dialog_Alert);
+ }
+
+ /**
+ * Constructor using a context and theme for this builder and
+ * the {@link AlertDialog} it creates.
+ */
+ public Builder(Context context, int theme) {
P = new AlertController.AlertParams(context);
+ mTheme = theme;
}
/**
@@ -783,7 +793,7 @@
* to do and want this to be created and displayed.
*/
public AlertDialog create() {
- final AlertDialog dialog = new AlertDialog(P.mContext);
+ final AlertDialog dialog = new AlertDialog(P.mContext, mTheme);
P.apply(dialog.mAlert);
dialog.setCancelable(P.mCancelable);
dialog.setOnCancelListener(P.mOnCancelListener);
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 8f940d5..2382596 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -188,7 +188,7 @@
/**
* Return activity in receiverPackage that handles ACTION_APP_ERROR.
*
- * @param pm PackageManager isntance
+ * @param pm PackageManager instance
* @param errorPackage package which caused the error
* @param receiverPackage candidate package to receive the error
* @return activity component within receiverPackage which handles
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 879670e..7513736 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -53,7 +53,6 @@
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.content.pm.PackageParser.Package;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
@@ -86,11 +85,9 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.StatFs;
import android.os.Vibrator;
import android.os.FileUtils.FileStatus;
import android.os.storage.StorageManager;
-import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.ClipboardManager;
import android.util.AndroidRuntimeException;
@@ -264,18 +261,18 @@
public Looper getMainLooper() {
return mMainThread.getLooper();
}
-
+
@Override
public Context getApplicationContext() {
return (mPackageInfo != null) ?
mPackageInfo.getApplication() : mMainThread.getApplication();
}
-
+
@Override
public void setTheme(int resid) {
mThemeResource = resid;
}
-
+
@Override
public Resources.Theme getTheme() {
if (mTheme == null) {
@@ -325,7 +322,7 @@
}
throw new RuntimeException("Not supported in system context");
}
-
+
private static File makeBackupFile(File prefsFile) {
return new File(prefsFile.getPath() + ".bak");
}
@@ -345,7 +342,6 @@
}
}
File f = getSharedPrefsFile(name);
-
FileInputStream str = null;
File backup = makeBackupFile(f);
if (backup.exists()) {
@@ -441,7 +437,7 @@
}
if (!mFilesDir.exists()) {
if(!mFilesDir.mkdirs()) {
- Log.w(TAG, "Unable to create files directory");
+ Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
return null;
}
FileUtils.setPermissions(
@@ -452,7 +448,7 @@
return mFilesDir;
}
}
-
+
@Override
public File getExternalFilesDir(String type) {
synchronized (mSync) {
@@ -484,7 +480,7 @@
return dir;
}
}
-
+
@Override
public File getCacheDir() {
synchronized (mSync) {
@@ -504,7 +500,7 @@
}
return mCacheDir;
}
-
+
@Override
public File getExternalCacheDir() {
synchronized (mSync) {
@@ -526,7 +522,7 @@
return mExternalCacheDir;
}
}
-
+
@Override
public File getFileStreamPath(String name) {
return makeFilename(getFilesDir(), name);
@@ -567,7 +563,7 @@
return (list != null) ? list : EMPTY_FILE_LIST;
}
-
+
private File getDatabasesDir() {
synchronized (mSync) {
if (mDatabasesDir == null) {
@@ -579,7 +575,7 @@
return mDatabasesDir;
}
}
-
+
@Override
public Drawable getWallpaper() {
return getWallpaperManager().getDrawable();
@@ -647,7 +643,7 @@
} catch (RemoteException e) {
}
}
-
+
@Override
public void sendBroadcast(Intent intent) {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
@@ -1560,15 +1556,15 @@
final void setActivityToken(IBinder token) {
mActivityToken = token;
}
-
+
final void setOuterContext(Context context) {
mOuterContext = context;
}
-
+
final Context getOuterContext() {
return mOuterContext;
}
-
+
final IBinder getActivityToken() {
return mActivityToken;
}
@@ -1645,7 +1641,7 @@
{
return mMainThread.releaseProvider(provider);
}
-
+
private final ActivityThread mMainThread;
}
@@ -1678,7 +1674,7 @@
throw new RuntimeException("Package manager has died", e);
}
}
-
+
@Override
public String[] canonicalToCurrentPackageNames(String[] names) {
try {
@@ -1687,7 +1683,7 @@
throw new RuntimeException("Package manager has died", e);
}
}
-
+
@Override
public Intent getLaunchIntentForPackage(String packageName) {
// First see if the package has an INFO activity; the existence of
@@ -1709,8 +1705,9 @@
if (resolveInfo == null) {
return null;
}
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClassName(packageName, resolveInfo.activityInfo.name);
+ Intent intent = new Intent(intentToResolve);
+ intent.setClassName(resolveInfo.activityInfo.applicationInfo.packageName,
+ resolveInfo.activityInfo.name);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return intent;
}
@@ -1876,7 +1873,7 @@
throw new RuntimeException("Package manager has died", e);
}
}
-
+
@Override
public boolean hasSystemFeature(String name) {
try {
@@ -1885,7 +1882,7 @@
throw new RuntimeException("Package manager has died", e);
}
}
-
+
@Override
public int checkPermission(String permName, String pkgName) {
try {
@@ -1957,9 +1954,9 @@
throw new RuntimeException("Package manager has died", e);
}
}
-
+
@Override
- public int getUidForSharedUser(String sharedUserName)
+ public int getUidForSharedUser(String sharedUserName)
throws NameNotFoundException {
try {
int uid = mPM.getUidForSharedUser(sharedUserName);
@@ -2363,7 +2360,7 @@
}
}
}
-
+
private static final class ResourceName {
final String packageName;
final int iconId;
@@ -2535,7 +2532,7 @@
}
}
@Override
- public void clearApplicationUserData(String packageName,
+ public void clearApplicationUserData(String packageName,
IPackageDataObserver observer) {
try {
mPM.clearApplicationUserData(packageName, observer);
@@ -2544,7 +2541,7 @@
}
}
@Override
- public void deleteApplicationCacheFiles(String packageName,
+ public void deleteApplicationCacheFiles(String packageName,
IPackageDataObserver observer) {
try {
mPM.deleteApplicationCacheFiles(packageName, observer);
@@ -2569,9 +2566,9 @@
// Should never happen!
}
}
-
+
@Override
- public void getPackageSizeInfo(String packageName,
+ public void getPackageSizeInfo(String packageName,
IPackageStatsObserver observer) {
try {
mPM.getPackageSizeInfo(packageName, observer);
@@ -2616,7 +2613,7 @@
// Should never happen!
}
}
-
+
@Override
public void replacePreferredActivity(IntentFilter filter,
int match, ComponentName[] set, ComponentName activity) {
@@ -2635,7 +2632,7 @@
// Should never happen!
}
}
-
+
@Override
public int getPreferredActivities(List<IntentFilter> outFilters,
List<ComponentName> outActivities, String packageName) {
@@ -2646,7 +2643,7 @@
}
return 0;
}
-
+
@Override
public void setComponentEnabledSetting(ComponentName componentName,
int newState, int flags) {
@@ -2676,7 +2673,7 @@
// Should never happen!
}
}
-
+
@Override
public int getApplicationEnabledSetting(String packageName) {
try {
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index 009671f..8ba480d 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -21,7 +21,6 @@
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.text.TextUtils.TruncateAt;
-import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.DatePicker;
@@ -39,13 +38,13 @@
* <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker
* tutorial</a>.</p>
*/
-public class DatePickerDialog extends AlertDialog implements OnClickListener,
+public class DatePickerDialog extends AlertDialog implements OnClickListener,
OnDateChangedListener {
private static final String YEAR = "year";
private static final String MONTH = "month";
private static final String DAY = "day";
-
+
private final DatePicker mDatePicker;
private final OnDateSetListener mCallBack;
private final Calendar mCalendar;
@@ -83,7 +82,7 @@
int year,
int monthOfYear,
int dayOfMonth) {
- this(context, com.android.internal.R.style.Theme_Dialog_Alert,
+ this(context, com.android.internal.R.style.Theme_Dialog_Alert,
callBack, year, monthOfYear, dayOfMonth);
}
@@ -109,17 +108,17 @@
mInitialDay = dayOfMonth;
DateFormatSymbols symbols = new DateFormatSymbols();
mWeekDays = symbols.getShortWeekdays();
-
+
mTitleDateFormat = java.text.DateFormat.
getDateInstance(java.text.DateFormat.FULL);
mCalendar = Calendar.getInstance();
updateTitle(mInitialYear, mInitialMonth, mInitialDay);
-
- setButton(context.getText(R.string.date_time_set), this);
- setButton2(context.getText(R.string.cancel), (OnClickListener) null);
+
+ setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set), this);
+ setButton(BUTTON_NEGATIVE, context.getText(R.string.cancel), (OnClickListener) null);
setIcon(R.drawable.ic_dialog_time);
-
- LayoutInflater inflater =
+
+ LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.date_picker_dialog, null);
setView(view);
@@ -139,20 +138,20 @@
title.setSingleLine();
title.setEllipsize(TruncateAt.END);
}
-
+
public void onClick(DialogInterface dialog, int which) {
if (mCallBack != null) {
mDatePicker.clearFocus();
- mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
+ mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
}
}
-
+
public void onDateChanged(DatePicker view, int year,
int month, int day) {
updateTitle(year, month, day);
}
-
+
public void updateDate(int year, int monthOfYear, int dayOfMonth) {
mInitialYear = year;
mInitialMonth = monthOfYear;
@@ -166,7 +165,7 @@
mCalendar.set(Calendar.DAY_OF_MONTH, day);
setTitle(mTitleDateFormat.format(mCalendar.getTime()));
}
-
+
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
@@ -175,7 +174,7 @@
state.putInt(DAY, mDatePicker.getDayOfMonth());
return state;
}
-
+
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 7625c04..2fb746c 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -1131,7 +1131,7 @@
try {
// If the intent was created from a suggestion, it will always have an explicit
// component here.
- Log.i(LOG_TAG, "Starting (as ourselves) " + intent.toURI());
+ Log.i(LOG_TAG, "Starting (as ourselves) " + intent.toUri(0));
getContext().startActivity(intent);
// If the search switches to a different activity,
// SearchDialogWrapper#performActivityResuming
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 62d3f7d..521d41c 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -36,7 +36,7 @@
* <p>See the <a href="{@docRoot}resources/tutorials/views/hello-timepicker.html">Time Picker
* tutorial</a>.</p>
*/
-public class TimePickerDialog extends AlertDialog implements OnClickListener,
+public class TimePickerDialog extends AlertDialog implements OnClickListener,
OnTimeChangedListener {
/**
@@ -56,12 +56,12 @@
private static final String HOUR = "hour";
private static final String MINUTE = "minute";
private static final String IS_24_HOUR = "is24hour";
-
+
private final TimePicker mTimePicker;
private final OnTimeSetListener mCallback;
private final Calendar mCalendar;
private final java.text.DateFormat mDateFormat;
-
+
int mInitialHourOfDay;
int mInitialMinute;
boolean mIs24HourView;
@@ -101,12 +101,13 @@
mDateFormat = DateFormat.getTimeFormat(context);
mCalendar = Calendar.getInstance();
updateTitle(mInitialHourOfDay, mInitialMinute);
-
- setButton(context.getText(R.string.date_time_set), this);
- setButton2(context.getText(R.string.cancel), (OnClickListener) null);
+
+ setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set), this);
+ setButton(BUTTON_NEGATIVE, context.getText(R.string.cancel),
+ (OnClickListener) null);
setIcon(R.drawable.ic_dialog_time);
-
- LayoutInflater inflater =
+
+ LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.time_picker_dialog, null);
setView(view);
@@ -118,11 +119,11 @@
mTimePicker.setIs24HourView(mIs24HourView);
mTimePicker.setOnTimeChangedListener(this);
}
-
+
public void onClick(DialogInterface dialog, int which) {
if (mCallback != null) {
mTimePicker.clearFocus();
- mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
+ mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
mTimePicker.getCurrentMinute());
}
}
@@ -130,7 +131,7 @@
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
updateTitle(hourOfDay, minute);
}
-
+
public void updateTime(int hourOfDay, int minutOfHour) {
mTimePicker.setCurrentHour(hourOfDay);
mTimePicker.setCurrentMinute(minutOfHour);
@@ -141,7 +142,7 @@
mCalendar.set(Calendar.MINUTE, minute);
setTitle(mDateFormat.format(mCalendar.getTime()));
}
-
+
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
@@ -150,7 +151,7 @@
state.putBoolean(IS_24_HOUR, mTimePicker.is24HourView());
return state;
}
-
+
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index d4ce6a1..d2ab85e 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -22,7 +22,6 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.util.TypedValue;
import android.widget.RemoteViews;
@@ -149,7 +148,7 @@
* instances as possible.</td>
* </tr>
* </table>
- *
+ *
* @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
*/
public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
@@ -163,7 +162,7 @@
/**
* Sent when an instance of an AppWidget is removed from the last host.
- *
+ *
* @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
*/
public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
@@ -172,7 +171,7 @@
* Sent when an instance of an AppWidget is added to a host for the first time.
* This broadcast is sent at boot time if there is a AppWidgetHost installed with
* an instance for this provider.
- *
+ *
* @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
*/
public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
@@ -183,20 +182,21 @@
* @see AppWidgetProviderInfo
*/
public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
-
+
/**
* Field for the manifest meta-data tag used to indicate any previous name for the
* app widget receiver.
*
* @see AppWidgetProviderInfo
- *
+ *
* @hide Pending API approval
*/
public static final String META_DATA_APPWIDGET_OLD_NAME = "android.appwidget.oldName";
- static WeakHashMap<Context, WeakReference<AppWidgetManager>> sManagerCache = new WeakHashMap();
+ static WeakHashMap<Context, WeakReference<AppWidgetManager>> sManagerCache =
+ new WeakHashMap<Context, WeakReference<AppWidgetManager>>();
static IAppWidgetService sService;
-
+
Context mContext;
private DisplayMetrics mDisplayMetrics;
@@ -219,7 +219,7 @@
}
if (result == null) {
result = new AppWidgetManager(context);
- sManagerCache.put(context, new WeakReference(result));
+ sManagerCache.put(context, new WeakReference<AppWidgetManager>(result));
}
return result;
}
@@ -310,7 +310,7 @@
AppWidgetProviderInfo info = sService.getAppWidgetInfo(appWidgetId);
if (info != null) {
// Converting complex to dp.
- info.minWidth =
+ info.minWidth =
TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
info.minHeight =
TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
@@ -344,7 +344,7 @@
/**
* Get the list of appWidgetIds that have been bound to the given AppWidget
* provider.
- *
+ *
* @param provider The {@link android.content.BroadcastReceiver} that is the
* AppWidget provider to find appWidgetIds for.
*/
diff --git a/core/java/android/bluetooth/AtCommandHandler.java b/core/java/android/bluetooth/AtCommandHandler.java
index 8de2133..6deab34 100644
--- a/core/java/android/bluetooth/AtCommandHandler.java
+++ b/core/java/android/bluetooth/AtCommandHandler.java
@@ -73,7 +73,7 @@
* least one element in this array.
* @return The result of this command.
*/
- // Typically used to set this paramter
+ // Typically used to set this parameter
public AtCommandResult handleSetCommand(Object[] args) {
return new AtCommandResult(AtCommandResult.ERROR);
}
@@ -83,11 +83,12 @@
* Test commands are part of the Extended command syntax, and are typically
* used to request an indication of the range of legal values that "FOO"
* can take.<p>
- * By defualt we return an OK result, to indicate that this command is at
+ * By default we return an OK result, to indicate that this command is at
* least recognized.<p>
* @return The result of this command.
*/
public AtCommandResult handleTestCommand() {
return new AtCommandResult(AtCommandResult.OK);
}
+
}
diff --git a/core/java/android/bluetooth/BluetoothAssignedNumbers.java b/core/java/android/bluetooth/BluetoothAssignedNumbers.java
new file mode 100644
index 0000000..55bc814
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothAssignedNumbers.java
@@ -0,0 +1,523 @@
+/*
+ * Copyright (C) 2010 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.bluetooth;
+
+/**
+ * Bluetooth Assigned Numbers.
+ * <p>
+ * For now we only include Company ID values.
+ * @see <a href="https://www.bluetooth.org/technical/assignednumbers/identifiers.htm">
+ * The Official Bluetooth SIG Member Website | Company Identifiers</a>
+ *
+ * @hide
+ */
+public class BluetoothAssignedNumbers {
+
+ //// Bluetooth SIG Company ID values
+
+ /*
+ * Ericsson Technology Licensing.
+ */
+ public static final int ERICSSON_TECHNOLOGY = 0x0000;
+
+ /*
+ * Nokia Mobile Phones.
+ */
+ public static final int NOKIA_MOBILE_PHONES = 0x0001;
+
+ /*
+ * Intel Corp.
+ */
+ public static final int INTEL = 0x0002;
+
+ /*
+ * IBM Corp.
+ */
+ public static final int IBM = 0x0003;
+
+ /*
+ * Toshiba Corp.
+ */
+ public static final int TOSHIBA = 0x0004;
+
+ /*
+ * 3Com.
+ */
+ public static final int THREECOM = 0x0005;
+
+ /*
+ * Microsoft.
+ */
+ public static final int MICROSOFT = 0x0006;
+
+ /*
+ * Lucent.
+ */
+ public static final int LUCENT = 0x0007;
+
+ /*
+ * Motorola.
+ */
+ public static final int MOTOROLA = 0x0008;
+
+ /*
+ * Infineon Technologies AG.
+ */
+ public static final int INFINEON_TECHNOLOGIES = 0x0009;
+
+ /*
+ * Cambridge Silicon Radio.
+ */
+ public static final int CAMBRIDGE_SILICON_RADIO = 0x000A;
+
+ /*
+ * Silicon Wave.
+ */
+ public static final int SILICON_WAVE = 0x000B;
+
+ /*
+ * Digianswer A/S.
+ */
+ public static final int DIGIANSWER = 0x000C;
+
+ /*
+ * Texas Instruments Inc.
+ */
+ public static final int TEXAS_INSTRUMENTS = 0x000D;
+
+ /*
+ * Parthus Technologies Inc.
+ */
+ public static final int PARTHUS_TECHNOLOGIES = 0x000E;
+
+ /*
+ * Broadcom Corporation.
+ */
+ public static final int BROADCOM = 0x000F;
+
+ /*
+ * Mitel Semiconductor.
+ */
+ public static final int MITEL_SEMICONDUCTOR = 0x0010;
+
+ /*
+ * Widcomm, Inc.
+ */
+ public static final int WIDCOMM = 0x0011;
+
+ /*
+ * Zeevo, Inc.
+ */
+ public static final int ZEEVO = 0x0012;
+
+ /*
+ * Atmel Corporation.
+ */
+ public static final int ATMEL = 0x0013;
+
+ /*
+ * Mitsubishi Electric Corporation.
+ */
+ public static final int MITSUBISHI_ELECTRIC = 0x0014;
+
+ /*
+ * RTX Telecom A/S.
+ */
+ public static final int RTX_TELECOM = 0x0015;
+
+ /*
+ * KC Technology Inc.
+ */
+ public static final int KC_TECHNOLOGY = 0x0016;
+
+ /*
+ * Newlogic.
+ */
+ public static final int NEWLOGIC = 0x0017;
+
+ /*
+ * Transilica, Inc.
+ */
+ public static final int TRANSILICA = 0x0018;
+
+ /*
+ * Rohde & Schwarz GmbH & Co. KG.
+ */
+ public static final int ROHDE_AND_SCHWARZ = 0x0019;
+
+ /*
+ * TTPCom Limited.
+ */
+ public static final int TTPCOM = 0x001A;
+
+ /*
+ * Signia Technologies, Inc.
+ */
+ public static final int SIGNIA_TECHNOLOGIES = 0x001B;
+
+ /*
+ * Conexant Systems Inc.
+ */
+ public static final int CONEXANT_SYSTEMS = 0x001C;
+
+ /*
+ * Qualcomm.
+ */
+ public static final int QUALCOMM = 0x001D;
+
+ /*
+ * Inventel.
+ */
+ public static final int INVENTEL = 0x001E;
+
+ /*
+ * AVM Berlin.
+ */
+ public static final int AVM_BERLIN = 0x001F;
+
+ /*
+ * BandSpeed, Inc.
+ */
+ public static final int BANDSPEED = 0x0020;
+
+ /*
+ * Mansella Ltd.
+ */
+ public static final int MANSELLA = 0x0021;
+
+ /*
+ * NEC Corporation.
+ */
+ public static final int NEC = 0x0022;
+
+ /*
+ * WavePlus Technology Co., Ltd.
+ */
+ public static final int WAVEPLUS_TECHNOLOGY = 0x0023;
+
+ /*
+ * Alcatel.
+ */
+ public static final int ALCATEL = 0x0024;
+
+ /*
+ * Philips Semiconductors.
+ */
+ public static final int PHILIPS_SEMICONDUCTORS = 0x0025;
+
+ /*
+ * C Technologies.
+ */
+ public static final int C_TECHNOLOGIES = 0x0026;
+
+ /*
+ * Open Interface.
+ */
+ public static final int OPEN_INTERFACE = 0x0027;
+
+ /*
+ * R F Micro Devices.
+ */
+ public static final int RF_MICRO_DEVICES = 0x0028;
+
+ /*
+ * Hitachi Ltd.
+ */
+ public static final int HITACHI = 0x0029;
+
+ /*
+ * Symbol Technologies, Inc.
+ */
+ public static final int SYMBOL_TECHNOLOGIES = 0x002A;
+
+ /*
+ * Tenovis.
+ */
+ public static final int TENOVIS = 0x002B;
+
+ /*
+ * Macronix International Co. Ltd.
+ */
+ public static final int MACRONIX = 0x002C;
+
+ /*
+ * GCT Semiconductor.
+ */
+ public static final int GCT_SEMICONDUCTOR = 0x002D;
+
+ /*
+ * Norwood Systems.
+ */
+ public static final int NORWOOD_SYSTEMS = 0x002E;
+
+ /*
+ * MewTel Technology Inc.
+ */
+ public static final int MEWTEL_TECHNOLOGY = 0x002F;
+
+ /*
+ * ST Microelectronics.
+ */
+ public static final int ST_MICROELECTRONICS = 0x0030;
+
+ /*
+ * Synopsys.
+ */
+ public static final int SYNOPSYS = 0x0031;
+
+ /*
+ * Red-M (Communications) Ltd.
+ */
+ public static final int RED_M = 0x0032;
+
+ /*
+ * Commil Ltd.
+ */
+ public static final int COMMIL = 0x0033;
+
+ /*
+ * Computer Access Technology Corporation (CATC).
+ */
+ public static final int CATC = 0x0034;
+
+ /*
+ * Eclipse (HQ Espana) S.L.
+ */
+ public static final int ECLIPSE = 0x0035;
+
+ /*
+ * Renesas Technology Corp.
+ */
+ public static final int RENESAS_TECHNOLOGY = 0x0036;
+
+ /*
+ * Mobilian Corporation.
+ */
+ public static final int MOBILIAN_CORPORATION = 0x0037;
+
+ /*
+ * Terax.
+ */
+ public static final int TERAX = 0x0038;
+
+ /*
+ * Integrated System Solution Corp.
+ */
+ public static final int INTEGRATED_SYSTEM_SOLUTION = 0x0039;
+
+ /*
+ * Matsushita Electric Industrial Co., Ltd.
+ */
+ public static final int MATSUSHITA_ELECTRIC = 0x003A;
+
+ /*
+ * Gennum Corporation.
+ */
+ public static final int GENNUM = 0x003B;
+
+ /*
+ * Research In Motion.
+ */
+ public static final int RESEARCH_IN_MOTION = 0x003C;
+
+ /*
+ * IPextreme, Inc.
+ */
+ public static final int IPEXTREME = 0x003D;
+
+ /*
+ * Systems and Chips, Inc.
+ */
+ public static final int SYSTEMS_AND_CHIPS = 0x003E;
+
+ /*
+ * Bluetooth SIG, Inc.
+ */
+ public static final int BLUETOOTH_SIG = 0x003F;
+
+ /*
+ * Seiko Epson Corporation.
+ */
+ public static final int SEIKO_EPSON = 0x0040;
+
+ /*
+ * Integrated Silicon Solution Taiwan, Inc.
+ */
+ public static final int INTEGRATED_SILICON_SOLUTION = 0x0041;
+
+ /*
+ * CONWISE Technology Corporation Ltd.
+ */
+ public static final int CONWISE_TECHNOLOGY = 0x0042;
+
+ /*
+ * PARROT SA.
+ */
+ public static final int PARROT = 0x0043;
+
+ /*
+ * Socket Mobile.
+ */
+ public static final int SOCKET_MOBILE = 0x0044;
+
+ /*
+ * Atheros Communications, Inc.
+ */
+ public static final int ATHEROS_COMMUNICATIONS = 0x0045;
+
+ /*
+ * MediaTek, Inc.
+ */
+ public static final int MEDIATEK = 0x0046;
+
+ /*
+ * Bluegiga.
+ */
+ public static final int BLUEGIGA = 0x0047;
+
+ /*
+ * Marvell Technology Group Ltd.
+ */
+ public static final int MARVELL = 0x0048;
+
+ /*
+ * 3DSP Corporation.
+ */
+ public static final int THREE_DSP = 0x0049;
+
+ /*
+ * Accel Semiconductor Ltd.
+ */
+ public static final int ACCEL_SEMICONDUCTOR = 0x004A;
+
+ /*
+ * Continental Automotive Systems.
+ */
+ public static final int CONTINENTAL_AUTOMOTIVE = 0x004B;
+
+ /*
+ * Apple, Inc.
+ */
+ public static final int APPLE = 0x004C;
+
+ /*
+ * Staccato Communications, Inc.
+ */
+ public static final int STACCATO_COMMUNICATIONS = 0x004D;
+
+ /*
+ * Avago Technologies.
+ */
+ public static final int AVAGO = 0x004E;
+
+ /*
+ * APT Licensing Ltd.
+ */
+ public static final int APT_LICENSING = 0x004F;
+
+ /*
+ * SiRF Technology, Inc.
+ */
+ public static final int SIRF_TECHNOLOGY = 0x0050;
+
+ /*
+ * Tzero Technologies, Inc.
+ */
+ public static final int TZERO_TECHNOLOGIES = 0x0051;
+
+ /*
+ * J&M Corporation.
+ */
+ public static final int J_AND_M = 0x0052;
+
+ /*
+ * Free2move AB.
+ */
+ public static final int FREE2MOVE = 0x0053;
+
+ /*
+ * 3DiJoy Corporation.
+ */
+ public static final int THREE_DIJOY = 0x0054;
+
+ /*
+ * Plantronics, Inc.
+ */
+ public static final int PLANTRONICS = 0x0055;
+
+ /*
+ * Sony Ericsson Mobile Communications.
+ */
+ public static final int SONY_ERICSSON = 0x0056;
+
+ /*
+ * Harman International Industries, Inc.
+ */
+ public static final int HARMAN_INTERNATIONAL = 0x0057;
+
+ /*
+ * Vizio, Inc.
+ */
+ public static final int VIZIO = 0x0058;
+
+ /*
+ * Nordic Semiconductor ASA.
+ */
+ public static final int NORDIC_SEMICONDUCTOR = 0x0059;
+
+ /*
+ * EM Microelectronic-Marin SA.
+ */
+ public static final int EM_MICROELECTRONIC_MARIN = 0x005A;
+
+ /*
+ * Ralink Technology Corporation.
+ */
+ public static final int RALINK_TECHNOLOGY = 0x005B;
+
+ /*
+ * Belkin International, Inc.
+ */
+ public static final int BELKIN_INTERNATIONAL = 0x005C;
+
+ /*
+ * Realtek Semiconductor Corporation.
+ */
+ public static final int REALTEK_SEMICONDUCTOR = 0x005D;
+
+ /*
+ * Stonestreet One, LLC.
+ */
+ public static final int STONESTREET_ONE = 0x005E;
+
+ /*
+ * Wicentric, Inc.
+ */
+ public static final int WICENTRIC = 0x005F;
+
+ /*
+ * RivieraWaves S.A.S.
+ */
+ public static final int RIVIERAWAVES = 0x0060;
+
+ /*
+ * You can't instantiate one of these.
+ */
+ private BluetoothAssignedNumbers() {
+ }
+
+}
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 4a91a8c..53d6a37 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -45,7 +45,7 @@
* This BluetoothHeadset object is not immediately bound to the
* BluetoothHeadset service. Use the ServiceListener interface to obtain a
* notification when it is bound, this is especially important if you wish to
- * immediately call methods on BluetootHeadset after construction.
+ * immediately call methods on BluetoothHeadset after construction.
*
* Android only supports one connected Bluetooth Headset at a time.
*
@@ -85,6 +85,43 @@
"android.bluetooth.headset.extra.DISCONNECT_INITIATOR";
/**
+ * Broadcast Action: Indicates a headset has posted a vendor-specific event.
+ * <p>Always contains the extra fields {@link #EXTRA_DEVICE},
+ * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD}, and
+ * {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS}.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_VENDOR_SPECIFIC_HEADSET_EVENT =
+ "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT";
+
+ /**
+ * A String extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
+ * intents that contains the name of the vendor-specific command.
+ */
+ public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD =
+ "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD";
+
+ /**
+ * An int extra field in {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT}
+ * intents that contains the Company ID of the vendor defining the vendor-specific
+ * command.
+ * @see <a href="https://www.bluetooth.org/Technical/AssignedNumbers/identifiers.htm">
+ * Bluetooth SIG Assigned Numbers - Company Identifiers</a>
+ */
+ public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID =
+ "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID";
+
+ /**
+ * A Parcelable String array extra field in
+ * {@link #ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} intents that contains
+ * the arguments to the vendor-specific command.
+ */
+ public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS =
+ "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_ARGS";
+
+
+ /**
* TODO(API release): Consider incorporating as new state in
* HEADSET_STATE_CHANGED
*/
@@ -108,7 +145,7 @@
public static final int RESULT_FAILURE = 0;
public static final int RESULT_SUCCESS = 1;
- /** Connection canceled before completetion. */
+ /** Connection canceled before completion. */
public static final int RESULT_CANCELED = 2;
/** Values for {@link #EXTRA_DISCONNECT_INITIATOR} */
diff --git a/core/java/android/bluetooth/HeadsetBase.java b/core/java/android/bluetooth/HeadsetBase.java
index e2935c9..9ef2eb5 100644
--- a/core/java/android/bluetooth/HeadsetBase.java
+++ b/core/java/android/bluetooth/HeadsetBase.java
@@ -74,8 +74,8 @@
private native void cleanupNativeDataNative();
- public HeadsetBase(PowerManager pm, BluetoothAdapter adapter, BluetoothDevice device,
- int rfcommChannel) {
+ public HeadsetBase(PowerManager pm, BluetoothAdapter adapter,
+ BluetoothDevice device, int rfcommChannel) {
mDirection = DIRECTION_OUTGOING;
mConnectTimestamp = System.currentTimeMillis();
mAdapter = adapter;
@@ -89,9 +89,10 @@
initializeNativeDataNative(-1);
}
- /* Create from an already exisiting rfcomm connection */
- public HeadsetBase(PowerManager pm, BluetoothAdapter adapter, BluetoothDevice device,
- int socketFd, int rfcommChannel, Handler handler) {
+ /* Create from an existing rfcomm connection */
+ public HeadsetBase(PowerManager pm, BluetoothAdapter adapter,
+ BluetoothDevice device,
+ int socketFd, int rfcommChannel, Handler handler) {
mDirection = DIRECTION_INCOMING;
mConnectTimestamp = System.currentTimeMillis();
mAdapter = adapter;
@@ -128,7 +129,7 @@
(System.currentTimeMillis() - timestamp) + " ms");
if (result.getResultCode() == AtCommandResult.ERROR) {
- Log.i(TAG, "Error pocessing <" + input + ">");
+ Log.i(TAG, "Error processing <" + input + ">");
}
sendURC(result.toString());
@@ -142,8 +143,9 @@
*/
protected void initializeAtParser() {
mAtParser = new AtParser();
- //TODO(): Get rid of this as there are no parsers registered. But because of dependencies,
- //it needs to be done as part of refactoring HeadsetBase and BluetoothHandsfree
+
+ //TODO(): Get rid of this as there are no parsers registered. But because of dependencies
+ // it needs to be done as part of refactoring HeadsetBase and BluetoothHandsfree
}
public AtParser getAtParser() {
@@ -159,8 +161,7 @@
String input = readNative(500);
if (input != null) {
handleInput(input);
- }
- else {
+ } else {
last_read_error = getLastReadStatusNative();
if (last_read_error != 0) {
Log.i(TAG, "headset read error " + last_read_error);
@@ -179,8 +180,6 @@
mEventThread.start();
}
-
-
private native String readNative(int timeout_ms);
private native int getLastReadStatusNative();
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
old mode 100644
new mode 100755
index 9bb3b75..a6513aa
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -25,6 +25,7 @@
import android.graphics.Movie;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable.ConstantState;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemProperties;
@@ -66,6 +67,8 @@
= new LongSparseArray<Drawable.ConstantState>();
private static final SparseArray<ColorStateList> mPreloadedColorStateLists
= new SparseArray<ColorStateList>();
+ private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables
+ = new LongSparseArray<Drawable.ConstantState>();
private static boolean mPreloaded;
/*package*/ final TypedValue mTmpValue = new TypedValue();
@@ -75,6 +78,8 @@
= new LongSparseArray<WeakReference<Drawable.ConstantState> >();
private final SparseArray<WeakReference<ColorStateList> > mColorStateListCache
= new SparseArray<WeakReference<ColorStateList> >();
+ private final LongSparseArray<WeakReference<Drawable.ConstantState> > mColorDrawableCache
+ = new LongSparseArray<WeakReference<Drawable.ConstantState> >();
private boolean mPreloading;
/*package*/ TypedArray mCachedStyledAttributes = null;
@@ -1299,37 +1304,13 @@
(int)(mMetrics.density*160), mConfiguration.keyboard,
keyboardHidden, mConfiguration.navigation, width, height,
mConfiguration.screenLayout, mConfiguration.uiMode, sSdkVersion);
- int N = mDrawableCache.size();
- if (DEBUG_CONFIG) {
- Log.d(TAG, "Cleaning up drawables config changes: 0x"
- + Integer.toHexString(configChanges));
- }
- for (int i=0; i<N; i++) {
- WeakReference<Drawable.ConstantState> ref = mDrawableCache.valueAt(i);
- if (ref != null) {
- Drawable.ConstantState cs = ref.get();
- if (cs != null) {
- if (Configuration.needNewResources(
- configChanges, cs.getChangingConfigurations())) {
- if (DEBUG_CONFIG) {
- Log.d(TAG, "FLUSHING #0x"
- + Long.toHexString(mDrawableCache.keyAt(i))
- + " / " + cs + " with changes: 0x"
- + Integer.toHexString(cs.getChangingConfigurations()));
- }
- mDrawableCache.setValueAt(i, null);
- } else if (DEBUG_CONFIG) {
- Log.d(TAG, "(Keeping #0x"
- + Long.toHexString(mDrawableCache.keyAt(i))
- + " / " + cs + " with changes: 0x"
- + Integer.toHexString(cs.getChangingConfigurations())
- + ")");
- }
- }
- }
- }
- mDrawableCache.clear();
+
+ clearDrawableCache(mDrawableCache, configChanges);
+ clearDrawableCache(mColorDrawableCache, configChanges);
+
mColorStateListCache.clear();
+
+
flushLayoutCache();
}
synchronized (mSync) {
@@ -1339,6 +1320,41 @@
}
}
+ private void clearDrawableCache(
+ LongSparseArray<WeakReference<ConstantState>> cache,
+ int configChanges) {
+ int N = cache.size();
+ if (DEBUG_CONFIG) {
+ Log.d(TAG, "Cleaning up drawables config changes: 0x"
+ + Integer.toHexString(configChanges));
+ }
+ for (int i=0; i<N; i++) {
+ WeakReference<Drawable.ConstantState> ref = cache.valueAt(i);
+ if (ref != null) {
+ Drawable.ConstantState cs = ref.get();
+ if (cs != null) {
+ if (Configuration.needNewResources(
+ configChanges, cs.getChangingConfigurations())) {
+ if (DEBUG_CONFIG) {
+ Log.d(TAG, "FLUSHING #0x"
+ + Long.toHexString(mDrawableCache.keyAt(i))
+ + " / " + cs + " with changes: 0x"
+ + Integer.toHexString(cs.getChangingConfigurations()));
+ }
+ cache.setValueAt(i, null);
+ } else if (DEBUG_CONFIG) {
+ Log.d(TAG, "(Keeping #0x"
+ + Long.toHexString(cache.keyAt(i))
+ + " / " + cs + " with changes: 0x"
+ + Integer.toHexString(cs.getChangingConfigurations())
+ + ")");
+ }
+ }
+ }
+ }
+ cache.clear();
+ }
+
/**
* Update the system resources configuration if they have previously
* been initialized.
@@ -1661,13 +1677,18 @@
}
final long key = (((long) value.assetCookie) << 32) | value.data;
- Drawable dr = getCachedDrawable(key);
+ boolean isColorDrawable = false;
+ if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
+ value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
+ isColorDrawable = true;
+ }
+ Drawable dr = getCachedDrawable(isColorDrawable ? mColorDrawableCache : mDrawableCache, key);
if (dr != null) {
return dr;
}
- Drawable.ConstantState cs = sPreloadedDrawables.get(key);
+ Drawable.ConstantState cs = isColorDrawable ? sPreloadedColorDrawables.get(key) : sPreloadedDrawables.get(key);
if (cs != null) {
dr = cs.newDrawable(this);
} else {
@@ -1726,13 +1747,21 @@
cs = dr.getConstantState();
if (cs != null) {
if (mPreloading) {
- sPreloadedDrawables.put(key, cs);
+ if (isColorDrawable) {
+ sPreloadedColorDrawables.put(key, cs);
+ } else {
+ sPreloadedDrawables.put(key, cs);
+ }
} else {
synchronized (mTmpValue) {
//Log.i(TAG, "Saving cached drawable @ #" +
// Integer.toHexString(key.intValue())
// + " in " + this + ": " + cs);
- mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
+ if (isColorDrawable) {
+ mColorDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
+ } else {
+ mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
+ }
}
}
}
@@ -1741,9 +1770,11 @@
return dr;
}
- private Drawable getCachedDrawable(long key) {
+ private Drawable getCachedDrawable(
+ LongSparseArray<WeakReference<ConstantState>> drawableCache,
+ long key) {
synchronized (mTmpValue) {
- WeakReference<Drawable.ConstantState> wr = mDrawableCache.get(key);
+ WeakReference<Drawable.ConstantState> wr = drawableCache.get(key);
if (wr != null) { // we have the key
Drawable.ConstantState entry = wr.get();
if (entry != null) {
@@ -1753,7 +1784,7 @@
return entry.newDrawable(this);
}
else { // our entry has been purged
- mDrawableCache.delete(key);
+ drawableCache.delete(key);
}
}
}
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index 038eedf..a5e5e46 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -204,7 +204,7 @@
* @param window
*/
public void fillWindow(int position, CursorWindow window) {
- if (position < 0 || position > getCount()) {
+ if (position < 0 || position >= getCount()) {
return;
}
window.acquireReference();
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 66406ca..95fc1fd 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -50,8 +50,6 @@
private static final boolean DEBUG = false;
private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
- private static final String[] countProjection = new String[]{"count(*)"};
-
/**
* Special function for writing an exception result at the header of
* a parcel, to be used when returning an exception from a transaction.
@@ -604,14 +602,40 @@
* @return the number of rows in the table
*/
public static long queryNumEntries(SQLiteDatabase db, String table) {
- Cursor cursor = db.query(table, countProjection,
- null, null, null, null, null);
- try {
- cursor.moveToFirst();
- return cursor.getLong(0);
- } finally {
- cursor.close();
- }
+ return queryNumEntries(db, table, null, null);
+ }
+
+ /**
+ * Query the table for the number of rows in the table.
+ * @param db the database the table is in
+ * @param table the name of the table to query
+ * @param selection A filter declaring which rows to return,
+ * formatted as an SQL WHERE clause (excluding the WHERE itself).
+ * Passing null will count all rows for the given table
+ * @return the number of rows in the table filtered by the selection
+ */
+ public static long queryNumEntries(SQLiteDatabase db, String table, String selection) {
+ return queryNumEntries(db, table, selection, null);
+ }
+
+ /**
+ * Query the table for the number of rows in the table.
+ * @param db the database the table is in
+ * @param table the name of the table to query
+ * @param selection A filter declaring which rows to return,
+ * formatted as an SQL WHERE clause (excluding the WHERE itself).
+ * Passing null will count all rows for the given table
+ * @param selectionArgs You may include ?s in selection,
+ * which will be replaced by the values from selectionArgs,
+ * in order that they appear in the selection.
+ * The values will be bound as Strings.
+ * @return the number of rows in the table filtered by the selection
+ */
+ public static long queryNumEntries(SQLiteDatabase db, String table, String selection,
+ String[] selectionArgs) {
+ String s = (!TextUtils.isEmpty(selection)) ? " where " + selection : "";
+ return longForQuery(db, "select count(*) from " + table + s,
+ selectionArgs);
}
/**
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 280ded6..5b0f60f 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -21,6 +21,9 @@
import android.os.Binder;
import android.os.RemoteException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
/**
* Class that answers queries about the state of network connectivity. It also
* notifies applications when network connectivity changes. Get an instance
@@ -309,8 +312,29 @@
* @return {@code true} on success, {@code false} on failure
*/
public boolean requestRouteToHost(int networkType, int hostAddress) {
+ InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
+
+ if (inetAddress == null) {
+ return false;
+ }
+
+ return requestRouteToHostAddress(networkType, inetAddress);
+ }
+
+ /**
+ * Ensure that a network route exists to deliver traffic to the specified
+ * host via the specified network interface. An attempt to add a route that
+ * already exists is ignored, but treated as successful.
+ * @param networkType the type of the network over which traffic to the specified
+ * host is to be routed
+ * @param hostAddress the IP address of the host to which the route is desired
+ * @return {@code true} on success, {@code false} on failure
+ * @hide
+ */
+ public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
+ byte[] address = hostAddress.getAddress();
try {
- return mService.requestRouteToHost(networkType, hostAddress);
+ return mService.requestRouteToHostAddress(networkType, address);
} catch (RemoteException e) {
return false;
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b05c2ed..0eb3afd 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -47,6 +47,8 @@
boolean requestRouteToHost(int networkType, int hostAddress);
+ boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
+
boolean getBackgroundDataSetting();
void setBackgroundDataSetting(boolean allowBackgroundData);
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index eb7117b..004cdb7 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -16,6 +16,8 @@
package android.net;
+import java.net.InetAddress;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -23,7 +25,6 @@
import android.os.RemoteException;
import android.os.Handler;
import android.os.ServiceManager;
-import android.os.SystemProperties;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.TelephonyIntents;
@@ -489,17 +490,16 @@
* Ensure that a network route exists to deliver traffic to the specified
* host via the mobile data network.
* @param hostAddress the IP address of the host to which the route is desired,
- * in network byte order.
* @return {@code true} on success, {@code false} on failure
*/
@Override
- public boolean requestRouteToHost(int hostAddress) {
+ public boolean requestRouteToHost(InetAddress hostAddress) {
if (DBG) {
- Log.d(TAG, "Requested host route to " + Integer.toHexString(hostAddress) +
+ Log.d(TAG, "Requested host route to " + hostAddress.getHostAddress() +
" for " + mApnType + "(" + mInterfaceName + ")");
}
- if (mInterfaceName != null && hostAddress != -1) {
- return NetworkUtils.addHostRoute(mInterfaceName, hostAddress) == 0;
+ if (mInterfaceName != null) {
+ return NetworkUtils.addHostRoute(mInterfaceName, hostAddress, null);
} else {
return false;
}
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 0277d2d..838696d 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -18,13 +18,14 @@
import java.io.FileWriter;
import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
import android.content.Context;
import android.text.TextUtils;
-import android.util.Config;
import android.util.Log;
@@ -128,13 +129,18 @@
}
if (mInterfaceName != null && !mPrivateDnsRouteSet) {
for (String addrString : getNameServers()) {
- int addr = NetworkUtils.lookupHost(addrString);
- if (addr != -1 && addr != 0) {
- if (DBG) Log.d(TAG, " adding "+addrString+" ("+addr+")");
- NetworkUtils.addHostRoute(mInterfaceName, addr);
+ if (addrString != null) {
+ try {
+ InetAddress inetAddress = InetAddress.getByName(addrString);
+ if (DBG) Log.d(TAG, " adding " + addrString);
+ if (NetworkUtils.addHostRoute(mInterfaceName, inetAddress, null)) {
+ mPrivateDnsRouteSet = true;
+ }
+ } catch (UnknownHostException e) {
+ if (DBG) Log.d(TAG, " DNS address " + addrString + " : Exception " + e);
+ }
}
}
- mPrivateDnsRouteSet = true;
}
}
@@ -157,7 +163,14 @@
Log.d(TAG, "addDefaultRoute for " + mNetworkInfo.getTypeName() +
" (" + mInterfaceName + "), GatewayAddr=" + mDefaultGatewayAddr);
}
- NetworkUtils.setDefaultRoute(mInterfaceName, mDefaultGatewayAddr);
+ InetAddress inetAddress = NetworkUtils.intToInetAddress(mDefaultGatewayAddr);
+ if (inetAddress == null) {
+ if (DBG) Log.d(TAG, " Unable to add default route. mDefaultGatewayAddr Error");
+ } else {
+ if (!NetworkUtils.addDefaultRoute(mInterfaceName, inetAddress) && DBG) {
+ Log.d(TAG, " Unable to add default route.");
+ }
+ }
}
}
@@ -394,7 +407,7 @@
* @param hostAddress the IP address of the host to which the route is desired
* @return {@code true} on success, {@code false} on failure
*/
- public boolean requestRouteToHost(int hostAddress) {
+ public boolean requestRouteToHost(InetAddress hostAddress) {
return false;
}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index e4f3d5c..5d4b099 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -17,25 +17,39 @@
package android.net;
import java.net.InetAddress;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
import java.net.UnknownHostException;
+import android.util.Log;
+
/**
* Native methods for managing network interfaces.
*
* {@hide}
*/
public class NetworkUtils {
+
+ private static final String TAG = "NetworkUtils";
+
/** Bring the named network interface up. */
public native static int enableInterface(String interfaceName);
/** Bring the named network interface down. */
public native static int disableInterface(String interfaceName);
- /** Add a route to the specified host via the named interface. */
- public native static int addHostRoute(String interfaceName, int hostaddr);
-
- /** Add a default route for the named interface. */
- public native static int setDefaultRoute(String interfaceName, int gwayAddr);
+ /**
+ * Add a route to the routing table.
+ *
+ * @param interfaceName the interface to route through.
+ * @param dst the network or host to route to. May be IPv4 or IPv6, e.g.
+ * "0.0.0.0" or "2001:4860::".
+ * @param prefixLength the prefix length of the route.
+ * @param gw the gateway to use, e.g., "192.168.251.1". If null,
+ * indicates a directly-connected route.
+ */
+ public native static int addRoute(String interfaceName, String dst,
+ int prefixLength, String gw);
/** Return the gateway address for the default route for the named interface. */
public native static int getDefaultRoute(String interfaceName);
@@ -106,27 +120,79 @@
String interfaceName, int ipAddress, int netmask, int gateway, int dns1, int dns2);
/**
- * Look up a host name and return the result as an int. Works if the argument
- * is an IP address in dot notation. Obviously, this can only be used for IPv4
- * addresses.
- * @param hostname the name of the host (or the IP address)
- * @return the IP address as an {@code int} in network byte order
+ * Convert a IPv4 address from an integer to an InetAddress.
+ * @param hostAddr is an Int corresponding to the IPv4 address in network byte order
+ * @return the IP address as an {@code InetAddress}, returns null if
+ * unable to convert or if the int is an invalid address.
*/
- public static int lookupHost(String hostname) {
+ public static InetAddress intToInetAddress(int hostAddress) {
InetAddress inetAddress;
+ byte[] addressBytes = { (byte)(0xff & hostAddress),
+ (byte)(0xff & (hostAddress >> 8)),
+ (byte)(0xff & (hostAddress >> 16)),
+ (byte)(0xff & (hostAddress >> 24)) };
+
try {
- inetAddress = InetAddress.getByName(hostname);
- } catch (UnknownHostException e) {
- return -1;
+ inetAddress = InetAddress.getByAddress(addressBytes);
+ } catch(UnknownHostException e) {
+ return null;
}
- byte[] addrBytes;
- int addr;
- addrBytes = inetAddress.getAddress();
- addr = ((addrBytes[3] & 0xff) << 24)
- | ((addrBytes[2] & 0xff) << 16)
- | ((addrBytes[1] & 0xff) << 8)
- | (addrBytes[0] & 0xff);
- return addr;
+
+ return inetAddress;
+ }
+
+ /**
+ * Add a default route through the specified gateway.
+ * @param interfaceName interface on which the route should be added
+ * @param gw the IP address of the gateway to which the route is desired,
+ * @return {@code true} on success, {@code false} on failure
+ */
+ public static boolean addDefaultRoute(String interfaceName, InetAddress gw) {
+ String dstStr;
+ String gwStr = gw.getHostAddress();
+
+ if (gw instanceof Inet4Address) {
+ dstStr = "0.0.0.0";
+ } else if (gw instanceof Inet6Address) {
+ dstStr = "::";
+ } else {
+ Log.w(TAG, "addDefaultRoute failure: address is neither IPv4 nor IPv6" +
+ "(" + gwStr + ")");
+ return false;
+ }
+ return addRoute(interfaceName, dstStr, 0, gwStr) == 0;
+ }
+
+ /**
+ * Add a host route.
+ * @param interfaceName interface on which the route should be added
+ * @param dst the IP address of the host to which the route is desired,
+ * this should not be null.
+ * @param gw the IP address of the gateway to which the route is desired,
+ * if null, indicates a directly-connected route.
+ * @return {@code true} on success, {@code false} on failure
+ */
+ public static boolean addHostRoute(String interfaceName, InetAddress dst,
+ InetAddress gw) {
+ if (dst == null) {
+ Log.w(TAG, "addHostRoute: dst should not be null");
+ return false;
+ }
+
+ int prefixLength;
+ String dstStr = dst.getHostAddress();
+ String gwStr = (gw != null) ? gw.getHostAddress() : null;
+
+ if (dst instanceof Inet4Address) {
+ prefixLength = 32;
+ } else if (dst instanceof Inet6Address) {
+ prefixLength = 128;
+ } else {
+ Log.w(TAG, "addHostRoute failure: address is neither IPv4 nor IPv6" +
+ "(" + dst + ")");
+ return false;
+ }
+ return addRoute(interfaceName, dstStr, prefixLength, gwStr) == 0;
}
public static int v4StringToInt(String str) {
diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java
index 66eefb2..22c30a5 100644
--- a/core/java/android/net/Proxy.java
+++ b/core/java/android/net/Proxy.java
@@ -16,12 +16,18 @@
package android.net;
+import org.apache.http.HttpHost;
+
import android.content.ContentResolver;
import android.content.Context;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Log;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+
import junit.framework.Assert;
/**
@@ -120,4 +126,73 @@
}
}
+ /**
+ * Returns the preferred proxy to be used by clients. This is a wrapper
+ * around {@link android.net.Proxy#getHost()}. Currently no proxy will
+ * be returned for localhost or if the active network is Wi-Fi.
+ *
+ * @param context the context which will be passed to
+ * {@link android.net.Proxy#getHost()}
+ * @param url the target URL for the request
+ * @note Calling this method requires permission
+ * android.permission.ACCESS_NETWORK_STATE
+ * @return The preferred proxy to be used by clients, or null if there
+ * is no proxy.
+ *
+ * {@hide}
+ */
+ static final public HttpHost getPreferredHttpHost(Context context,
+ String url) {
+ if (!isLocalHost(url) && !isNetworkWifi(context)) {
+ final String proxyHost = Proxy.getHost(context);
+ if (proxyHost != null) {
+ return new HttpHost(proxyHost, Proxy.getPort(context), "http");
+ }
+ }
+
+ return null;
+ }
+
+ static final private boolean isLocalHost(String url) {
+ if (url == null) {
+ return false;
+ }
+
+ try {
+ final URI uri = URI.create(url);
+ final String host = uri.getHost();
+ if (host != null) {
+ if (host.equalsIgnoreCase("localhost")) {
+ return true;
+ }
+ if (InetAddress.getByName(host).isLoopbackAddress()) {
+ return true;
+ }
+ }
+ } catch (UnknownHostException uex) {
+ // Ignore (INetworkSystem.ipStringToByteArray)
+ } catch (IllegalArgumentException iex) {
+ // Ignore (URI.create)
+ }
+
+ return false;
+ }
+
+ static final private boolean isNetworkWifi(Context context) {
+ if (context == null) {
+ return false;
+ }
+
+ final ConnectivityManager connectivity = (ConnectivityManager)
+ context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (connectivity != null) {
+ final NetworkInfo info = connectivity.getActiveNetworkInfo();
+ if (info != null &&
+ info.getType() == ConnectivityManager.TYPE_WIFI) {
+ return true;
+ }
+ }
+
+ return false;
+ }
};
diff --git a/core/java/android/net/http/Headers.java b/core/java/android/net/http/Headers.java
index 09f6f4f..74c0de8 100644
--- a/core/java/android/net/http/Headers.java
+++ b/core/java/android/net/http/Headers.java
@@ -262,7 +262,14 @@
break;
case HASH_CACHE_CONTROL:
if (name.equals(CACHE_CONTROL)) {
- mHeaders[IDX_CACHE_CONTROL] = val;
+ // In case where we receive more than one header, create a ',' separated list.
+ // This should be ok, according to RFC 2616 chapter 4.2
+ if (mHeaders[IDX_CACHE_CONTROL] != null &&
+ mHeaders[IDX_CACHE_CONTROL].length() > 0) {
+ mHeaders[IDX_CACHE_CONTROL] += (',' + val);
+ } else {
+ mHeaders[IDX_CACHE_CONTROL] = val;
+ }
}
break;
case HASH_LAST_MODIFIED:
diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java
index 8c9d013f..cefa997 100644
--- a/core/java/android/net/http/HttpsConnection.java
+++ b/core/java/android/net/http/HttpsConnection.java
@@ -204,10 +204,13 @@
BasicHttpRequest proxyReq = new BasicHttpRequest
("CONNECT", mHost.toHostString());
- // add all 'proxy' headers from the original request
+ // add all 'proxy' headers from the original request, we also need
+ // to add 'host' header unless we want proxy to answer us with a
+ // 400 Bad Request
for (Header h : req.mHttpRequest.getAllHeaders()) {
String headerName = h.getName().toLowerCase();
- if (headerName.startsWith("proxy") || headerName.equals("keep-alive")) {
+ if (headerName.startsWith("proxy") || headerName.equals("keep-alive")
+ || headerName.equals("host")) {
proxyReq.addHeader(h);
}
}
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 2e14667..86f9a6b 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -94,7 +94,8 @@
/**
* Default trace file path and file
*/
- private static final String DEFAULT_TRACE_PATH_PREFIX = "/sdcard/";
+ private static final String DEFAULT_TRACE_PATH_PREFIX =
+ Environment.getExternalStorageDirectory().getPath() + "/";
private static final String DEFAULT_TRACE_BODY = "dmtrace";
private static final String DEFAULT_TRACE_EXTENSION = ".trace";
private static final String DEFAULT_TRACE_FILE_PATH =
@@ -127,7 +128,7 @@
public int otherPrivateDirty;
/** The shared dirty pages used by everything else. */
public int otherSharedDirty;
-
+
public MemoryInfo() {
}
@@ -137,21 +138,21 @@
public int getTotalPss() {
return dalvikPss + nativePss + otherPss;
}
-
+
/**
* Return total private dirty memory usage in kB.
*/
public int getTotalPrivateDirty() {
return dalvikPrivateDirty + nativePrivateDirty + otherPrivateDirty;
}
-
+
/**
* Return total shared dirty memory usage in kB.
*/
public int getTotalSharedDirty() {
return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty;
}
-
+
public int describeContents() {
return 0;
}
@@ -179,7 +180,7 @@
otherPrivateDirty = source.readInt();
otherSharedDirty = source.readInt();
}
-
+
public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() {
public MemoryInfo createFromParcel(Parcel source) {
return new MemoryInfo(source);
@@ -460,7 +461,7 @@
* Like startMethodTracing(String, int, int), but taking an already-opened
* FileDescriptor in which the trace is written. The file name is also
* supplied simply for logging. Makes a dup of the file descriptor.
- *
+ *
* Not exposed in the SDK unless we are really comfortable with supporting
* this and find it would be useful.
* @hide
@@ -1070,7 +1071,7 @@
* static {
* // Sets all the fields
* Debug.setFieldsOn(MyDebugVars.class);
- *
+ *
* // Sets only the fields annotated with @Debug.DebugProperty
* // Debug.setFieldsOn(MyDebugVars.class, true);
* }
diff --git a/core/java/android/preference/ListPreference.java b/core/java/android/preference/ListPreference.java
index f842d75..f44cbe4 100644
--- a/core/java/android/preference/ListPreference.java
+++ b/core/java/android/preference/ListPreference.java
@@ -39,6 +39,7 @@
private CharSequence[] mEntries;
private CharSequence[] mEntryValues;
private String mValue;
+ private String mSummary;
private int mClickedDialogEntryIndex;
public ListPreference(Context context, AttributeSet attrs) {
@@ -49,8 +50,16 @@
mEntries = a.getTextArray(com.android.internal.R.styleable.ListPreference_entries);
mEntryValues = a.getTextArray(com.android.internal.R.styleable.ListPreference_entryValues);
a.recycle();
+
+ /* Retrieve the Preference summary attribute since it's private
+ * in the Preference class.
+ */
+ a = context.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.Preference, 0, 0);
+ mSummary = a.getString(com.android.internal.R.styleable.Preference_summary);
+ a.recycle();
}
-
+
public ListPreference(Context context) {
this(context, null);
}
@@ -127,6 +136,43 @@
}
/**
+ * Returns the summary of this ListPreference. If the summary
+ * has a {@linkplain java.lang.String#format String formatting}
+ * marker in it (i.e. "%s" or "%1$s"), then the current entry
+ * value will be substituted in its place.
+ *
+ * @return the summary with appropriate string substitution
+ */
+ @Override
+ public CharSequence getSummary() {
+ final CharSequence entry = getEntry();
+ if (mSummary == null || entry == null) {
+ return super.getSummary();
+ } else {
+ return String.format(mSummary, entry);
+ }
+ }
+
+ /**
+ * Sets the summary for this Preference with a CharSequence.
+ * If the summary has a
+ * {@linkplain java.lang.String#format String formatting}
+ * marker in it (i.e. "%s" or "%1$s"), then the current entry
+ * value will be substituted in its place when it's retrieved.
+ *
+ * @param summary The summary for the preference.
+ */
+ @Override
+ public void setSummary(CharSequence summary) {
+ super.setSummary(summary);
+ if (summary == null && mSummary != null) {
+ mSummary = null;
+ } else if (summary != null && !summary.equals(mSummary)) {
+ mSummary = summary.toString();
+ }
+ }
+
+ /**
* Sets the value to the given index from the entry values.
*
* @param index The index of the value to set.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 78a384b..f5fad4d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3579,7 +3579,7 @@
while (intent == null && c.moveToNext()) {
try {
String intentURI = c.getString(c.getColumnIndexOrThrow(INTENT));
- intent = Intent.getIntent(intentURI);
+ intent = Intent.parseUri(intentURI, 0);
} catch (java.net.URISyntaxException e) {
// The stored URL is bad... ignore it.
} catch (IllegalArgumentException e) {
@@ -3637,7 +3637,7 @@
ContentValues values = new ContentValues();
if (title != null) values.put(TITLE, title);
if (folder != null) values.put(FOLDER, folder);
- values.put(INTENT, intent.toURI());
+ values.put(INTENT, intent.toUri(0));
if (shortcut != 0) values.put(SHORTCUT, (int) shortcut);
values.put(ORDERING, ordering);
return cr.insert(CONTENT_URI, values);
@@ -3689,7 +3689,7 @@
Intent intent;
try {
- intent = Intent.getIntent(intentUri);
+ intent = Intent.parseUri(intentUri, 0);
} catch (URISyntaxException e) {
return "";
}
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index bf9e854..fa5cd8b 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -25,6 +25,7 @@
import android.database.Cursor;
import android.database.sqlite.SqliteWrapper;
import android.net.Uri;
+import android.os.Environment;
import android.telephony.SmsMessage;
import android.text.TextUtils;
import android.util.Config;
@@ -561,15 +562,24 @@
* values:</p>
*
* <ul>
- * <li><em>transactionId (Integer)</em> - The WAP transaction
- * ID</li>
+ * <li><em>transactionId (Integer)</em> - The WAP transaction ID</li>
* <li><em>pduType (Integer)</em> - The WAP PDU type</li>
* <li><em>header (byte[])</em> - The header of the message</li>
* <li><em>data (byte[])</em> - The data payload of the message</li>
+ * <li><em>contentTypeParameters (HashMap<String,String>)</em>
+ * - Any parameters associated with the content type
+ * (decoded from the WSP Content-Type header)</li>
* </ul>
*
* <p>If a BroadcastReceiver encounters an error while processing
* this intent it should set the result code appropriately.</p>
+ *
+ * <p>The contentTypeParameters extra value is map of content parameters keyed by
+ * their names.</p>
+ *
+ * <p>If any unassigned well-known parameters are encountered, the key of the map will
+ * be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter. If
+ * a parameter has No-Value the value in the map will be null.</p>
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String WAP_PUSH_RECEIVED_ACTION =
@@ -582,7 +592,7 @@
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String SIM_FULL_ACTION =
- "android.provider.Telephony.SIM_FULL";
+ "android.provider.Telephony.SIM_FULL";
/**
* Broadcast Action: An incoming SMS has been rejected by the
@@ -1526,7 +1536,8 @@
* which streams the captured image to the uri. Internally we write the media content
* to this file. It's named '.temp.jpg' so Gallery won't pick it up.
*/
- public static final String SCRAP_FILE_PATH = "/sdcard/mms/scrapSpace/.temp.jpg";
+ public static final String SCRAP_FILE_PATH =
+ Environment.getExternalStorageDirectory().getPath() + "/mms/scrapSpace/.temp.jpg";
}
public static final class Intents {
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index e1d3f13..35a582d 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -30,6 +30,8 @@
import java.util.HashMap;
import java.util.Set;
+import android.os.PowerManager;
+
/**
* TODO: Move this to
@@ -51,6 +53,9 @@
private final BluetoothService mBluetoothService;
private final BluetoothAdapter mAdapter;
private final Context mContext;
+ // The WakeLock is used for bringing up the LCD during a pairing request
+ // from remote device when Android is in Suspend state.
+ private PowerManager.WakeLock mWakeLock;
private static final int EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 1;
private static final int EVENT_RESTART_BLUETOOTH = 2;
@@ -121,6 +126,11 @@
mContext = context;
mPasskeyAgentRequestData = new HashMap();
mAdapter = adapter;
+ //WakeLock instantiation in BluetoothEventLoop class
+ PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP
+ | PowerManager.ON_AFTER_RELEASE, TAG);
+ mWakeLock.setReferenceCounted(false);
initializeNativeDataNative();
}
@@ -458,37 +468,46 @@
mHandler.sendMessageDelayed(message, 1500);
return;
}
-
+ // Acquire wakelock during PIN code request to bring up LCD display
+ mWakeLock.acquire();
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_CONSENT);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+ // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+ mWakeLock.release();
return;
}
private void onRequestPasskeyConfirmation(String objectPath, int passkey, int nativeData) {
String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
if (address == null) return;
-
+ // Acquire wakelock during PIN code request to bring up LCD display
+ mWakeLock.acquire();
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
intent.putExtra(BluetoothDevice.EXTRA_PASSKEY, passkey);
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+ // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+ mWakeLock.release();
return;
}
private void onRequestPasskey(String objectPath, int nativeData) {
String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
if (address == null) return;
-
+ // Acquire wakelock during PIN code request to bring up LCD display
+ mWakeLock.acquire();
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_PASSKEY);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+ // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+ mWakeLock.release();
return;
}
@@ -526,10 +545,14 @@
}
}
}
+ // Acquire wakelock during PIN code request to bring up LCD display
+ mWakeLock.acquire();
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PIN);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+ // Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+ mWakeLock.release();
return;
}
@@ -537,12 +560,16 @@
String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
if (address == null) return;
+ // Acquire wakelock during PIN code request to bring up LCD display
+ mWakeLock.acquire();
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
intent.putExtra(BluetoothDevice.EXTRA_PASSKEY, passkey);
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+ //Release wakelock to allow the LCD to go off after the PIN popup notifcation.
+ mWakeLock.release();
}
private boolean onAgentAuthorize(String objectPath, String deviceUuid) {
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
old mode 100644
new mode 100755
index 38ac9b7..4e197cd
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -749,6 +749,9 @@
if (line == getLineCount() - 1)
max++;
+ if (line != getLineCount() - 1)
+ max = TextUtils.getOffsetBefore(mText, getLineEnd(line));
+
int best = min;
float bestdist = Math.abs(getPrimaryHorizontal(best) - horiz);
@@ -893,7 +896,7 @@
Directions dirs = getLineDirections(line);
if (line != getLineCount() - 1)
- end--;
+ end = TextUtils.getOffsetBefore(mText, end);
float horiz = getPrimaryHorizontal(offset);
@@ -993,7 +996,7 @@
Directions dirs = getLineDirections(line);
if (line != getLineCount() - 1)
- end--;
+ end = TextUtils.getOffsetBefore(mText, end);
float horiz = getPrimaryHorizontal(offset);
@@ -1564,7 +1567,8 @@
h = dir * nextTab(text, start, end, h * dir, tabs);
}
- if (bm != null) {
+ if (j != there && bm != null) {
+ if (offset == start + j) return h;
workPaint.set(paint);
Styled.measureText(paint, workPaint, text,
j, j + 2, null);
@@ -1958,4 +1962,3 @@
new Directions(new short[] { 0, 32767 });
}
-
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
old mode 100644
new mode 100755
index f02ad2a..d0d2482
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -313,7 +313,9 @@
class);
if (spanned == null) {
- paint.getTextWidths(sub, i, next, widths);
+ final int actualNum = paint.getTextWidths(sub, i, next, widths);
+ if (next - i > actualNum)
+ adjustTextWidths(widths, sub, i, next, actualNum);
System.arraycopy(widths, 0, widths,
end - start + (i - start), next - i);
@@ -321,9 +323,11 @@
} else {
mWorkPaint.baselineShift = 0;
- Styled.getTextWidths(paint, mWorkPaint,
- spanned, i, next,
- widths, fm);
+ final int actualNum = Styled.getTextWidths(paint, mWorkPaint,
+ spanned, i, next,
+ widths, fm);
+ if (next - i > actualNum)
+ adjustTextWidths(widths, spanned, i, next, actualNum);
System.arraycopy(widths, 0, widths,
end - start + (i - start), next - i);
@@ -966,6 +970,22 @@
return low;
}
+ private static void adjustTextWidths(float[] widths, CharSequence text,
+ int curPos, int nextPos, int actualNum) {
+ try {
+ int dstIndex = nextPos - curPos - 1;
+ for (int srcIndex = actualNum - 1; srcIndex >= 0; srcIndex--) {
+ final char c = text.charAt(dstIndex + curPos);
+ if (c >= 0xD800 && c <= 0xDFFF) {
+ widths[dstIndex--] = 0.0f;
+ }
+ widths[dstIndex--] = widths[srcIndex];
+ }
+ } catch (IndexOutOfBoundsException e) {
+ Log.e("text", "adjust text widths failed");
+ }
+ }
+
private int out(CharSequence text, int start, int end,
int above, int below, int top, int bottom, int v,
float spacingmult, float spacingadd,
diff --git a/core/java/android/text/Styled.java b/core/java/android/text/Styled.java
old mode 100644
new mode 100755
index 513b2cd..13cc42c
--- a/core/java/android/text/Styled.java
+++ b/core/java/android/text/Styled.java
@@ -203,9 +203,10 @@
}
}
+ int result;
if (replacement == null) {
workPaint.getFontMetricsInt(fmi);
- workPaint.getTextWidths(text, start, end, widths);
+ result = workPaint.getTextWidths(text, start, end, widths);
} else {
int wid = replacement.getSize(workPaint, text, start, end, fmi);
@@ -214,8 +215,9 @@
for (int i = start + 1; i < end; i++)
widths[i - start] = 0;
}
+ result = end - start;
}
- return end - start;
+ return result;
}
/**
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index dde0889..89b3cba 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -496,7 +496,7 @@
}
}
} else if (duration < WEEK_IN_MILLIS && minResolution < WEEK_IN_MILLIS) {
- count = duration / DAY_IN_MILLIS;
+ count = getNumberOfDaysPassed(time, now);
if (past) {
if (abbrevRelative) {
resId = com.android.internal.R.plurals.abbrev_num_days_ago;
@@ -521,6 +521,24 @@
}
/**
+ * Returns the number of days passed between two dates.
+ *
+ * @param date1 first date
+ * @param date2 second date
+ * @return number of days passed between to dates.
+ */
+ private synchronized static long getNumberOfDaysPassed(long date1, long date2) {
+ if (sThenTime == null) {
+ sThenTime = new Time();
+ }
+ sThenTime.set(date1);
+ int day1 = Time.getJulianDay(date1, sThenTime.gmtoff);
+ sThenTime.set(date2);
+ int day2 = Time.getJulianDay(date2, sThenTime.gmtoff);
+ return Math.abs(day2 - day1);
+ }
+
+ /**
* Return string describing the elapsed time since startTime formatted like
* "[relative time/date], [time]".
* <p>
@@ -1550,40 +1568,45 @@
public static CharSequence getRelativeTimeSpanString(Context c, long millis,
boolean withPreposition) {
+ String result;
long now = System.currentTimeMillis();
long span = now - millis;
- if (sNowTime == null) {
- sNowTime = new Time();
- sThenTime = new Time();
- }
+ synchronized (DateUtils.class) {
+ if (sNowTime == null) {
+ sNowTime = new Time();
+ }
- sNowTime.set(now);
- sThenTime.set(millis);
+ if (sThenTime == null) {
+ sThenTime = new Time();
+ }
- String result;
- int prepositionId;
- if (span < DAY_IN_MILLIS && sNowTime.weekDay == sThenTime.weekDay) {
- // Same day
- int flags = FORMAT_SHOW_TIME;
- result = formatDateRange(c, millis, millis, flags);
- prepositionId = R.string.preposition_for_time;
- } else if (sNowTime.year != sThenTime.year) {
- // Different years
- int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE;
- result = formatDateRange(c, millis, millis, flags);
+ sNowTime.set(now);
+ sThenTime.set(millis);
- // This is a date (like "10/31/2008" so use the date preposition)
- prepositionId = R.string.preposition_for_date;
- } else {
- // Default
- int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH;
- result = formatDateRange(c, millis, millis, flags);
- prepositionId = R.string.preposition_for_date;
- }
- if (withPreposition) {
- Resources res = c.getResources();
- result = res.getString(prepositionId, result);
+ int prepositionId;
+ if (span < DAY_IN_MILLIS && sNowTime.weekDay == sThenTime.weekDay) {
+ // Same day
+ int flags = FORMAT_SHOW_TIME;
+ result = formatDateRange(c, millis, millis, flags);
+ prepositionId = R.string.preposition_for_time;
+ } else if (sNowTime.year != sThenTime.year) {
+ // Different years
+ int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE;
+ result = formatDateRange(c, millis, millis, flags);
+
+ // This is a date (like "10/31/2008" so use the date preposition)
+ prepositionId = R.string.preposition_for_date;
+ } else {
+ // Default
+ int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH;
+ result = formatDateRange(c, millis, millis, flags);
+ prepositionId = R.string.preposition_for_date;
+ }
+ if (withPreposition) {
+ Resources res = c.getResources();
+ result = res.getString(prepositionId, result);
+ }
}
return result;
}
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index 8eae111..c05a8fe 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -32,7 +32,7 @@
private static final String Y_M_D_T_H_M_S_000 = "%Y-%m-%dT%H:%M:%S.000";
private static final String Y_M_D_T_H_M_S_000_Z = "%Y-%m-%dT%H:%M:%S.000Z";
private static final String Y_M_D = "%Y-%m-%d";
-
+
public static final String TIMEZONE_UTC = "UTC";
/**
@@ -170,11 +170,11 @@
public Time() {
this(TimeZone.getDefault().getID());
}
-
+
/**
* A copy constructor. Construct a Time object by copying the given
* Time object. No normalization occurs.
- *
+ *
* @param other
*/
public Time(Time other) {
@@ -185,17 +185,17 @@
* Ensures the values in each field are in range. For example if the
* current value of this calendar is March 32, normalize() will convert it
* to April 1. It also fills in weekDay, yearDay, isDst and gmtoff.
- *
+ *
* <p>
* If "ignoreDst" is true, then this method sets the "isDst" field to -1
* (the "unknown" value) before normalizing. It then computes the
* correct value for "isDst".
- *
+ *
* <p>
* See {@link #toMillis(boolean)} for more information about when to
* use <tt>true</tt> or <tt>false</tt> for "ignoreDst".
- *
- * @return the UTC milliseconds since the epoch
+ *
+ * @return the UTC milliseconds since the epoch
*/
native public long normalize(boolean ignoreDst);
@@ -379,13 +379,13 @@
* Parses a date-time string in either the RFC 2445 format or an abbreviated
* format that does not include the "time" field. For example, all of the
* following strings are valid:
- *
+ *
* <ul>
* <li>"20081013T160000Z"</li>
* <li>"20081013T160000"</li>
* <li>"20081013"</li>
* </ul>
- *
+ *
* Returns whether or not the time is in UTC (ends with Z). If the string
* ends with "Z" then the timezone is set to UTC. If the date-time string
* included only a date and no time field, then the <code>allDay</code>
@@ -396,10 +396,10 @@
* <code>yearDay</code>, and <code>gmtoff</code> are always set to zero,
* and the field <code>isDst</code> is set to -1 (unknown). To set those
* fields, call {@link #normalize(boolean)} after parsing.
- *
+ *
* To parse a date-time string and convert it to UTC milliseconds, do
* something like this:
- *
+ *
* <pre>
* Time time = new Time();
* String date = "20081013T160000Z";
@@ -428,25 +428,25 @@
* Parse a time in RFC 3339 format. This method also parses simple dates
* (that is, strings that contain no time or time offset). For example,
* all of the following strings are valid:
- *
+ *
* <ul>
* <li>"2008-10-13T16:00:00.000Z"</li>
* <li>"2008-10-13T16:00:00.000+07:00"</li>
* <li>"2008-10-13T16:00:00.000-07:00"</li>
* <li>"2008-10-13"</li>
* </ul>
- *
+ *
* <p>
* If the string contains a time and time offset, then the time offset will
* be used to convert the time value to UTC.
* </p>
- *
+ *
* <p>
* If the given string contains just a date (with no time field), then
* the {@link #allDay} field is set to true and the {@link #hour},
* {@link #minute}, and {@link #second} fields are set to zero.
* </p>
- *
+ *
* <p>
* Returns true if the resulting time value is in UTC time.
* </p>
@@ -462,7 +462,7 @@
}
return false;
}
-
+
native private boolean nativeParse3339(String s);
/**
@@ -484,13 +484,13 @@
* <em>not</em> change any of the fields in this Time object. If you want
* to normalize the fields in this Time object and also get the milliseconds
* then use {@link #normalize(boolean)}.
- *
+ *
* <p>
* If "ignoreDst" is false, then this method uses the current setting of the
* "isDst" field and will adjust the returned time if the "isDst" field is
* wrong for the given time. See the sample code below for an example of
* this.
- *
+ *
* <p>
* If "ignoreDst" is true, then this method ignores the current setting of
* the "isDst" field in this Time object and will instead figure out the
@@ -499,27 +499,27 @@
* correct value of the "isDst" field is when the time is inherently
* ambiguous because it falls in the hour that is repeated when switching
* from Daylight-Saving Time to Standard Time.
- *
+ *
* <p>
* Here is an example where <tt>toMillis(true)</tt> adjusts the time,
* assuming that DST changes at 2am on Sunday, Nov 4, 2007.
- *
+ *
* <pre>
* Time time = new Time();
- * time.set(2007, 10, 4); // set the date to Nov 4, 2007, 12am
+ * time.set(4, 10, 2007); // set the date to Nov 4, 2007, 12am
* time.normalize(); // this sets isDst = 1
* time.monthDay += 1; // changes the date to Nov 5, 2007, 12am
* millis = time.toMillis(false); // millis is Nov 4, 2007, 11pm
* millis = time.toMillis(true); // millis is Nov 5, 2007, 12am
* </pre>
- *
+ *
* <p>
* To avoid this problem, use <tt>toMillis(true)</tt>
* after adding or subtracting days or explicitly setting the "monthDay"
* field. On the other hand, if you are adding
* or subtracting hours or minutes, then you should use
* <tt>toMillis(false)</tt>.
- *
+ *
* <p>
* You should also use <tt>toMillis(false)</tt> if you want
* to read back the same milliseconds that you set with {@link #set(long)}
@@ -531,14 +531,14 @@
* Sets the fields in this Time object given the UTC milliseconds. After
* this method returns, all the fields are normalized.
* This also sets the "isDst" field to the correct value.
- *
+ *
* @param millis the time in UTC milliseconds since the epoch.
*/
native public void set(long millis);
/**
* Format according to RFC 2445 DATETIME type.
- *
+ *
* <p>
* The same as format("%Y%m%dT%H%M%S").
*/
@@ -584,7 +584,7 @@
* Sets the date from the given fields. Also sets allDay to true.
* Sets weekDay, yearDay and gmtoff to 0, and isDst to -1.
* Call {@link #normalize(boolean)} if you need those.
- *
+ *
* @param monthDay the day of the month (in the range [1,31])
* @param month the zero-based month number (in the range [0,11])
* @param year the year
@@ -606,7 +606,7 @@
/**
* Returns true if the time represented by this Time object occurs before
* the given time.
- *
+ *
* @param that a given Time object to compare against
* @return true if this time is less than the given time
*/
@@ -618,7 +618,7 @@
/**
* Returns true if the time represented by this Time object occurs after
* the given time.
- *
+ *
* @param that a given Time object to compare against
* @return true if this time is greater than the given time
*/
@@ -632,12 +632,12 @@
* closest Thursday yearDay.
*/
private static final int[] sThursdayOffset = { -3, 3, 2, 1, 0, -1, -2 };
-
+
/**
* Computes the week number according to ISO 8601. The current Time
* object must already be normalized because this method uses the
* yearDay and weekDay fields.
- *
+ *
* <p>
* In IS0 8601, weeks start on Monday.
* The first week of the year (week 1) is defined by ISO 8601 as the
@@ -645,12 +645,12 @@
* Or equivalently, the week containing January 4. Or equivalently,
* the week with the year's first Thursday in it.
* </p>
- *
+ *
* <p>
* The week number can be calculated by counting Thursdays. Week N
* contains the Nth Thursday of the year.
* </p>
- *
+ *
* @return the ISO week number.
*/
public int getWeekNumber() {
@@ -661,7 +661,7 @@
if (closestThursday >= 0 && closestThursday <= 364) {
return closestThursday / 7 + 1;
}
-
+
// The week crosses a year boundary.
Time temp = new Time(this);
temp.monthDay += sThursdayOffset[weekDay];
@@ -670,7 +670,7 @@
}
/**
- * Return a string in the RFC 3339 format.
+ * Return a string in the RFC 3339 format.
* <p>
* If allDay is true, expresses the time as Y-M-D</p>
* <p>
@@ -691,13 +691,13 @@
int offset = (int)Math.abs(gmtoff);
int minutes = (offset % 3600) / 60;
int hours = offset / 3600;
-
+
return String.format("%s%s%02d:%02d", base, sign, hours, minutes);
}
}
-
+
/**
- * Returns true if the day of the given time is the epoch on the Julian Calendar
+ * Returns true if the day of the given time is the epoch on the Julian Calendar
* (January 1, 1970 on the Gregorian calendar).
*
* @param time the time to test
@@ -707,7 +707,7 @@
long millis = time.toMillis(true);
return getJulianDay(millis, 0) == EPOCH_JULIAN_DAY;
}
-
+
/**
* Computes the Julian day number, given the UTC milliseconds
* and the offset (in seconds) from UTC. The Julian day for a given
@@ -716,10 +716,10 @@
* what timezone is being used. The Julian day is useful for testing
* if two events occur on the same day and for determining the relative
* time of an event from the present ("yesterday", "3 days ago", etc.).
- *
+ *
* <p>
* Use {@link #toMillis(boolean)} to get the milliseconds.
- *
+ *
* @param millis the time in UTC milliseconds
* @param gmtoff the offset from UTC in seconds
* @return the Julian day
@@ -729,7 +729,7 @@
long julianDay = (millis + offsetMillis) / DateUtils.DAY_IN_MILLIS;
return (int) julianDay + EPOCH_JULIAN_DAY;
}
-
+
/**
* <p>Sets the time from the given Julian day number, which must be based on
* the same timezone that is set in this Time object. The "gmtoff" field
@@ -738,7 +738,7 @@
* After this method returns all the fields will be normalized and the time
* will be set to 12am at the beginning of the given Julian day.
* </p>
- *
+ *
* <p>
* The only exception to this is if 12am does not exist for that day because
* of daylight saving time. For example, Cairo, Eqypt moves time ahead one
@@ -746,7 +746,7 @@
* also change daylight saving time at 12am. In those cases, the time
* will be set to 1am.
* </p>
- *
+ *
* @param julianDay the Julian day in the timezone for this Time object
* @return the UTC milliseconds for the beginning of the Julian day
*/
@@ -756,13 +756,13 @@
// the day.
long millis = (julianDay - EPOCH_JULIAN_DAY) * DateUtils.DAY_IN_MILLIS;
set(millis);
-
+
// Figure out how close we are to the requested Julian day.
// We can't be off by more than a day.
int approximateDay = getJulianDay(millis, gmtoff);
int diff = julianDay - approximateDay;
monthDay += diff;
-
+
// Set the time to 12am and re-normalize.
hour = 0;
minute = 0;
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 219a469..a2c80f2 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -785,11 +785,7 @@
* @return The BrowserFrame object stored in the new WebView.
*/
private BrowserFrame createWindow(boolean dialog, boolean userGesture) {
- WebView w = mCallbackProxy.createWindow(dialog, userGesture);
- if (w != null) {
- return w.getWebViewCore().getBrowserFrame();
- }
- return null;
+ return mCallbackProxy.createWindow(dialog, userGesture);
}
/**
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 0e0e032..d65c106 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -1098,7 +1098,7 @@
}
}
- public WebView createWindow(boolean dialog, boolean userGesture) {
+ public BrowserFrame createWindow(boolean dialog, boolean userGesture) {
// Do an unsynchronized quick check to avoid posting if no callback has
// been set.
if (mWebChromeClient == null) {
@@ -1122,9 +1122,15 @@
WebView w = transport.getWebView();
if (w != null) {
- w.getWebViewCore().initializeSubwindow();
+ WebViewCore core = w.getWebViewCore();
+ // If WebView.destroy() has been called, core may be null. Skip
+ // initialization in that case and return null.
+ if (core != null) {
+ core.initializeSubwindow();
+ return core.getBrowserFrame();
+ }
}
- return w;
+ return null;
}
public void onRequestFocus() {
diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java
index ca9ad53..c1ac180 100644
--- a/core/java/android/webkit/MimeTypeMap.java
+++ b/core/java/android/webkit/MimeTypeMap.java
@@ -369,10 +369,13 @@
sMimeTypeMap.loadEntry("application/x-xfig", "fig");
sMimeTypeMap.loadEntry("application/xhtml+xml", "xhtml");
sMimeTypeMap.loadEntry("audio/3gpp", "3gpp");
+ sMimeTypeMap.loadEntry("audio/amr", "amr");
sMimeTypeMap.loadEntry("audio/basic", "snd");
sMimeTypeMap.loadEntry("audio/midi", "mid");
sMimeTypeMap.loadEntry("audio/midi", "midi");
sMimeTypeMap.loadEntry("audio/midi", "kar");
+ sMimeTypeMap.loadEntry("audio/midi", "xmf");
+ sMimeTypeMap.loadEntry("audio/mobile-xmf", "mxmf");
sMimeTypeMap.loadEntry("audio/mpeg", "mpga");
sMimeTypeMap.loadEntry("audio/mpeg", "mpega");
sMimeTypeMap.loadEntry("audio/mpeg", "mp2");
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index c01068f..bf528e0 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4089,6 +4089,16 @@
}
}
+ if (keyCode == KeyEvent.KEYCODE_PAGE_UP) {
+ pageUp(false);
+ return true;
+ }
+
+ if (keyCode == KeyEvent.KEYCODE_PAGE_DOWN) {
+ pageDown(false);
+ return true;
+ }
+
if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
&& keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
switchOutDrawHistory();
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index 32e5504..03ada94 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -24,6 +24,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.Comparator;
import java.util.Collections;
@@ -83,7 +84,7 @@
*/
private boolean mNotifyOnChange = true;
- private Context mContext;
+ private Context mContext;
private ArrayList<T> mOriginalValues;
private ArrayFilter mFilter;
@@ -181,6 +182,44 @@
}
/**
+ * Adds the specified Collection at the end of the array.
+ *
+ * @param collection The Collection to add at the end of the array.
+ */
+ public void addAll(Collection<? extends T> collection) {
+ if (mOriginalValues != null) {
+ synchronized (mLock) {
+ mOriginalValues.addAll(collection);
+ if (mNotifyOnChange) notifyDataSetChanged();
+ }
+ } else {
+ mObjects.addAll(collection);
+ if (mNotifyOnChange) notifyDataSetChanged();
+ }
+ }
+
+ /**
+ * Adds the specified items at the end of the array.
+ *
+ * @param items The items to add at the end of the array.
+ */
+ public void addAll(T ... items) {
+ if (mOriginalValues != null) {
+ synchronized (mLock) {
+ for (T item : items) {
+ mOriginalValues.add(item);
+ }
+ if (mNotifyOnChange) notifyDataSetChanged();
+ }
+ } else {
+ for (T item : items) {
+ mObjects.add(item);
+ }
+ if (mNotifyOnChange) notifyDataSetChanged();
+ }
+ }
+
+ /**
* Inserts the specified object at the specified index in the array.
*
* @param object The object to insert into the array.
@@ -236,7 +275,7 @@
*/
public void sort(Comparator<? super T> comparator) {
Collections.sort(mObjects, comparator);
- if (mNotifyOnChange) notifyDataSetChanged();
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 1e8023c..93f64b4 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4558,6 +4558,9 @@
partialStartOffset = 0;
partialEndOffset = N;
} else {
+ // Now use the delta to determine the actual amount of text
+ // we need.
+ partialEndOffset += delta;
// Adjust offsets to ensure we contain full spans.
if (content instanceof Spanned) {
Spanned spanned = (Spanned)content;
@@ -4573,10 +4576,8 @@
}
}
outText.partialStartOffset = partialStartOffset;
- outText.partialEndOffset = partialEndOffset;
- // Now use the delta to determine the actual amount of text
- // we need.
- partialEndOffset += delta;
+ outText.partialEndOffset = partialEndOffset - delta;
+
if (partialStartOffset > N) {
partialStartOffset = N;
} else if (partialStartOffset < 0) {
@@ -4640,6 +4641,10 @@
+ ": " + ims.mTmpExtracted.text);
imm.updateExtractedText(this, req.token,
mInputMethodState.mTmpExtracted);
+ ims.mChangedStart = EXTRACT_UNKNOWN;
+ ims.mChangedEnd = EXTRACT_UNKNOWN;
+ ims.mChangedDelta = 0;
+ ims.mContentChanged = false;
return true;
}
}
@@ -6227,8 +6232,8 @@
ims.mChangedStart = start;
ims.mChangedEnd = start+before;
} else {
- if (ims.mChangedStart > start) ims.mChangedStart = start;
- if (ims.mChangedEnd < (start+before)) ims.mChangedEnd = start+before;
+ ims.mChangedStart = Math.min(ims.mChangedStart, start);
+ ims.mChangedEnd = Math.max(ims.mChangedEnd, start + before - ims.mChangedDelta);
}
ims.mChangedDelta += after-before;
}
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 107b145..4a0617c 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -435,6 +435,7 @@
View titleTemplate = mWindow.findViewById(R.id.title_template);
titleTemplate.setVisibility(View.GONE);
mIconView.setVisibility(View.GONE);
+ topPanel.setVisibility(View.GONE);
hasTitle = false;
}
}
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index d1aff2a..e07c54f 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -134,7 +134,7 @@
private static void beginShutdownSequence(Context context) {
synchronized (sIsStartedGuard) {
if (sIsStarted) {
- Log.d(TAG, "Request to shutdown already running, returning.");
+ Log.d(TAG, "Shutdown sequence already running, returning.");
return;
}
sIsStarted = true;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f4447ab..0a1c8ff 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -917,7 +917,7 @@
private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
- byte[] buffer = new byte[4096];
+ byte[] buffer = new byte[8192];
int len;
try {
@@ -964,9 +964,11 @@
for (endIndex=startIndex;
endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
endIndex++);
- // Don't go over the end of the buffer
- if (endIndex < len) {
- endIndex++; // endIndex is an exclusive upper bound.
+ endIndex++; // endIndex is an exclusive upper bound.
+ // Don't go over the end of the buffer, Process.parseProcLine might
+ // write to wlBuffer[endIndex]
+ if (endIndex >= (len - 1) ) {
+ return m;
}
String[] nameStringArray = mProcWakelocksName;
diff --git a/core/java/com/android/internal/os/SamplingProfilerIntegration.java b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
index a3efbc8..ea278a6 100644
--- a/core/java/com/android/internal/os/SamplingProfilerIntegration.java
+++ b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
@@ -96,7 +96,8 @@
pending = true;
snapshotWriter.execute(new Runnable() {
public void run() {
- String dir = "/sdcard/snapshots";
+ String dir =
+ Environment.getExternalStorageDirectory().getPath() + "/snapshots";
if (!dirMade) {
new File(dir).mkdirs();
if (new File(dir).isDirectory()) {
diff --git a/core/java/com/google/android/mms/pdu/PduParser.java b/core/java/com/google/android/mms/pdu/PduParser.java
index 21f0c93..8edfe52 100644
--- a/core/java/com/google/android/mms/pdu/PduParser.java
+++ b/core/java/com/google/android/mms/pdu/PduParser.java
@@ -163,6 +163,13 @@
// or "application/vnd.wap.multipart.related"
// or "application/vnd.wap.multipart.alternative"
return retrieveConf;
+ } else if (ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) {
+ // "application/vnd.wap.multipart.alternative"
+ // should take only the first part.
+ PduPart firstPart = mBody.getPart(0);
+ mBody.removeAll();
+ mBody.addPart(0, firstPart);
+ return retrieveConf;
}
return null;
case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index feb0dad..6575b9a 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -25,9 +25,8 @@
extern "C" {
int ifc_enable(const char *ifname);
int ifc_disable(const char *ifname);
-int ifc_add_host_route(const char *ifname, uint32_t addr);
+int ifc_add_route(const char *ifname, const char *destStr, uint32_t prefixLen, const char *gwStr);
int ifc_remove_host_routes(const char *ifname);
-int ifc_set_default_route(const char *ifname, uint32_t gateway);
int ifc_get_default_route(const char *ifname);
int ifc_remove_default_route(const char *ifname);
int ifc_reset_connections(const char *ifname);
@@ -87,13 +86,23 @@
return (jint)result;
}
-static jint android_net_utils_addHostRoute(JNIEnv* env, jobject clazz, jstring ifname, jint addr)
+static jint android_net_utils_addRoute(JNIEnv* env, jobject clazz, jstring ifname,
+ jstring dst, jint prefixLength, jstring gw)
{
int result;
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
- result = ::ifc_add_host_route(nameStr, addr);
+ const char *dstStr = env->GetStringUTFChars(dst, NULL);
+ const char *gwStr = NULL;
+ if (gw != NULL) {
+ gwStr = env->GetStringUTFChars(gw, NULL);
+ }
+ result = ::ifc_add_route(nameStr, dstStr, prefixLength, gwStr);
env->ReleaseStringUTFChars(ifname, nameStr);
+ env->ReleaseStringUTFChars(dst, dstStr);
+ if (gw != NULL) {
+ env->ReleaseStringUTFChars(gw, gwStr);
+ }
return (jint)result;
}
@@ -107,16 +116,6 @@
return (jint)result;
}
-static jint android_net_utils_setDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname, jint gateway)
-{
- int result;
-
- const char *nameStr = env->GetStringUTFChars(ifname, NULL);
- result = ::ifc_set_default_route(nameStr, gateway);
- env->ReleaseStringUTFChars(ifname, nameStr);
- return (jint)result;
-}
-
static jint android_net_utils_getDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname)
{
int result;
@@ -222,9 +221,9 @@
{ "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface },
{ "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
- { "addHostRoute", "(Ljava/lang/String;I)I", (void *)android_net_utils_addHostRoute },
+ { "addRoute", "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)I",
+ (void *)android_net_utils_addRoute },
{ "removeHostRoutes", "(Ljava/lang/String;)I", (void *)android_net_utils_removeHostRoutes },
- { "setDefaultRoute", "(Ljava/lang/String;I)I", (void *)android_net_utils_setDefaultRoute },
{ "getDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_getDefaultRoute },
{ "removeDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_removeDefaultRoute },
{ "resetConnections", "(Ljava/lang/String;)I", (void *)android_net_utils_resetConnections },
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d565c68..800ed13 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -255,6 +255,21 @@
<!-- Default LED off time for notification LED in milliseconds. -->
<integer name="config_defaultNotificationLedOff">2000</integer>
+ <!-- Default value for led color when battery is low on charge -->
+ <integer name="config_notificationsBatteryLowARGB">0xFFFF0000</integer>
+
+ <!-- Default value for led color when battery is medium charged -->
+ <integer name="config_notificationsBatteryMediumARGB">0xFFFFFF00</integer>
+
+ <!-- Default value for led color when battery is fully charged -->
+ <integer name="config_notificationsBatteryFullARGB">0xFF00FF00</integer>
+
+ <!-- Default value for LED on time when the battery is low on charge in miliseconds -->
+ <integer name="config_notificationsBatteryLedOn">125</integer>
+
+ <!-- Default value for LED off time when the battery is low on charge in miliseconds -->
+ <integer name="config_notificationsBatteryLedOff">2875</integer>
+
<!-- Allow the menu hard key to be disabled in LockScreen on some devices -->
<bool name="config_disableMenuKeyInLockScreen">false</bool>
diff --git a/core/tests/coretests/src/android/preference/ListPreferenceTest.java b/core/tests/coretests/src/android/preference/ListPreferenceTest.java
new file mode 100644
index 0000000..41f8e03
--- /dev/null
+++ b/core/tests/coretests/src/android/preference/ListPreferenceTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.preference;
+
+import android.preference.ListPreference;
+import android.test.AndroidTestCase;
+
+public class ListPreferenceTest extends AndroidTestCase {
+ public void testListPreferenceSummaryFromEntries() {
+ String[] entries = { "one", "two", "three" };
+ String[] entryValues = { "1" , "2", "3" };
+ ListPreference lp = new ListPreference(getContext());
+ lp.setEntries(entries);
+ lp.setEntryValues(entryValues);
+
+ lp.setValue(entryValues[1]);
+ assertTrue(lp.getSummary() == null);
+
+ lp.setSummary("%1$s");
+ assertEquals(entries[1], lp.getSummary());
+
+ lp.setValue(entryValues[2]);
+ assertEquals(entries[2], lp.getSummary());
+
+ lp.setSummary(null);
+ assertTrue(lp.getSummary() == null);
+
+ lp.setSummary("The color is %1$s");
+ assertEquals("The color is " + entries[2], lp.getSummary());
+ }
+}
diff --git a/core/tests/hosttests/Android.mk b/core/tests/hosttests/Android.mk
index 0001201..07d99cb 100644
--- a/core/tests/hosttests/Android.mk
+++ b/core/tests/hosttests/Android.mk
@@ -23,7 +23,7 @@
LOCAL_MODULE := FrameworkCoreHostTests
-LOCAL_JAVA_LIBRARIES := hosttestlib ddmlib junit
+LOCAL_JAVA_LIBRARIES := hosttestlib ddmlib-prebuilt junit
include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java
index 91cbe2f..b225c37 100644
--- a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java
+++ b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java
@@ -16,32 +16,32 @@
package android.content.pm;
+import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.InstallException;
import com.android.ddmlib.Log;
import com.android.ddmlib.MultiLineReceiver;
-import com.android.ddmlib.SyncService;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.SyncException;
+import com.android.ddmlib.TimeoutException;
import com.android.ddmlib.SyncService.ISyncProgressMonitor;
-import com.android.ddmlib.SyncService.SyncResult;
import com.android.ddmlib.testrunner.ITestRunListener;
import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
import com.android.ddmlib.testrunner.TestIdentifier;
-import com.android.hosttest.DeviceTestCase;
-import com.android.hosttest.DeviceTestSuite;
import java.io.BufferedReader;
-import java.io.File;
-import java.io.InputStreamReader;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.StringReader;
import java.lang.Runtime;
import java.lang.Process;
+import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import junit.framework.Assert;
-import com.android.hosttest.DeviceTestCase;
/**
* Set of tests that verify host side install cases
@@ -119,8 +119,14 @@
* Helper method to run tests and return the listener that collected the results.
* @param pkgName Android application package for tests
* @return the {@link CollectingTestRunListener}
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- private CollectingTestRunListener doRunTests(String pkgName) throws IOException {
+ private CollectingTestRunListener doRunTests(String pkgName) throws IOException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
pkgName, mDevice);
CollectingTestRunListener listener = new CollectingTestRunListener();
@@ -133,8 +139,14 @@
*
* @param pkgName Android application package for tests
* @return true if every test passed, false otherwise.
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public boolean runDeviceTestsDidAllTestsPass(String pkgName) throws IOException {
+ public boolean runDeviceTestsDidAllTestsPass(String pkgName) throws IOException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
CollectingTestRunListener listener = doRunTests(pkgName);
return listener.didAllTestsPass();
}
@@ -142,22 +154,26 @@
/**
* Helper method to push a file to device
* @param apkAppPrivatePath
- * @throws IOException
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws IOException if connection to device was lost.
+ * @throws SyncException if the sync failed for another reason.
*/
public void pushFile(final String localFilePath, final String destFilePath)
- throws IOException {
- SyncResult result = mDevice.getSyncService().pushFile(
- localFilePath, destFilePath, new NullSyncProgressMonitor());
- assertEquals(SyncService.RESULT_OK, result.getCode());
+ throws IOException, SyncException, TimeoutException, AdbCommandRejectedException {
+ mDevice.getSyncService().pushFile(localFilePath,
+ destFilePath, new NullSyncProgressMonitor());
}
/**
* Helper method to install a file
* @param localFilePath the absolute file system path to file on local host to install
* @param reinstall set to <code>true</code> if re-install of app should be performed
- * @throws IOException
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed
*/
- public void installFile(final String localFilePath, final boolean replace) throws IOException {
+ public void installFile(final String localFilePath, final boolean replace) throws IOException,
+ InstallException {
String result = mDevice.installPackage(localFilePath, replace);
assertEquals(null, result);
}
@@ -167,10 +183,11 @@
* @param localFilePath the absolute file system path to file on local host to install
* @param reinstall set to <code>true</code> if re-install of app should be performed
* @return the string output of the failed install attempt
- * @throws IOException
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed
*/
public String installFileFail(final String localFilePath, final boolean replace)
- throws IOException {
+ throws IOException, InstallException {
String result = mDevice.installPackage(localFilePath, replace);
assertNotNull(result);
return result;
@@ -180,10 +197,17 @@
* Helper method to install a file to device as forward locked
* @param localFilePath the absolute file system path to file on local host to install
* @param reinstall set to <code>true</code> if re-install of app should be performed
- * @throws IOException
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws SyncException if the sync failed for another reason.
+ * @throws InstallException if the install failed.
*/
public String installFileForwardLocked(final String localFilePath, final boolean replace)
- throws IOException {
+ throws IOException, SyncException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException, InstallException {
String remoteFilePath = mDevice.syncPackageToDevice(localFilePath);
InstallReceiver receiver = new InstallReceiver();
String cmd = String.format(replace ? "pm install -r -l \"%1$s\"" :
@@ -198,9 +222,14 @@
*
* @param destPath the absolute path of file on device to check
* @return <code>true</code> if file exists, <code>false</code> otherwise.
- * @throws IOException if adb shell command failed
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public boolean doesRemoteFileExist(String destPath) throws IOException {
+ public boolean doesRemoteFileExist(String destPath) throws IOException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
String lsGrep = executeShellCommand(String.format("ls %s", destPath));
return !lsGrep.contains("No such file or directory");
}
@@ -211,10 +240,15 @@
* @param destPath the absolute path of the file
* @return <code>true</code> if file exists containing given string,
* <code>false</code> otherwise.
- * @throws IOException if adb shell command failed
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
public boolean doesRemoteFileExistContainingString(String destPath, String searchString)
- throws IOException {
+ throws IOException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
String lsResult = executeShellCommand(String.format("ls %s", destPath));
return lsResult.contains(searchString);
}
@@ -224,9 +258,14 @@
*
* @param packageName the Android manifest package to check.
* @return <code>true</code> if package exists, <code>false</code> otherwise
- * @throws IOException if adb shell command failed
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public boolean doesPackageExist(String packageName) throws IOException {
+ public boolean doesPackageExist(String packageName) throws IOException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
String pkgGrep = executeShellCommand(String.format("pm path %s", packageName));
return pkgGrep.contains("package:");
}
@@ -236,9 +275,14 @@
*
* @param packageName package name to check for
* @return <code>true</code> if file exists, <code>false</code> otherwise.
- * @throws IOException if adb shell command failed
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public boolean doesAppExistOnDevice(String packageName) throws IOException {
+ public boolean doesAppExistOnDevice(String packageName) throws IOException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
return doesRemoteFileExistContainingString(DEVICE_APP_PATH, packageName);
}
@@ -247,9 +291,14 @@
*
* @param packageName package name to check for
* @return <code>true</code> if file exists, <code>false</code> otherwise.
- * @throws IOException if adb shell command failed
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public boolean doesAppExistOnSDCard(String packageName) throws IOException {
+ public boolean doesAppExistOnSDCard(String packageName) throws IOException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
return doesRemoteFileExistContainingString(SDCARD_APP_PATH, packageName);
}
@@ -258,9 +307,14 @@
*
* @param packageName package name to check for
* @return <code>true</code> if file exists, <code>false</code> otherwise.
- * @throws IOException if adb shell command failed
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public boolean doesAppExistAsForwardLocked(String packageName) throws IOException {
+ public boolean doesAppExistAsForwardLocked(String packageName) throws IOException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
return doesRemoteFileExistContainingString(APP_PRIVATE_PATH, packageName);
}
@@ -268,9 +322,14 @@
* Waits for device's package manager to respond.
*
* @throws InterruptedException
- * @throws IOException
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public void waitForPackageManager() throws InterruptedException, IOException {
+ public void waitForPackageManager() throws InterruptedException, IOException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "waiting for device");
int currentWaitTime = 0;
// poll the package manager until it returns something for android
@@ -336,9 +395,14 @@
*
* @param packageName The name of the package to wait to load
* @throws InterruptedException
- * @throws IOException
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public void waitForApp(String packageName) throws InterruptedException, IOException {
+ public void waitForApp(String packageName) throws InterruptedException, IOException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "waiting for app to launch");
int currentWaitTime = 0;
// poll the package manager until it returns something for the package we're looking for
@@ -355,9 +419,14 @@
/**
* Helper method which executes a adb shell command and returns output as a {@link String}
* @return the output of the command
- * @throws IOException
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public String executeShellCommand(String command) throws IOException {
+ public String executeShellCommand(String command) throws IOException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, String.format("adb shell %s", command));
CollectingOutputReceiver receiver = new CollectingOutputReceiver();
mDevice.executeShellCommand(command, receiver);
@@ -369,9 +438,14 @@
/**
* Helper method ensures we are in root mode on the host side. It returns only after
* PackageManager is actually up and running.
- * @throws IOException
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public void runAdbRoot() throws IOException, InterruptedException {
+ public void runAdbRoot() throws IOException, InterruptedException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "adb root");
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("adb root"); // adb should be in the path
@@ -389,10 +463,15 @@
/**
* Helper method which reboots the device and returns once the device is online again
* and package manager is up and running (note this function is synchronous to callers).
- * @throws IOException
* @throws InterruptedException
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public void rebootDevice() throws IOException, InterruptedException {
+ public void rebootDevice() throws IOException, InterruptedException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
String command = "reboot"; // no need for -s since mDevice is already tied to a device
Log.i(LOG_TAG, command);
CollectingOutputReceiver receiver = new CollectingOutputReceiver();
@@ -468,7 +547,7 @@
mAllTestsPassed = false;
}
- public void testRunEnded(long elapsedTime) {
+ public void testRunEnded(long elapsedTime, Map<String, String> resultBundle) {
// ignore
}
@@ -545,17 +624,23 @@
/**
* Helper method for installing an app to wherever is specified in its manifest, and
* then verifying the app was installed onto SD Card.
+ * <p/>
+ * Assumes adb is running as root in device under test.
*
* @param the path of the apk to install
* @param the name of the package
* @param <code>true</code> if the app should be overwritten, <code>false</code> otherwise
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
- * <p/>
- * Assumes adb is running as root in device under test.
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
public void installAppAndVerifyExistsOnSDCard(String apkPath, String pkgName, boolean overwrite)
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
// Start with a clean slate if we're not overwriting
if (!overwrite) {
// cleanup test app just in case it already exists
@@ -576,17 +661,23 @@
/**
* Helper method for installing an app to wherever is specified in its manifest, and
* then verifying the app was installed onto device.
+ * <p/>
+ * Assumes adb is running as root in device under test.
*
* @param the path of the apk to install
* @param the name of the package
* @param <code>true</code> if the app should be overwritten, <code>false</code> otherwise
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
- * <p/>
- * Assumes adb is running as root in device under test.
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
public void installAppAndVerifyExistsOnDevice(String apkPath, String pkgName, boolean overwrite)
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
// Start with a clean slate if we're not overwriting
if (!overwrite) {
// cleanup test app just in case it already exists
@@ -607,17 +698,24 @@
/**
* Helper method for installing an app as forward-locked, and
* then verifying the app was installed in the proper forward-locked location.
+ * <p/>
+ * Assumes adb is running as root in device under test.
*
* @param the path of the apk to install
* @param the name of the package
* @param <code>true</code> if the app should be overwritten, <code>false</code> otherwise
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
- * <p/>
- * Assumes adb is running as root in device under test.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
*/
public void installFwdLockedAppAndVerifyExists(String apkPath,
- String pkgName, boolean overwrite) throws IOException, InterruptedException {
+ String pkgName, boolean overwrite) throws IOException, InterruptedException,
+ InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
// Start with a clean slate if we're not overwriting
if (!overwrite) {
// cleanup test app just in case it already exists
@@ -638,14 +736,21 @@
/**
* Helper method for uninstalling an app.
- *
- * @param pkgName package name to uninstall
- * @throws IOException if adb shell command failed
- * @throws InterruptedException if the thread was interrupted
* <p/>
* Assumes adb is running as root in device under test.
+ *
+ * @param pkgName package name to uninstall
+ * @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the uninstall failed.
*/
- public void uninstallApp(String pkgName) throws IOException, InterruptedException {
+ public void uninstallApp(String pkgName) throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
mDevice.uninstallPackage(pkgName);
// make sure its not installed anymore
assertFalse(doesPackageExist(pkgName));
@@ -655,12 +760,18 @@
* Helper method for clearing any installed non-system apps.
* Useful ensuring no non-system apps are installed, and for cleaning up stale files that
* may be lingering on the system for whatever reason.
- *
- * @throws IOException if adb shell command failed
* <p/>
* Assumes adb is running as root in device under test.
+ *
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the uninstall failed.
*/
- public void wipeNonSystemApps() throws IOException {
+ public void wipeNonSystemApps() throws IOException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException, InstallException {
String allInstalledPackages = executeShellCommand("pm list packages -f");
BufferedReader outputReader = new BufferedReader(new StringReader(allInstalledPackages));
@@ -685,8 +796,14 @@
*
* <p/>
* Assumes adb is running as root in device under test.
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public void setDevicePreferredInstallLocation(InstallLocPreference pref) throws IOException {
+ public void setDevicePreferredInstallLocation(InstallLocPreference pref) throws IOException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
String command = "pm setInstallLocation %d";
int locValue = 0;
switch (pref) {
@@ -708,8 +825,14 @@
*
* <p/>
* Assumes adb is running as root in device under test.
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
*/
- public InstallLocPreference getDevicePreferredInstallLocation() throws IOException {
+ public InstallLocPreference getDevicePreferredInstallLocation() throws IOException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
String result = executeShellCommand("pm getInstallLocation");
if (result.indexOf('0') != -1) {
return InstallLocPreference.AUTO;
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
index 1b797d5..22a2be6 100644
--- a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
+++ b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
@@ -16,13 +16,12 @@
package android.content.pm;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.AdbCommandRejectedException;
+import com.android.ddmlib.InstallException;
import com.android.ddmlib.Log;
-import com.android.ddmlib.MultiLineReceiver;
-import com.android.ddmlib.SyncService;
-import com.android.ddmlib.SyncService.ISyncProgressMonitor;
-import com.android.ddmlib.SyncService.SyncResult;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.SyncException;
+import com.android.ddmlib.TimeoutException;
import com.android.hosttest.DeviceTestCase;
import com.android.hosttest.DeviceTestSuite;
@@ -156,10 +155,18 @@
* the app, and otherwise cause the system to blow up.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws SyncException if the sync failed for another reason.
+ * @throws InstallException if the install failed.
*/
- public void testPushAppPrivate() throws IOException, InterruptedException {
+ public void testPushAppPrivate() throws IOException, InterruptedException, InstallException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
+ SyncException {
Log.i(LOG_TAG, "testing pushing an apk to /data/app-private");
final String apkAppPrivatePath = appPrivatePath + SIMPLE_APK;
@@ -187,12 +194,18 @@
* @param apkName the file name of the test app apk
* @param pkgName the package name of the test app apk
* @param expectedLocation the file name of the test app apk
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
private void doStandardInstall(String apkName, String pkgName,
PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
if (expectedLocation == PackageManagerHostTestUtils.InstallLocation.DEVICE) {
mPMHostUtils.installAppAndVerifyExistsOnDevice(
@@ -211,12 +224,18 @@
* Assumes adb is running as root in device under test.
* @param preference the device's preferred location of where to install apps
* @param expectedLocation the expected location of where the apk was installed
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
public void installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference preference,
PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException, InstallException {
PackageManagerHostTestUtils.InstallLocPreference savedPref =
PackageManagerHostTestUtils.InstallLocPreference.AUTO;
@@ -239,10 +258,16 @@
* will install the app to the device when device's preference is auto.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppAutoLocPrefIsAuto() throws IOException, InterruptedException {
+ public void testInstallAppAutoLocPrefIsAuto() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installLocation=auto, prefer=auto gets installed on device");
installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference.AUTO,
PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -253,10 +278,17 @@
* will install the app to the device when device's preference is internal.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppAutoLocPrefIsInternal() throws IOException, InterruptedException {
+ public void testInstallAppAutoLocPrefIsInternal() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installLocation=auto, prefer=internal gets installed on device");
installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference.INTERNAL,
PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -267,10 +299,17 @@
* will install the app to the SD card when device's preference is external.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppAutoLocPrefIsExternal() throws IOException, InterruptedException {
+ public void testInstallAppAutoLocPrefIsExternal() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installLocation=auto, prefer=external gets installed on device");
installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference.EXTERNAL,
PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -283,12 +322,18 @@
* Assumes adb is running as root in device under test.
* @param preference the device's preferred location of where to install apps
* @param expectedLocation the expected location of where the apk was installed
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the (un)install failed.
*/
public void installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference preference,
PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException, InstallException {
PackageManagerHostTestUtils.InstallLocPreference savedPref =
PackageManagerHostTestUtils.InstallLocPreference.AUTO;
@@ -311,10 +356,17 @@
* will install the app to the device when device's preference is auto.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppInternalLocPrefIsAuto() throws IOException, InterruptedException {
+ public void testInstallAppInternalLocPrefIsAuto() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installLocation=internal, prefer=auto gets installed on device");
installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference.AUTO,
PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -325,10 +377,17 @@
* will install the app to the device when device's preference is internal.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppInternalLocPrefIsInternal() throws IOException, InterruptedException {
+ public void testInstallAppInternalLocPrefIsInternal() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installLocation=internal, prefer=internal is installed on device");
installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference.INTERNAL,
PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -339,10 +398,17 @@
* will install the app to the device when device's preference is external.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppInternalLocPrefIsExternal() throws IOException, InterruptedException {
+ public void testInstallAppInternalLocPrefIsExternal() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installLocation=internal, prefer=external is installed on device");
installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference.EXTERNAL,
PackageManagerHostTestUtils.InstallLocation.DEVICE);
@@ -355,12 +421,18 @@
* Assumes adb is running as root in device under test.
* @param preference the device's preferred location of where to install apps
* @param expectedLocation the expected location of where the apk was installed
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
public void installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference preference,
PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException, InstallException {
PackageManagerHostTestUtils.InstallLocPreference savedPref =
PackageManagerHostTestUtils.InstallLocPreference.AUTO;
@@ -384,10 +456,17 @@
* will install the app to the device when device's preference is auto.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppExternalLocPrefIsAuto() throws IOException, InterruptedException {
+ public void testInstallAppExternalLocPrefIsAuto() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installLocation=external, pref=auto gets installed on SD Card");
installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference.AUTO,
PackageManagerHostTestUtils.InstallLocation.SDCARD);
@@ -398,10 +477,17 @@
* will install the app to the device when device's preference is internal.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppExternalLocPrefIsInternal() throws IOException, InterruptedException {
+ public void testInstallAppExternalLocPrefIsInternal() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installLocation=external, pref=internal gets installed on SD Card");
installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference.INTERNAL,
PackageManagerHostTestUtils.InstallLocation.SDCARD);
@@ -412,10 +498,17 @@
* will install the app to the device when device's preference is external.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppExternalLocPrefIsExternal() throws IOException, InterruptedException {
+ public void testInstallAppExternalLocPrefIsExternal() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installLocation=external, pref=external gets installed on SD Card");
installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference.EXTERNAL,
PackageManagerHostTestUtils.InstallLocation.SDCARD);
@@ -427,10 +520,17 @@
* system decide.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppNoLocPrefIsAuto() throws IOException, InterruptedException {
+ public void testInstallAppNoLocPrefIsAuto() throws IOException, InterruptedException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
+ InstallException {
Log.i(LOG_TAG, "Test an app with no installLocation gets installed on device");
PackageManagerHostTestUtils.InstallLocPreference savedPref =
@@ -456,10 +556,17 @@
* external.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppNoLocPrefIsExternal() throws IOException, InterruptedException {
+ public void testInstallAppNoLocPrefIsExternal() throws IOException, InterruptedException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
+ InstallException {
Log.i(LOG_TAG, "Test an app with no installLocation gets installed on SD card");
PackageManagerHostTestUtils.InstallLocPreference savedPref =
@@ -485,10 +592,17 @@
* internal.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testInstallAppNoLocPrefIsInternal() throws IOException, InterruptedException {
+ public void testInstallAppNoLocPrefIsInternal() throws IOException, InterruptedException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
+ InstallException {
Log.i(LOG_TAG, "Test an app with no installLocation gets installed on device");
PackageManagerHostTestUtils.InstallLocPreference savedPref =
@@ -513,10 +627,18 @@
* forward-locked will get installed to the correct location.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws SyncException if the sync failed for another reason.
+ * @throws InstallException if the install failed.
*/
- public void testInstallFwdLockedAppInternal() throws IOException, InterruptedException {
+ public void testInstallFwdLockedAppInternal() throws IOException, InterruptedException,
+ InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test an app with installLoc set to Internal gets installed to app-private");
try {
@@ -534,10 +656,18 @@
* forward-locked will get installed to the correct location.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws SyncException if the sync failed for another reason.
+ * @throws InstallException if the install failed.
*/
- public void testInstallFwdLockedAppExternal() throws IOException, InterruptedException {
+ public void testInstallFwdLockedAppExternal() throws IOException, InterruptedException,
+ InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test an app with installLoc set to Internal gets installed to app-private");
try {
@@ -555,10 +685,18 @@
* forward-locked will get installed to the correct location.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws SyncException if the sync failed for another reason.
+ * @throws InstallException if the install failed.
*/
- public void testInstallFwdLockedAppAuto() throws IOException, InterruptedException {
+ public void testInstallFwdLockedAppAuto() throws IOException, InterruptedException,
+ InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test an app with installLoc set to Auto gets installed to app-private");
try {
@@ -576,10 +714,18 @@
* forward-locked installed will get installed to the correct location.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws SyncException if the sync failed for another reason.
+ * @throws InstallException if the install failed.
*/
- public void testInstallFwdLockedAppNone() throws IOException, InterruptedException {
+ public void testInstallFwdLockedAppNone() throws IOException, InterruptedException,
+ InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test an app with no installLoc set gets installed to app-private");
try {
@@ -597,14 +743,21 @@
* uninstall it, and reinstall it onto the SD card.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
// TODO: This currently relies on the app's manifest to switch from device to
// SD card install locations. We might want to make Device's installPackage()
// accept a installLocation flag so we can install a package to the
// destination of our choosing.
- public void testReinstallInternalToExternal() throws IOException, InterruptedException {
+ public void testReinstallInternalToExternal() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installing an app first to the device, then to the SD Card");
try {
@@ -625,14 +778,21 @@
* uninstall it, and reinstall it onto the device.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
// TODO: This currently relies on the app's manifest to switch from device to
// SD card install locations. We might want to make Device's installPackage()
// accept a installLocation flag so we can install a package to the
// destination of our choosing.
- public void testReinstallExternalToInternal() throws IOException, InterruptedException {
+ public void testReinstallExternalToInternal() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installing an app first to the SD Care, then to the device");
try {
@@ -655,10 +815,16 @@
* the update onto the SD card as well when location is set to external for both versions
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testUpdateBothExternal() throws IOException, InterruptedException {
+ public void testUpdateBothExternal() throws IOException, InterruptedException, InstallException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
try {
@@ -681,10 +847,16 @@
* updated apps' manifest file.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testUpdateToSDCard() throws IOException, InterruptedException {
+ public void testUpdateToSDCard() throws IOException, InterruptedException, InstallException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
try {
@@ -706,10 +878,17 @@
* the update onto the device if the manifest has changed to installLocation=internalOnly
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
- public void testUpdateSDCardToDevice() throws IOException, InterruptedException {
+ public void testUpdateSDCardToDevice() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test updating an app on the SD card to the Device through manifest change");
try {
@@ -731,11 +910,18 @@
* the update onto the device's forward-locked location
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws SyncException if the sync failed for another reason.
+ * @throws InstallException if the install failed.
*/
public void testInstallAndUpdateExternalLocForwardLockedApp()
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, SyncException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test updating a forward-locked app marked preferExternal");
try {
@@ -757,11 +943,18 @@
* the update onto the device's forward-locked location
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws SyncException if the sync failed for another reason.
+ * @throws InstallException if the install failed.
*/
public void testInstallAndUpdateNoLocForwardLockedApp()
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, SyncException,
+ TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test updating a forward-locked app with no installLocation pref set");
try {
@@ -783,11 +976,18 @@
* and then launched without crashing.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws SyncException if the sync failed for another reason.
+ * @throws InstallException if the install failed.
*/
public void testInstallAndLaunchAllPermsAppOnSD()
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test launching an app with all perms set, installed on SD card");
try {
@@ -808,11 +1008,17 @@
* run without permissions errors.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
public void testInstallAndLaunchFLPermsAppOnSD()
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test launching an app with location perms set, installed on SD card");
try {
@@ -833,11 +1039,17 @@
* run without permissions errors.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
public void testInstallAndLaunchBTPermsAppOnSD()
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test launching an app with bluetooth perms set, installed on SD card");
try {
@@ -858,11 +1070,17 @@
* SecurityException when launched if its other shared apps are not installed.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
public void testInstallAndLaunchSharedPermsAppOnSD_NoPerms()
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test launching an app with no explicit perms set, installed on SD card");
try {
@@ -888,11 +1106,17 @@
* shared apps are installed.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
public void testInstallAndLaunchSharedPermsAppOnSD_GrantedPerms()
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test launching an app with no explicit perms set, installed on SD card");
try {
@@ -921,11 +1145,17 @@
* run without permissions errors even after a reboot
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
public void testInstallAndLaunchFLPermsAppOnSD_Reboot()
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test launching an app with location perms set, installed on SD card");
try {
@@ -951,11 +1181,17 @@
* shared apps are installed, even after a reboot.
* <p/>
* Assumes adb is running as root in device under test.
- * @throws IOException if adb shell command failed
* @throws InterruptedException if the thread was interrupted
+ * @throws TimeoutException in case of a timeout on the connection.
+ * @throws AdbCommandRejectedException if adb rejects the command
+ * @throws ShellCommandUnresponsiveException if the device did not output anything for
+ * a period longer than the max time to output.
+ * @throws IOException if connection to device was lost.
+ * @throws InstallException if the install failed.
*/
public void testInstallAndLaunchSharedPermsAppOnSD_Reboot()
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InstallException, TimeoutException,
+ AdbCommandRejectedException, ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test launching an app on SD, with no explicit perms set after reboot");
try {
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerStressHostTests.java b/core/tests/hosttests/src/android/content/pm/PackageManagerStressHostTests.java
index 715c55b..a2a5dd3 100644
--- a/core/tests/hosttests/src/android/content/pm/PackageManagerStressHostTests.java
+++ b/core/tests/hosttests/src/android/content/pm/PackageManagerStressHostTests.java
@@ -16,8 +16,11 @@
package android.content.pm;
-import com.android.ddmlib.IDevice;
+import com.android.ddmlib.AdbCommandRejectedException;
+import com.android.ddmlib.InstallException;
import com.android.ddmlib.Log;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.TimeoutException;
import com.android.hosttest.DeviceTestCase;
import com.android.hosttest.DeviceTestSuite;
@@ -138,7 +141,9 @@
* <p/>
* Assumes adb is running as root in device under test.
*/
- public void testUpdateAppManyTimesOnSD() throws IOException, InterruptedException {
+ public void testUpdateAppManyTimesOnSD() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test updating an app on SD numerous times");
// cleanup test app just in case it already exists
@@ -173,7 +178,9 @@
* <p/>
* Assumes adb is running as root in device under test.
*/
- public void testUninstallReinstallAppOnSDManyTimes() throws IOException, InterruptedException {
+ public void testUninstallReinstallAppOnSDManyTimes() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
// cleanup test app just in case it was already exists
@@ -207,7 +214,9 @@
* <p/>
* Assumes adb is running as root in device under test.
*/
- public void testInstallManyLargeAppsOnSD() throws IOException, InterruptedException {
+ public void testInstallManyLargeAppsOnSD() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installing 20 large apps onto the sd card");
try {
@@ -251,7 +260,9 @@
* <p/>
* Assumes adb is running as root in device under test.
*/
- public void testInstallManyAppsOnSD() throws IOException, InterruptedException {
+ public void testInstallManyAppsOnSD() throws IOException, InterruptedException,
+ InstallException, TimeoutException, AdbCommandRejectedException,
+ ShellCommandUnresponsiveException {
Log.i(LOG_TAG, "Test installing 500 small apps onto SD");
try {
diff --git a/docs/html/community/index.jd b/docs/html/community/index.jd
index 3e69de4..23203c1 100644
--- a/docs/html/community/index.jd
+++ b/docs/html/community/index.jd
@@ -4,10 +4,10 @@
<div id="mainBodyFluid">
<h1>Community</h1>
-<p>Welcome to the Android developers community! We're glad you're here and invite you to participate in these discussions. Before posting, please read the <a href="http://source.android.com/discuss/android-discussion-groups-charter">Groups Charter</a> that covers the community guidelines.</p>
+<p>Welcome to the Android developers community! We're glad you're here and invite you to participate in these discussions. Before posting, please read the <a href="http://source.android.com/community/groups-charter.html">Groups Charter</a> that covers the community guidelines.</p>
<p class="note"><strong>Note:</strong> If you are seeking discussion about Android source code (not application development),
-then please refer to the <a href="http://source.android.com/discuss">Open Source Project Mailing lists</a>.</p>
+then please refer to the <a href="http://source.android.com/community">Open Source Project Mailing lists</a>.</p>
<p style="margin-bottom:.5em"><strong>Contents</strong></p>
<ol class="toc">
@@ -31,7 +31,7 @@
As you write your post, please do the following:
<ol>
<li><b>Read
-the <a href="http://sites.google.com/a/android.com/opensource/discuss/android-discussion-groups-charter">mailing list charter</a></b> that covers the community guidelines.
+the <a href="http://source.android.com/community/groups-charter.html">mailing list charter</a></b> that covers the community guidelines.
</li>
<li><b>Select the most appropriate mailing list for your question</b>. There are several different lists for
developers, described below.</li>
diff --git a/docs/html/guide/topics/resources/animation-resource.jd b/docs/html/guide/topics/resources/animation-resource.jd
index e0ce051..972dd72 100644
--- a/docs/html/guide/topics/resources/animation-resource.jd
+++ b/docs/html/guide/topics/resources/animation-resource.jd
@@ -65,10 +65,10 @@
android:pivotX="<em>float</em>"
android:pivotY="<em>float</em>" />
<<a href="#translate-element">translate</a>
- android:fromX="<em>float</em>"
- android:toX="<em>float</em>"
- android:fromY="<em>float</em>"
- android:toY="<em>float</em>" />
+ android:fromXDelta="<em>float</em>"
+ android:toXDelta="<em>float</em>"
+ android:fromYDelta="<em>float</em>"
+ android:toYDelta="<em>float</em>" />
<<a href="#rotate-element">rotate</a>
android:fromDegrees="<em>float</em>"
android:toDegrees="<em>float</em>"
@@ -212,10 +212,10 @@
android:shareInterpolator="false">
<scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
- android:fromXScale="1.0"
- android:toXScale="1.4"
- android:fromYScale="1.0"
- android:toYScale="0.6"
+ android:fromXScale="1.0"
+ android:toXScale="1.4"
+ android:fromYScale="1.0"
+ android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
@@ -224,18 +224,18 @@
android:interpolator="@android:anim/accelerate_interpolator"
android:startOffset="700">
<scale
- android:fromXScale="1.4"
+ android:fromXScale="1.4"
android:toXScale="0.0"
android:fromYScale="0.6"
- android:toYScale="0.0"
- android:pivotX="50%"
- android:pivotY="50%"
+ android:toYScale="0.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
android:duration="400" />
<rotate
- android:fromDegrees="0"
+ android:fromDegrees="0"
android:toDegrees="-45"
- android:toYScale="0.0"
- android:pivotX="50%"
+ android:toYScale="0.0"
+ android:pivotX="50%"
android:pivotY="50%"
android:duration="400" />
</set>
diff --git a/docs/html/intl/ja/community/index.jd b/docs/html/intl/ja/community/index.jd
index 659aee7..490b23f 100644
--- a/docs/html/intl/ja/community/index.jd
+++ b/docs/html/intl/ja/community/index.jd
@@ -4,9 +4,9 @@
<div id="mainBodyFluid">
<h1>コミュニティ</h1>
- <p>Android デベロッパー コミュニティへようこそ。コミュニティでのディスカッションにぜひ参加してください。投稿する前に、コミュニティ ガイドラインが記載されている<a href="http://source.android.com/discuss/android-discussion-groups-charter">グループの趣意</a>をお読みください。</p>
+ <p>Android デベロッパー コミュニティへようこそ。コミュニティでのディスカッションにぜひ参加してください。投稿する前に、コミュニティ ガイドラインが記載されている<a href="http://source.android.com/community/groups-charter.html">グループの趣意</a>をお読みください。</p>
-<p class="note"><strong>注:</strong> Android ソース コード(アプリケーション開発ではなく)に関するディスカッションは、<a href="http://source.android.com/discuss">オープンソース プロジェクトのメーリング リスト</a>(英語)を参照してください。</p>
+<p class="note"><strong>注:</strong> Android ソース コード(アプリケーション開発ではなく)に関するディスカッションは、<a href="http://source.android.com/community">オープンソース プロジェクトのメーリング リスト</a>(英語)を参照してください。</p>
<p style="margin-bottom:.5em"><strong>目次</strong></p>
<ol class="toc">
@@ -28,7 +28,7 @@
<p>質問への答えが見つからない場合、コミュニティで質問することをおすすめします。投稿する際は、次の手順に従ってください。
<ol>
-<li>コミュニティ ガイドラインが記載されている<b><a href="http://sites.google.com/a/android.com/opensource/discuss/android-discussion-groups-charter">Android メーリングリストの趣意</a></b>をお読みください。
+<li>コミュニティ ガイドラインが記載されている<b><a href="http://source.android.com/community/groups-charter.html">Android メーリングリストの趣意</a></b>をお読みください。
</li>
<li><b>質問に最適なメーリング リストを選択してください</b>。後述するように、デベロッパー向けのメーリング リストは何種類かに分かれています。</li>
<li>
diff --git a/docs/html/intl/ja/resources/community-groups.jd b/docs/html/intl/ja/resources/community-groups.jd
index c99b1f8..ecedde1 100644
--- a/docs/html/intl/ja/resources/community-groups.jd
+++ b/docs/html/intl/ja/resources/community-groups.jd
@@ -4,9 +4,9 @@
<div id="mainBodyFluid">
<h1>コミュニティ</h1>
- <p>Android デベロッパー コミュニティへようこそ。コミュニティでのディスカッションにぜひ参加してください。投稿する前に、コミュニティ ガイドラインが記載されている<a href="http://source.android.com/discuss/android-discussion-groups-charter">グループの趣意</a>をお読みください。</p>
+ <p>Android デベロッパー コミュニティへようこそ。コミュニティでのディスカッションにぜひ参加してください。投稿する前に、コミュニティ ガイドラインが記載されている<a href="http://source.android.com/community/groups-charter.html">グループの趣意</a>をお読みください。</p>
-<p class="note"><strong>注:</strong> Android ソース コード(アプリケーション開発ではなく)に関するディスカッションは、<a href="http://source.android.com/discuss">オープンソース プロジェクトのメーリング リスト</a>(英語)を参照してください。</p>
+<p class="note"><strong>注:</strong> Android ソース コード(アプリケーション開発ではなく)に関するディスカッションは、<a href="http://source.android.com/community">オープンソース プロジェクトのメーリング リスト</a>(英語)を参照してください。</p>
<p style="margin-bottom:.5em"><strong>目次</strong></p>
<ol class="toc">
@@ -28,7 +28,7 @@
<p>質問への答えが見つからない場合、コミュニティで質問することをおすすめします。投稿する際は、次の手順に従ってください。
<ol>
-<li>コミュニティ ガイドラインが記載されている<b><a href="http://sites.google.com/a/android.com/opensource/discuss/android-discussion-groups-charter">Android メーリングリストの趣意</a></b>をお読みください。
+<li>コミュニティ ガイドラインが記載されている<b><a href="http://source.android.com/community/groups-charter.html">Android メーリングリストの趣意</a></b>をお読みください。
</li>
<li><b>質問に最適なメーリング リストを選択してください</b>。後述するように、デベロッパー向けのメーリング リストは何種類かに分かれています。</li>
<li>
diff --git a/docs/html/resources/articles/painless-threading.jd b/docs/html/resources/articles/painless-threading.jd
index 921f4df..17cec35 100644
--- a/docs/html/resources/articles/painless-threading.jd
+++ b/docs/html/resources/articles/painless-threading.jd
@@ -108,7 +108,7 @@
new DownloadImageTask().execute("http://example.com/image.png");
}
-private class DownloadImageTask extends AsyncTask<string, void,="" bitmap=""> {
+private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}
diff --git a/docs/html/resources/community-groups.jd b/docs/html/resources/community-groups.jd
index 651edbc..599c4ae 100644
--- a/docs/html/resources/community-groups.jd
+++ b/docs/html/resources/community-groups.jd
@@ -22,7 +22,7 @@
<p>Welcome to the Android developers community! We're glad you're here and invite you to participate in discussions with other Android application developers on topics that interest you.</p>
-<p>The lists on this page are primarily for discussion about Android application development. If you are seeking discussion about Android source code (not application development), then please refer to the <a href="http://source.android.com/discuss">Open Source Project Mailing lists</a>.</p>
+<p>The lists on this page are primarily for discussion about Android application development. If you are seeking discussion about Android source code (not application development), then please refer to the <a href="http://source.android.com/community">Open Source Project Mailing lists</a>.</p>
<h2 id="StackOverflow">Stack Overflow</h2>
@@ -56,7 +56,7 @@
As you write your post, please do the following:
<ol>
<li><strong>Read
-the <a href="http://source.android.com/discuss/android-discussion-groups-charter">mailing list charter</a></strong> that covers the community guidelines.
+the <a href="http://source.android.com/community/groups-charter.html">mailing list charter</a></strong> that covers the community guidelines.
</li>
<li><strong>Select the most appropriate mailing list for your question</strong>. There are several different lists for
developers, described below.</li>
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 345f810..76cde73 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1221,7 +1221,7 @@
checkRange(texs.length, texOffset, vertexCount);
}
if (colors != null) {
- checkRange(colors.length, colorOffset, vertexCount);
+ checkRange(colors.length, colorOffset, vertexCount / 2);
}
if (indices != null) {
checkRange(indices.length, indexOffset, indexCount);
diff --git a/libs/rs/rsNoise.cpp b/libs/rs/rsNoise.cpp
index 764dc1a..4b67586 100644
--- a/libs/rs/rsNoise.cpp
+++ b/libs/rs/rsNoise.cpp
@@ -253,4 +253,4 @@
}
}
-}
\ No newline at end of file
+}
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 013f8fc..3333268 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1215,8 +1215,12 @@
prescan(path);
File file = new File(path);
+
+ // lastModified is in milliseconds on Files.
+ long lastModifiedSeconds = file.lastModified() / 1000;
+
// always scan the file, so we can return the content://media Uri for existing files
- return mClient.doScanFile(path, mimeType, file.lastModified(), file.length(), true);
+ return mClient.doScanFile(path, mimeType, lastModifiedSeconds, file.length(), true);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e);
return null;
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index 6f581d3..c5112a5 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -81,13 +81,13 @@
}
static bool fileMatchesExtension(const char* path, const char* extensions) {
- char* extension = strrchr(path, '.');
+ const char* extension = strrchr(path, '.');
if (!extension) return false;
++extension; // skip the dot
if (extension[0] == 0) return false;
while (extensions[0]) {
- char* comma = strchr(extensions, ',');
+ const char* comma = strchr(extensions, ',');
size_t length = (comma ? comma - extensions : strlen(extensions));
if (length == strlen(extension) && strncasecmp(extension, extensions, length) == 0) return true;
extensions += length;
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 163b2dbc..460b74f 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -480,13 +480,13 @@
copybit_device_t* const copybit = blitengine;
if (copybit) {
copybit_image_t simg;
- simg.w = src->width;
+ simg.w = src->stride;
simg.h = src->height;
simg.format = src->format;
simg.handle = const_cast<native_handle_t*>(src->handle);
copybit_image_t dimg;
- dimg.w = dst->width;
+ dimg.w = dst->stride;
dimg.h = dst->height;
dimg.format = dst->format;
dimg.handle = const_cast<native_handle_t*>(dst->handle);
diff --git a/opengl/tests/gl_jni/jni/gl_code.cpp b/opengl/tests/gl_jni/jni/gl_code.cpp
index f031c79..ef66841 100644
--- a/opengl/tests/gl_jni/jni/gl_code.cpp
+++ b/opengl/tests/gl_jni/jni/gl_code.cpp
@@ -181,4 +181,3 @@
{
background = 1.0f - background;
}
-
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index c751f3d..4c81380 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -27,6 +27,7 @@
import android.net.MobileDataStateTracker;
import android.net.NetworkInfo;
import android.net.NetworkStateTracker;
+import android.net.NetworkUtils;
import android.net.wifi.WifiStateTracker;
import android.os.Binder;
import android.os.Handler;
@@ -49,6 +50,8 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
/**
* @hide
@@ -730,6 +733,8 @@
}
/**
+ * @deprecated use requestRouteToHostAddress instead
+ *
* Ensure that a network route exists to deliver traffic to the specified
* host via the specified network interface.
* @param networkType the type of the network over which traffic to the
@@ -739,6 +744,25 @@
* @return {@code true} on success, {@code false} on failure
*/
public boolean requestRouteToHost(int networkType, int hostAddress) {
+ InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
+
+ if (inetAddress == null) {
+ return false;
+ }
+
+ return requestRouteToHostAddress(networkType, inetAddress.getAddress());
+ }
+
+ /**
+ * Ensure that a network route exists to deliver traffic to the specified
+ * host via the specified network interface.
+ * @param networkType the type of the network over which traffic to the
+ * specified host is to be routed
+ * @param hostAddress the IP address of the host to which the route is
+ * desired
+ * @return {@code true} on success, {@code false} on failure
+ */
+ public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
enforceChangePermission();
if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
return false;
@@ -748,11 +772,18 @@
if (tracker == null || !tracker.getNetworkInfo().isConnected() ||
tracker.isTeardownRequested()) {
if (DBG) {
- Slog.d(TAG, "requestRouteToHost on down network (" + networkType + ") - dropped");
+ Slog.d(TAG, "requestRouteToHostAddress on down network " +
+ "(" + networkType + ") - dropped");
}
return false;
}
- return tracker.requestRouteToHost(hostAddress);
+
+ try {
+ InetAddress inetAddress = InetAddress.getByAddress(hostAddress);
+ return tracker.requestRouteToHost(inetAddress);
+ } catch (UnknownHostException e) {
+ return false;
+ }
}
/**
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 6e8b42e..f83119f 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1087,7 +1087,7 @@
private void setUmsEnabling(boolean enable) {
synchronized (mListeners) {
- mUmsEnabling = true;
+ mUmsEnabling = enable;
}
}
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 63325dd..ed8b90b 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -129,11 +129,11 @@
private boolean mBatteryFull;
private NotificationRecord mLedNotification;
- private static final int BATTERY_LOW_ARGB = 0xFFFF0000; // Charging Low - red solid on
- private static final int BATTERY_MEDIUM_ARGB = 0xFFFFFF00; // Charging - orange solid on
- private static final int BATTERY_FULL_ARGB = 0xFF00FF00; // Charging Full - green solid on
- private static final int BATTERY_BLINK_ON = 125;
- private static final int BATTERY_BLINK_OFF = 2875;
+ private static int mBatteryLowARGB;
+ private static int mBatteryMediumARGB;
+ private static int mBatteryFullARGB;
+ private static int mBatteryLedOn;
+ private static int mBatteryLedOff;
private static String idDebugString(Context baseContext, String packageName, int id) {
Context c = null;
@@ -448,6 +448,17 @@
mDefaultNotificationLedOff = resources.getInteger(
com.android.internal.R.integer.config_defaultNotificationLedOff);
+ mBatteryLowARGB = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_notificationsBatteryLowARGB);
+ mBatteryMediumARGB = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_notificationsBatteryMediumARGB);
+ mBatteryFullARGB = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_notificationsBatteryFullARGB);
+ mBatteryLedOn = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_notificationsBatteryLedOn);
+ mBatteryLedOff = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_notificationsBatteryLedOff);
+
// Don't start allowing notifications until the setup wizard has run once.
// After that, including subsequent boots, init with notifications turned on.
// This works on the first boot because the setup wizard will toggle this
@@ -1066,17 +1077,17 @@
// Battery low always shows, other states only show if charging.
if (mBatteryLow) {
if (mBatteryCharging) {
- mBatteryLight.setColor(BATTERY_LOW_ARGB);
+ mBatteryLight.setColor(mBatteryLowARGB);
} else {
// Flash when battery is low and not charging
- mBatteryLight.setFlashing(BATTERY_LOW_ARGB, LightsService.LIGHT_FLASH_TIMED,
- BATTERY_BLINK_ON, BATTERY_BLINK_OFF);
+ mBatteryLight.setFlashing(mBatteryLowARGB, LightsService.LIGHT_FLASH_TIMED,
+ mBatteryLedOn, mBatteryLedOff);
}
} else if (mBatteryCharging) {
if (mBatteryFull) {
- mBatteryLight.setColor(BATTERY_FULL_ARGB);
+ mBatteryLight.setColor(mBatteryFullARGB);
} else {
- mBatteryLight.setColor(BATTERY_MEDIUM_ARGB);
+ mBatteryLight.setColor(mBatteryMediumARGB);
}
} else {
mBatteryLight.turnOff();
diff --git a/services/java/com/android/server/ProcessStats.java b/services/java/com/android/server/ProcessStats.java
index 0c8c2fd..5bdadcc 100644
--- a/services/java/com/android/server/ProcessStats.java
+++ b/services/java/com/android/server/ProcessStats.java
@@ -778,7 +778,7 @@
break;
}
}
- return new String(mBuffer, 0, 0, i);
+ return new String(mBuffer, 0, i);
}
} catch (java.io.FileNotFoundException e) {
} catch (java.io.IOException e) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 30dc5ea..a41ba9c 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -55,6 +55,7 @@
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IIntentReceiver;
@@ -1083,7 +1084,7 @@
d.setCancelable(false);
d.setTitle("System UIDs Inconsistent");
d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
- d.setButton("I'm Feeling Lucky",
+ d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
mUidAlert = d;
d.show();
@@ -3628,10 +3629,12 @@
String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
if (pkgs != null) {
for (String pkg : pkgs) {
- if (forceStopPackageLocked(pkg, -1, false, false, false)) {
- setResultCode(Activity.RESULT_OK);
- return;
- }
+ synchronized (ActivityManagerService.this) {
+ if (forceStopPackageLocked(pkg, -1, false, false, false)) {
+ setResultCode(Activity.RESULT_OK);
+ return;
+ }
+ }
}
}
}
@@ -6208,7 +6211,28 @@
sr.crashCount++;
}
}
-
+
+ // If the crashing process is what we consider to be the "home process" and it has been
+ // replaced by a third-party app, clear the package preferred activities from packages
+ // with a home activity running in the process to prevent a repeatedly crashing app
+ // from blocking the user to manually clear the list.
+ if (app == mHomeProcess && mHomeProcess.activities.size() > 0
+ && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ Iterator it = mHomeProcess.activities.iterator();
+ while (it.hasNext()) {
+ ActivityRecord r = (ActivityRecord)it.next();
+ if (r.isHomeActivity) {
+ Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
+ try {
+ ActivityThread.getPackageManager()
+ .clearPackagePreferredActivities(r.packageName);
+ } catch (RemoteException c) {
+ // pm is in same process, this will never happen.
+ }
+ }
+ }
+ }
+
mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
return true;
}
diff --git a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java b/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
index 8e9818d..9fb48b3 100644
--- a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
+++ b/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import android.content.Context;
+import android.content.DialogInterface;
import android.os.Handler;
import android.os.Message;
@@ -49,7 +50,7 @@
text.append(" is waiting for the debugger to attach.");
setMessage(text.toString());
- setButton("Force Close", mHandler.obtainMessage(1, app));
+ setButton(DialogInterface.BUTTON_POSITIVE, "Force Close", mHandler.obtainMessage(1, app));
setTitle("Waiting For Debugger");
getWindow().setTitle("Waiting For Debugger: " + app.info.processName);
}
diff --git a/services/java/com/android/server/am/FactoryErrorDialog.java b/services/java/com/android/server/am/FactoryErrorDialog.java
index 2e25474..b19bb5ca 100644
--- a/services/java/com/android/server/am/FactoryErrorDialog.java
+++ b/services/java/com/android/server/am/FactoryErrorDialog.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import android.content.Context;
+import android.content.DialogInterface;
import android.os.Handler;
import android.os.Message;
@@ -26,7 +27,8 @@
setCancelable(false);
setTitle(context.getText(com.android.internal.R.string.factorytest_failed));
setMessage(msg);
- setButton(context.getText(com.android.internal.R.string.factorytest_reboot),
+ setButton(DialogInterface.BUTTON_POSITIVE,
+ context.getText(com.android.internal.R.string.factorytest_reboot),
mHandler.obtainMessage(0));
getWindow().setTitle("Factory Error");
}
diff --git a/services/surfaceflinger/LayerBuffer.cpp b/services/surfaceflinger/LayerBuffer.cpp
index 0240748..fdf9abc 100644
--- a/services/surfaceflinger/LayerBuffer.cpp
+++ b/services/surfaceflinger/LayerBuffer.cpp
@@ -495,7 +495,7 @@
const ISurface::BufferHeap& buffers(mBufferHeap);
uint32_t w = mLayer.mTransformedBounds.width();
uint32_t h = mLayer.mTransformedBounds.height();
- if (buffers.w * h != buffers.h * w) {
+ if (mLayer.getOrientation() & (Transform::ROT_90 | Transform::ROT_270)) {
int t = w; w = h; h = t;
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index f5c6909..7829006 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -55,6 +55,12 @@
public static final char WILD = 'N';
/*
+ * Calling Line Identification Restriction (CLIR)
+ */
+ private static final String CLIR_ON = "*31#+";
+ private static final String CLIR_OFF = "#31#+";
+
+ /*
* TOA = TON + NPI
* See TS 24.008 section 10.5.4.7 for details.
* These are the only really useful TOA values
@@ -179,8 +185,6 @@
* Please note that the GSM wild character is allowed in the result.
* This must be resolved before dialing.
*
- * Allows + only in the first position in the result string.
- *
* Returns null if phoneNumber == null
*/
public static String
@@ -203,6 +207,11 @@
}
}
+ int pos = addPlusChar(phoneNumber);
+ if (pos >= 0 && ret.length() > pos) {
+ ret.insert(pos, '+');
+ }
+
return ret.toString();
}
@@ -304,6 +313,28 @@
}
}
+ /** GSM codes
+ * Finds if a GSM code includes the international prefix (+).
+ *
+ * @param number the number to dial.
+ *
+ * @return the position where the + char will be inserted, -1 if the GSM code was not found.
+ */
+ private static int
+ addPlusChar(String number) {
+ int pos = -1;
+
+ if (number.startsWith(CLIR_OFF)) {
+ pos = CLIR_OFF.length() - 1;
+ }
+
+ if (number.startsWith(CLIR_ON)) {
+ pos = CLIR_ON.length() - 1;
+ }
+
+ return pos;
+ }
+
/**
* Extracts the post-dial sequence of DTMF control digits, pauses, and
* waits. Strips separators. This string may be empty, but will not be null
@@ -1119,7 +1150,7 @@
&& text.charAt(2) == '1') {
formatType = FORMAT_JAPAN;
} else {
- return;
+ formatType = FORMAT_UNKNOWN;
}
}
@@ -1130,6 +1161,9 @@
case FORMAT_JAPAN:
formatJapaneseNumber(text);
return;
+ case FORMAT_UNKNOWN:
+ removeDashes(text);
+ return;
}
}
@@ -1165,14 +1199,7 @@
CharSequence saved = text.subSequence(0, length);
// Strip the dashes first, as we're going to add them back
- int p = 0;
- while (p < text.length()) {
- if (text.charAt(p) == '-') {
- text.delete(p, p + 1);
- } else {
- p++;
- }
- }
+ removeDashes(text);
length = text.length();
// When scanning the number we record where dashes need to be added,
@@ -1276,6 +1303,22 @@
JapanesePhoneNumberFormatter.format(text);
}
+ /**
+ * Removes all dashes from the number.
+ *
+ * @param text the number to clear from dashes
+ */
+ private static void removeDashes(Editable text) {
+ int p = 0;
+ while (p < text.length()) {
+ if (text.charAt(p) == '-') {
+ text.delete(p, p + 1);
+ } else {
+ p++;
+ }
+ }
+ }
+
// Three and four digit phone numbers for either special services,
// or 3-6 digit addresses from the network (eg carrier-originated SMS messages) should
// not match.
diff --git a/telephony/java/com/android/internal/telephony/AdnRecordCache.java b/telephony/java/com/android/internal/telephony/AdnRecordCache.java
index c8c0658..a175d49 100644
--- a/telephony/java/com/android/internal/telephony/AdnRecordCache.java
+++ b/telephony/java/com/android/internal/telephony/AdnRecordCache.java
@@ -186,7 +186,12 @@
}
ArrayList<AdnRecord> oldAdnList;
- oldAdnList = getRecordsIfLoaded(efid);
+
+ if (efid == EF_PBR) {
+ oldAdnList = mUsimPhoneBookManager.loadEfFilesFromUsim();
+ } else {
+ oldAdnList = getRecordsIfLoaded(efid);
+ }
if (oldAdnList == null) {
sendErrorResponse(response, "Adn list not exist for EF:" + efid);
@@ -208,6 +213,17 @@
return;
}
+ if (efid == EF_PBR) {
+ AdnRecord foundAdn = oldAdnList.get(index-1);
+ efid = foundAdn.efid;
+ extensionEF = foundAdn.extRecord;
+ index = foundAdn.recordNumber;
+
+ newAdn.efid = efid;
+ newAdn.extRecord = extensionEF;
+ newAdn.recordNumber = index;
+ }
+
Message pendingResponse = userWriteResponse.get(efid);
if (pendingResponse != null) {
@@ -331,6 +347,7 @@
if (ar.exception == null) {
adnLikeFiles.get(efid).set(index - 1, adn);
+ mUsimPhoneBookManager.invalidateCache();
}
Message response = userWriteResponse.get(efid);
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index b962375..815fbfb 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -73,10 +73,10 @@
protected Registrant mSmsOnSimRegistrant;
protected Registrant mSmsStatusRegistrant;
protected Registrant mSsnRegistrant;
- protected Registrant mStkSessionEndRegistrant;
- protected Registrant mStkProCmdRegistrant;
- protected Registrant mStkEventRegistrant;
- protected Registrant mStkCallSetUpRegistrant;
+ protected Registrant mCatSessionEndRegistrant;
+ protected Registrant mCatProCmdRegistrant;
+ protected Registrant mCatEventRegistrant;
+ protected Registrant mCatCallSetUpRegistrant;
protected Registrant mIccSmsFullRegistrant;
protected Registrant mEmergencyCallbackModeRegistrant;
protected Registrant mIccRefreshRegistrant;
@@ -395,36 +395,36 @@
mSsnRegistrant.clear();
}
- public void setOnStkSessionEnd(Handler h, int what, Object obj) {
- mStkSessionEndRegistrant = new Registrant (h, what, obj);
+ public void setOnCatSessionEnd(Handler h, int what, Object obj) {
+ mCatSessionEndRegistrant = new Registrant (h, what, obj);
}
- public void unSetOnStkSessionEnd(Handler h) {
- mStkSessionEndRegistrant.clear();
+ public void unSetOnCatSessionEnd(Handler h) {
+ mCatSessionEndRegistrant.clear();
}
- public void setOnStkProactiveCmd(Handler h, int what, Object obj) {
- mStkProCmdRegistrant = new Registrant (h, what, obj);
+ public void setOnCatProactiveCmd(Handler h, int what, Object obj) {
+ mCatProCmdRegistrant = new Registrant (h, what, obj);
}
- public void unSetOnStkProactiveCmd(Handler h) {
- mStkProCmdRegistrant.clear();
+ public void unSetOnCatProactiveCmd(Handler h) {
+ mCatProCmdRegistrant.clear();
}
- public void setOnStkEvent(Handler h, int what, Object obj) {
- mStkEventRegistrant = new Registrant (h, what, obj);
+ public void setOnCatEvent(Handler h, int what, Object obj) {
+ mCatEventRegistrant = new Registrant (h, what, obj);
}
- public void unSetOnStkEvent(Handler h) {
- mStkEventRegistrant.clear();
+ public void unSetOnCatEvent(Handler h) {
+ mCatEventRegistrant.clear();
}
- public void setOnStkCallSetUp(Handler h, int what, Object obj) {
- mStkCallSetUpRegistrant = new Registrant (h, what, obj);
+ public void setOnCatCallSetUp(Handler h, int what, Object obj) {
+ mCatCallSetUpRegistrant = new Registrant (h, what, obj);
}
- public void unSetOnStkCallSetUp(Handler h) {
- mStkCallSetUpRegistrant.clear();
+ public void unSetOnCatCallSetUp(Handler h) {
+ mCatCallSetUpRegistrant.clear();
}
public void setOnIccSmsFull(Handler h, int what, Object obj) {
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 8e03c5a..5de0426 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -374,48 +374,48 @@
void unSetOnSuppServiceNotification(Handler h);
/**
- * Sets the handler for Session End Notifications for STK.
+ * Sets the handler for Session End Notifications for CAT.
* Unlike the register* methods, there's only one notification handler
*
* @param h Handler for notification message.
* @param what User-defined message code.
* @param obj User object.
*/
- void setOnStkSessionEnd(Handler h, int what, Object obj);
- void unSetOnStkSessionEnd(Handler h);
+ void setOnCatSessionEnd(Handler h, int what, Object obj);
+ void unSetOnCatSessionEnd(Handler h);
/**
- * Sets the handler for Proactive Commands for STK.
+ * Sets the handler for Proactive Commands for CAT.
* Unlike the register* methods, there's only one notification handler
*
* @param h Handler for notification message.
* @param what User-defined message code.
* @param obj User object.
*/
- void setOnStkProactiveCmd(Handler h, int what, Object obj);
- void unSetOnStkProactiveCmd(Handler h);
+ void setOnCatProactiveCmd(Handler h, int what, Object obj);
+ void unSetOnCatProactiveCmd(Handler h);
/**
- * Sets the handler for Event Notifications for STK.
+ * Sets the handler for Event Notifications for CAT.
* Unlike the register* methods, there's only one notification handler
*
* @param h Handler for notification message.
* @param what User-defined message code.
* @param obj User object.
*/
- void setOnStkEvent(Handler h, int what, Object obj);
- void unSetOnStkEvent(Handler h);
+ void setOnCatEvent(Handler h, int what, Object obj);
+ void unSetOnCatEvent(Handler h);
/**
- * Sets the handler for Call Set Up Notifications for STK.
+ * Sets the handler for Call Set Up Notifications for CAT.
* Unlike the register* methods, there's only one notification handler
*
* @param h Handler for notification message.
* @param what User-defined message code.
* @param obj User object.
*/
- void setOnStkCallSetUp(Handler h, int what, Object obj);
- void unSetOnStkCallSetUp(Handler h);
+ void setOnCatCallSetUp(Handler h, int what, Object obj);
+ void unSetOnCatCallSetUp(Handler h);
/**
* Enables/disbables supplementary service related notifications from
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index d3a34ec..90f9e8c 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -672,12 +672,11 @@
* @return true if a ICC card is present
*/
public boolean hasIccCard() {
- boolean isIccPresent;
- if (mPhone.getPhoneName().equals("GSM")) {
- return mIccCardStatus.getCardState().isCardPresent();
- } else {
- // TODO: Make work with a CDMA device with a RUIM card.
+ if (mIccCardStatus == null) {
return false;
+ } else {
+ // Returns ICC card status for both GSM and CDMA mode
+ return mIccCardStatus.getCardState().isCardPresent();
}
}
diff --git a/telephony/java/com/android/internal/telephony/IccConstants.java b/telephony/java/com/android/internal/telephony/IccConstants.java
index acc9197..b12d2d4 100644
--- a/telephony/java/com/android/internal/telephony/IccConstants.java
+++ b/telephony/java/com/android/internal/telephony/IccConstants.java
@@ -52,6 +52,7 @@
static final int EF_SPN_CPHS = 0x6f14;
static final int EF_SPN_SHORT_CPHS = 0x6f18;
static final int EF_INFO_CPHS = 0x6f16;
+ static final int EF_CSP_CPHS = 0x6f15;
// CDMA RUIM file ids from 3GPP2 C.S0023-0
static final int EF_CST = 0x6f32;
diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 9f8e57f..2f22d74 100644
--- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -62,8 +62,8 @@
logd("GET_RECORD_SIZE Size " + recordSize[0] +
" total " + recordSize[1] +
" #record " + recordSize[2]);
- mLock.notifyAll();
}
+ mLock.notifyAll();
}
break;
case EVENT_UPDATE_DONE:
@@ -144,6 +144,9 @@
if (DBG) logd("updateAdnRecordsInEfBySearch: efid=" + efid +
" ("+ oldTag + "," + oldPhoneNumber + ")"+ "==>" +
" ("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
+
+ efid = updateEfForIccType(efid);
+
synchronized(mLock) {
checkThread();
success = false;
diff --git a/telephony/java/com/android/internal/telephony/IccUtils.java b/telephony/java/com/android/internal/telephony/IccUtils.java
index 71936f1..957eddd 100644
--- a/telephony/java/com/android/internal/telephony/IccUtils.java
+++ b/telephony/java/com/android/internal/telephony/IccUtils.java
@@ -51,6 +51,8 @@
ret.append((char)('0' + v));
v = (data[i] >> 4) & 0xf;
+ // Some PLMNs have 'f' as high nibble, ignore it
+ if (v == 0xf) continue;
if (v > 9) break;
ret.append((char)('0' + v));
}
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 9afade3..3dd9a01 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -1710,4 +1710,15 @@
void unsetOnEcbModeExitResponse(Handler h);
+ /**
+ * TODO: Adding a function for each property is not good.
+ * A fucntion of type getPhoneProp(propType) where propType is an
+ * enum of GSM+CDMA+LTE props would be a better approach.
+ *
+ * Get "Restriction of menu options for manual PLMN selection" bit
+ * status from EF_CSP data, this belongs to "Value Added Services Group".
+ * @return true if this bit is set or EF_CSP data is unavailable,
+ * false otherwise
+ */
+ boolean isCspPlmnEnabled();
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 74601e6..c3c8f5e 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -1018,6 +1018,13 @@
}
}
+ public boolean isCspPlmnEnabled() {
+ // This function should be overridden by the class GSMPhone.
+ // Not implemented in CDMAPhone.
+ logUnexpectedGsmMethodCall("isCspPlmnEnabled");
+ return false;
+ }
+
/**
* Common error logger method for unexpected calls to CDMA-only methods.
*/
@@ -1026,4 +1033,12 @@
Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
"called, CDMAPhone inactive.");
}
+
+ /**
+ * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
+ */
+ private void logUnexpectedGsmMethodCall(String name) {
+ Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
+ "called, GSMPhone inactive.");
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index e1511e6..5e7dcb0 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -839,4 +839,8 @@
public void unsetOnEcbModeExitResponse(Handler h){
mActivePhone.unsetOnEcbModeExitResponse(h);
}
+
+ public boolean isCspPlmnEnabled() {
+ return mActivePhone.isCspPlmnEnabled();
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 3d410fd..569ac5c 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -2339,7 +2339,7 @@
case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCdmaSms(p); break;
- case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseString(p); break;
+ case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseRaw(p); break;
case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
@@ -2481,8 +2481,8 @@
case RIL_UNSOL_STK_SESSION_END:
if (RILJ_LOGD) unsljLog(response);
- if (mStkSessionEndRegistrant != null) {
- mStkSessionEndRegistrant.notifyRegistrant(
+ if (mCatSessionEndRegistrant != null) {
+ mCatSessionEndRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
@@ -2490,8 +2490,8 @@
case RIL_UNSOL_STK_PROACTIVE_COMMAND:
if (RILJ_LOGD) unsljLogRet(response, ret);
- if (mStkProCmdRegistrant != null) {
- mStkProCmdRegistrant.notifyRegistrant(
+ if (mCatProCmdRegistrant != null) {
+ mCatProCmdRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
@@ -2499,8 +2499,8 @@
case RIL_UNSOL_STK_EVENT_NOTIFY:
if (RILJ_LOGD) unsljLogRet(response, ret);
- if (mStkEventRegistrant != null) {
- mStkEventRegistrant.notifyRegistrant(
+ if (mCatEventRegistrant != null) {
+ mCatEventRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
@@ -2508,8 +2508,8 @@
case RIL_UNSOL_STK_CALL_SETUP:
if (RILJ_LOGD) unsljLogRet(response, ret);
- if (mStkCallSetUpRegistrant != null) {
- mStkCallSetUpRegistrant.notifyRegistrant(
+ if (mCatCallSetUpRegistrant != null) {
+ mCatCallSetUpRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
@@ -3406,6 +3406,8 @@
RILRequest rr = RILRequest.obtain(
RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
send(rr);
}
@@ -3419,6 +3421,9 @@
rr.mp.writeInt(1);
rr.mp.writeInt(ttyMode);
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + " : " + ttyMode);
+
send(rr);
}
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
index a636a4b..2f5d3ec 100644
--- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
@@ -24,7 +24,6 @@
import android.util.Config;
import android.util.Log;
-
/**
* WAP push handler class.
*
@@ -59,7 +58,7 @@
*/
public int dispatchWapPdu(byte[] pdu) {
- if (Config.LOGD) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
+ if (Config.DEBUG) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
int index = 0;
int transactionId = pdu[index++] & 0xFF;
@@ -68,7 +67,7 @@
if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
(pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
- if (Config.LOGD) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
+ if (Config.DEBUG) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
return Intents.RESULT_SMS_HANDLED;
}
@@ -81,7 +80,7 @@
* So it will be encoded in no more than 5 octets.
*/
if (pduDecoder.decodeUintvarInteger(index) == false) {
- if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Length error.");
+ if (Config.DEBUG) Log.w(LOG_TAG, "Received PDU. Header Length error.");
return Intents.RESULT_SMS_GENERIC_ERROR;
}
headerLength = (int)pduDecoder.getValue32();
@@ -102,136 +101,44 @@
* Length = Uintvar-integer
*/
if (pduDecoder.decodeContentType(index) == false) {
- if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
+ if (Config.DEBUG) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
return Intents.RESULT_SMS_GENERIC_ERROR;
}
- int binaryContentType;
+
String mimeType = pduDecoder.getValueString();
- if (mimeType == null) {
- binaryContentType = (int)pduDecoder.getValue32();
- // TODO we should have more generic way to map binaryContentType code to mimeType.
- switch (binaryContentType) {
- case WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_XML:
- mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML;
- break;
- case WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_WBXML:
- mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML;
- break;
- case WspTypeDecoder.CONTENT_TYPE_B_PUSH_SI:
- mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SI;
- break;
- case WspTypeDecoder.CONTENT_TYPE_B_PUSH_SL:
- mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SL;
- break;
- case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO:
- mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO;
- break;
- case WspTypeDecoder.CONTENT_TYPE_B_MMS:
- mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS;
- break;
- case WspTypeDecoder.CONTENT_TYPE_B_VND_DOCOMO_PF:
- mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_VND_DOCOMO_PF;
- break;
- default:
- if (Config.LOGD) {
- Log.w(LOG_TAG,
- "Received PDU. Unsupported Content-Type = " + binaryContentType);
- }
- return Intents.RESULT_SMS_HANDLED;
- }
- } else {
- if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML)) {
- binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_XML;
- } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML)) {
- binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_WBXML;
- } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SI)) {
- binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_SI;
- } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SL)) {
- binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_SL;
- } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO)) {
- binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO;
- } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS)) {
- binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_MMS;
- } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_VND_DOCOMO_PF)) {
- binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_VND_DOCOMO_PF;
- } else {
- if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Unknown Content-Type = " + mimeType);
- return Intents.RESULT_SMS_HANDLED;
- }
- }
+
index += pduDecoder.getDecodedDataLength();
- boolean dispatchedByApplication = false;
- switch (binaryContentType) {
- case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO:
- dispatchWapPdu_PushCO(pdu, transactionId, pduType, headerStartIndex, headerLength);
- dispatchedByApplication = true;
- break;
- case WspTypeDecoder.CONTENT_TYPE_B_MMS:
- dispatchWapPdu_MMS(pdu, transactionId, pduType, headerStartIndex, headerLength);
- dispatchedByApplication = true;
- break;
- default:
- break;
- }
- if (dispatchedByApplication == false) {
- dispatchWapPdu_default(pdu, transactionId, pduType, mimeType,
- headerStartIndex, headerLength);
- }
- return Activity.RESULT_OK;
- }
-
- private void dispatchWapPdu_default(byte[] pdu, int transactionId, int pduType,
- String mimeType, int headerStartIndex, int headerLength) {
byte[] header = new byte[headerLength];
System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
- int dataIndex = headerStartIndex + headerLength;
- byte[] data;
- data = new byte[pdu.length - dataIndex];
- System.arraycopy(pdu, dataIndex, data, 0, data.length);
+ byte[] intentData;
+ String permission;
+
+ if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
+ intentData = pdu;
+ } else {
+ int dataIndex = headerStartIndex + headerLength;
+ intentData = new byte[pdu.length - dataIndex];
+ System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
+ }
+
+ if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) {
+ permission = "android.permission.RECEIVE_MMS";
+ } else {
+ permission = "android.permission.RECEIVE_WAP_PUSH";
+ }
Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
intent.setType(mimeType);
intent.putExtra("transactionId", transactionId);
intent.putExtra("pduType", pduType);
intent.putExtra("header", header);
- intent.putExtra("data", data);
+ intent.putExtra("data", intentData);
+ intent.putExtra("contentTypeParameters", pduDecoder.getContentParameters());
- mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
+ mSmsDispatcher.dispatch(intent, permission);
+
+ return Activity.RESULT_OK;
}
-
- private void dispatchWapPdu_PushCO(byte[] pdu, int transactionId, int pduType,
- int headerStartIndex, int headerLength) {
- byte[] header = new byte[headerLength];
- System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
-
- Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
- intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO);
- intent.putExtra("transactionId", transactionId);
- intent.putExtra("pduType", pduType);
- intent.putExtra("header", header);
- intent.putExtra("data", pdu);
-
- mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
- }
-
- private void dispatchWapPdu_MMS(byte[] pdu, int transactionId, int pduType,
- int headerStartIndex, int headerLength) {
- byte[] header = new byte[headerLength];
- System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
- int dataIndex = headerStartIndex + headerLength;
- byte[] data = new byte[pdu.length - dataIndex];
- System.arraycopy(pdu, dataIndex, data, 0, data.length);
-
- Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
- intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS);
- intent.putExtra("transactionId", transactionId);
- intent.putExtra("pduType", pduType);
- intent.putExtra("header", header);
- intent.putExtra("data", data);
-
- mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_MMS");
- }
-}
-
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
index 336bc82..6bf6b13 100644
--- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
+++ b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
@@ -16,11 +16,12 @@
package com.android.internal.telephony;
+import java.util.HashMap;
/**
- * Implement the WSP data type decoder.
+ * Implement the WSP data type decoder.
*
- * @hide
+ * @hide
*/
public class WspTypeDecoder {
@@ -30,35 +31,176 @@
public static final int PDU_TYPE_PUSH = 0x06;
public static final int PDU_TYPE_CONFIRMED_PUSH = 0x07;
- // TODO we should have mapping between those binary code and mime type string.
- // see http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
+ private final static HashMap<Integer, String> WELL_KNOWN_MIME_TYPES =
+ new HashMap<Integer, String>();
- public static final int CONTENT_TYPE_B_DRM_RIGHTS_XML = 0x4a;
- public static final int CONTENT_TYPE_B_DRM_RIGHTS_WBXML = 0x4b;
- public static final int CONTENT_TYPE_B_PUSH_SI = 0x2e;
- public static final int CONTENT_TYPE_B_PUSH_SL = 0x30;
- public static final int CONTENT_TYPE_B_PUSH_CO = 0x32;
- public static final int CONTENT_TYPE_B_MMS = 0x3e;
- public static final int CONTENT_TYPE_B_VND_DOCOMO_PF = 0x0310;
+ private final static HashMap<Integer, String> WELL_KNOWN_PARAMETERS =
+ new HashMap<Integer, String>();
- public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML =
- "application/vnd.oma.drm.rights+xml";
- public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML =
- "application/vnd.oma.drm.rights+wbxml";
- public static final String CONTENT_MIME_TYPE_B_PUSH_SI = "application/vnd.wap.sic";
- public static final String CONTENT_MIME_TYPE_B_PUSH_SL = "application/vnd.wap.slc";
- public static final String CONTENT_MIME_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
- public static final String CONTENT_MIME_TYPE_B_MMS = "application/vnd.wap.mms-message";
- public static final String CONTENT_MIME_TYPE_B_VND_DOCOMO_PF = "application/vnd.docomo.pf";
+ private static final int Q_VALUE = 0x00;
- public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f;
+ static {
+ WELL_KNOWN_MIME_TYPES.put(0x00, "*/*");
+ WELL_KNOWN_MIME_TYPES.put(0x01, "text/*");
+ WELL_KNOWN_MIME_TYPES.put(0x02, "text/html");
+ WELL_KNOWN_MIME_TYPES.put(0x03, "text/plain");
+ WELL_KNOWN_MIME_TYPES.put(0x04, "text/x-hdml");
+ WELL_KNOWN_MIME_TYPES.put(0x05, "text/x-ttml");
+ WELL_KNOWN_MIME_TYPES.put(0x06, "text/x-vCalendar");
+ WELL_KNOWN_MIME_TYPES.put(0x07, "text/x-vCard");
+ WELL_KNOWN_MIME_TYPES.put(0x08, "text/vnd.wap.wml");
+ WELL_KNOWN_MIME_TYPES.put(0x09, "text/vnd.wap.wmlscript");
+ WELL_KNOWN_MIME_TYPES.put(0x0A, "text/vnd.wap.wta-event");
+ WELL_KNOWN_MIME_TYPES.put(0x0B, "multipart/*");
+ WELL_KNOWN_MIME_TYPES.put(0x0C, "multipart/mixed");
+ WELL_KNOWN_MIME_TYPES.put(0x0D, "multipart/form-data");
+ WELL_KNOWN_MIME_TYPES.put(0x0E, "multipart/byterantes");
+ WELL_KNOWN_MIME_TYPES.put(0x0F, "multipart/alternative");
+ WELL_KNOWN_MIME_TYPES.put(0x10, "application/*");
+ WELL_KNOWN_MIME_TYPES.put(0x11, "application/java-vm");
+ WELL_KNOWN_MIME_TYPES.put(0x12, "application/x-www-form-urlencoded");
+ WELL_KNOWN_MIME_TYPES.put(0x13, "application/x-hdmlc");
+ WELL_KNOWN_MIME_TYPES.put(0x14, "application/vnd.wap.wmlc");
+ WELL_KNOWN_MIME_TYPES.put(0x15, "application/vnd.wap.wmlscriptc");
+ WELL_KNOWN_MIME_TYPES.put(0x16, "application/vnd.wap.wta-eventc");
+ WELL_KNOWN_MIME_TYPES.put(0x17, "application/vnd.wap.uaprof");
+ WELL_KNOWN_MIME_TYPES.put(0x18, "application/vnd.wap.wtls-ca-certificate");
+ WELL_KNOWN_MIME_TYPES.put(0x19, "application/vnd.wap.wtls-user-certificate");
+ WELL_KNOWN_MIME_TYPES.put(0x1A, "application/x-x509-ca-cert");
+ WELL_KNOWN_MIME_TYPES.put(0x1B, "application/x-x509-user-cert");
+ WELL_KNOWN_MIME_TYPES.put(0x1C, "image/*");
+ WELL_KNOWN_MIME_TYPES.put(0x1D, "image/gif");
+ WELL_KNOWN_MIME_TYPES.put(0x1E, "image/jpeg");
+ WELL_KNOWN_MIME_TYPES.put(0x1F, "image/tiff");
+ WELL_KNOWN_MIME_TYPES.put(0x20, "image/png");
+ WELL_KNOWN_MIME_TYPES.put(0x21, "image/vnd.wap.wbmp");
+ WELL_KNOWN_MIME_TYPES.put(0x22, "application/vnd.wap.multipart.*");
+ WELL_KNOWN_MIME_TYPES.put(0x23, "application/vnd.wap.multipart.mixed");
+ WELL_KNOWN_MIME_TYPES.put(0x24, "application/vnd.wap.multipart.form-data");
+ WELL_KNOWN_MIME_TYPES.put(0x25, "application/vnd.wap.multipart.byteranges");
+ WELL_KNOWN_MIME_TYPES.put(0x26, "application/vnd.wap.multipart.alternative");
+ WELL_KNOWN_MIME_TYPES.put(0x27, "application/xml");
+ WELL_KNOWN_MIME_TYPES.put(0x28, "text/xml");
+ WELL_KNOWN_MIME_TYPES.put(0x29, "application/vnd.wap.wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x2A, "application/x-x968-cross-cert");
+ WELL_KNOWN_MIME_TYPES.put(0x2B, "application/x-x968-ca-cert");
+ WELL_KNOWN_MIME_TYPES.put(0x2C, "application/x-x968-user-cert");
+ WELL_KNOWN_MIME_TYPES.put(0x2D, "text/vnd.wap.si");
+ WELL_KNOWN_MIME_TYPES.put(0x2E, "application/vnd.wap.sic");
+ WELL_KNOWN_MIME_TYPES.put(0x2F, "text/vnd.wap.sl");
+ WELL_KNOWN_MIME_TYPES.put(0x30, "application/vnd.wap.slc");
+ WELL_KNOWN_MIME_TYPES.put(0x31, "text/vnd.wap.co");
+ WELL_KNOWN_MIME_TYPES.put(0x32, "application/vnd.wap.coc");
+ WELL_KNOWN_MIME_TYPES.put(0x33, "application/vnd.wap.multipart.related");
+ WELL_KNOWN_MIME_TYPES.put(0x34, "application/vnd.wap.sia");
+ WELL_KNOWN_MIME_TYPES.put(0x35, "text/vnd.wap.connectivity-xml");
+ WELL_KNOWN_MIME_TYPES.put(0x36, "application/vnd.wap.connectivity-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x37, "application/pkcs7-mime");
+ WELL_KNOWN_MIME_TYPES.put(0x38, "application/vnd.wap.hashed-certificate");
+ WELL_KNOWN_MIME_TYPES.put(0x39, "application/vnd.wap.signed-certificate");
+ WELL_KNOWN_MIME_TYPES.put(0x3A, "application/vnd.wap.cert-response");
+ WELL_KNOWN_MIME_TYPES.put(0x3B, "application/xhtml+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x3C, "application/wml+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x3D, "text/css");
+ WELL_KNOWN_MIME_TYPES.put(0x3E, "application/vnd.wap.mms-message");
+ WELL_KNOWN_MIME_TYPES.put(0x3F, "application/vnd.wap.rollover-certificate");
+ WELL_KNOWN_MIME_TYPES.put(0x40, "application/vnd.wap.locc+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x41, "application/vnd.wap.loc+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x42, "application/vnd.syncml.dm+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x43, "application/vnd.syncml.dm+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x44, "application/vnd.syncml.notification");
+ WELL_KNOWN_MIME_TYPES.put(0x45, "application/vnd.wap.xhtml+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x46, "application/vnd.wv.csp.cir");
+ WELL_KNOWN_MIME_TYPES.put(0x47, "application/vnd.oma.dd+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x48, "application/vnd.oma.drm.message");
+ WELL_KNOWN_MIME_TYPES.put(0x49, "application/vnd.oma.drm.content");
+ WELL_KNOWN_MIME_TYPES.put(0x4A, "application/vnd.oma.drm.rights+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x4B, "application/vnd.oma.drm.rights+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x4C, "application/vnd.wv.csp+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x4D, "application/vnd.wv.csp+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x4E, "application/vnd.syncml.ds.notification");
+ WELL_KNOWN_MIME_TYPES.put(0x4F, "audio/*");
+ WELL_KNOWN_MIME_TYPES.put(0x50, "video/*");
+ WELL_KNOWN_MIME_TYPES.put(0x51, "application/vnd.oma.dd2+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x52, "application/mikey");
+ WELL_KNOWN_MIME_TYPES.put(0x53, "application/vnd.oma.dcd");
+ WELL_KNOWN_MIME_TYPES.put(0x54, "application/vnd.oma.dcdc");
+ WELL_KNOWN_MIME_TYPES.put(0x0201, "application/vnd.uplanet.cacheop-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0202, "application/vnd.uplanet.signal");
+ WELL_KNOWN_MIME_TYPES.put(0x0203, "application/vnd.uplanet.alert-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0204, "application/vnd.uplanet.list-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0205, "application/vnd.uplanet.listcmd-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0206, "application/vnd.uplanet.channel-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0207, "application/vnd.uplanet.provisioning-status-uri");
+ WELL_KNOWN_MIME_TYPES.put(0x0208, "x-wap.multipart/vnd.uplanet.header-set");
+ WELL_KNOWN_MIME_TYPES.put(0x0209, "application/vnd.uplanet.bearer-choice-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x020A, "application/vnd.phonecom.mmc-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x020B, "application/vnd.nokia.syncset+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x020C, "image/x-up-wpng");
+ WELL_KNOWN_MIME_TYPES.put(0x0300, "application/iota.mmc-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0301, "application/iota.mmc-xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0302, "application/vnd.syncml+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0303, "application/vnd.syncml+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0304, "text/vnd.wap.emn+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0305, "text/calendar");
+ WELL_KNOWN_MIME_TYPES.put(0x0306, "application/vnd.omads-email+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0307, "application/vnd.omads-file+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0308, "application/vnd.omads-folder+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0309, "text/directory;profile=vCard");
+ WELL_KNOWN_MIME_TYPES.put(0x030A, "application/vnd.wap.emn+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x030B, "application/vnd.nokia.ipdc-purchase-response");
+ WELL_KNOWN_MIME_TYPES.put(0x030C, "application/vnd.motorola.screen3+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x030D, "application/vnd.motorola.screen3+gzip");
+ WELL_KNOWN_MIME_TYPES.put(0x030E, "application/vnd.cmcc.setting+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x030F, "application/vnd.cmcc.bombing+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0310, "application/vnd.docomo.pf");
+ WELL_KNOWN_MIME_TYPES.put(0x0311, "application/vnd.docomo.ub");
+ WELL_KNOWN_MIME_TYPES.put(0x0312, "application/vnd.omaloc-supl-init");
+ WELL_KNOWN_MIME_TYPES.put(0x0313, "application/vnd.oma.group-usage-list+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0314, "application/oma-directory+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0315, "application/vnd.docomo.pf2");
+ WELL_KNOWN_MIME_TYPES.put(0x0316, "application/vnd.oma.drm.roap-trigger+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0317, "application/vnd.sbm.mid2");
+ WELL_KNOWN_MIME_TYPES.put(0x0318, "application/vnd.wmf.bootstrap");
+ WELL_KNOWN_MIME_TYPES.put(0x0319, "application/vnc.cmcc.dcd+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x031A, "application/vnd.sbm.cid");
+ WELL_KNOWN_MIME_TYPES.put(0x031B, "application/vnd.oma.bcast.provisioningtrigger");
+
+ WELL_KNOWN_PARAMETERS.put(0x00, "Q");
+ WELL_KNOWN_PARAMETERS.put(0x01, "Charset");
+ WELL_KNOWN_PARAMETERS.put(0x02, "Level");
+ WELL_KNOWN_PARAMETERS.put(0x03, "Type");
+ WELL_KNOWN_PARAMETERS.put(0x07, "Differences");
+ WELL_KNOWN_PARAMETERS.put(0x08, "Padding");
+ WELL_KNOWN_PARAMETERS.put(0x09, "Type");
+ WELL_KNOWN_PARAMETERS.put(0x0E, "Max-Age");
+ WELL_KNOWN_PARAMETERS.put(0x10, "Secure");
+ WELL_KNOWN_PARAMETERS.put(0x11, "SEC");
+ WELL_KNOWN_PARAMETERS.put(0x12, "MAC");
+ WELL_KNOWN_PARAMETERS.put(0x13, "Creation-date");
+ WELL_KNOWN_PARAMETERS.put(0x14, "Modification-date");
+ WELL_KNOWN_PARAMETERS.put(0x15, "Read-date");
+ WELL_KNOWN_PARAMETERS.put(0x16, "Size");
+ WELL_KNOWN_PARAMETERS.put(0x17, "Name");
+ WELL_KNOWN_PARAMETERS.put(0x18, "Filename");
+ WELL_KNOWN_PARAMETERS.put(0x19, "Start");
+ WELL_KNOWN_PARAMETERS.put(0x1A, "Start-info");
+ WELL_KNOWN_PARAMETERS.put(0x1B, "Comment");
+ WELL_KNOWN_PARAMETERS.put(0x1C, "Domain");
+ WELL_KNOWN_PARAMETERS.put(0x1D, "Path");
+ }
+
+ public static final String CONTENT_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
+ public static final String CONTENT_TYPE_B_MMS = "application/vnd.wap.mms-message";
byte[] wspData;
int dataLength;
long unsigned32bit;
String stringValue;
+ HashMap<String, String> contentParameters;
+
public WspTypeDecoder(byte[] pdu) {
wspData = pdu;
}
@@ -69,17 +211,17 @@
* @param startIndex The starting position of the "Text-string" in this pdu
*
* @return false when error(not a Text-string) occur
- * return value can be retrieved by getValueString() method
- * length of data in pdu can be retrieved by getValue32() method
+ * return value can be retrieved by getValueString() method length of data in pdu can be
+ * retrieved by getDecodedDataLength() method
*/
public boolean decodeTextString(int startIndex) {
int index = startIndex;
while (wspData[index] != 0) {
index++;
}
- dataLength = index - startIndex + 1;
+ dataLength = index - startIndex + 1;
if (wspData[startIndex] == 127) {
- stringValue = new String(wspData, startIndex+1, dataLength - 2);
+ stringValue = new String(wspData, startIndex + 1, dataLength - 2);
} else {
stringValue = new String(wspData, startIndex, dataLength - 1);
}
@@ -87,13 +229,33 @@
}
/**
+ * Decode the "Token-text" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Token-text" in this pdu
+ *
+ * @return always true
+ * return value can be retrieved by getValueString() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
+ */
+ public boolean decodeTokenText(int startIndex) {
+ int index = startIndex;
+ while (wspData[index] != 0) {
+ index++;
+ }
+ dataLength = index - startIndex + 1;
+ stringValue = new String(wspData, startIndex, dataLength - 1);
+
+ return true;
+ }
+
+ /**
* Decode the "Short-integer" type for WSP pdu
*
* @param startIndex The starting position of the "Short-integer" in this pdu
*
* @return false when error(not a Short-integer) occur
* return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeShortInteger(int startIndex) {
if ((wspData[startIndex] & 0x80) == 0) {
@@ -111,7 +273,7 @@
*
* @return false when error(not a Long-integer) occur
* return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeLongInteger(int startIndex) {
int lengthMultiOctet = wspData[startIndex] & 0xff;
@@ -120,10 +282,10 @@
return false;
}
unsigned32bit = 0;
- for (int i=1; i<=lengthMultiOctet; i++) {
- unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex+i] & 0xff);
+ for (int i = 1; i <= lengthMultiOctet; i++) {
+ unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex + i] & 0xff);
}
- dataLength = 1+lengthMultiOctet;
+ dataLength = 1 + lengthMultiOctet;
return true;
}
@@ -134,7 +296,7 @@
*
* @return false when error(not a Integer-Value) occur
* return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeIntegerValue(int startIndex) {
if (decodeShortInteger(startIndex) == true) {
@@ -150,10 +312,10 @@
*
* @return false when error(not a Uintvar-integer) occur
* return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeUintvarInteger(int startIndex) {
- int index = startIndex;
+ int index = startIndex;
unsigned32bit = 0;
while ((wspData[index] & 0x80) != 0) {
@@ -175,7 +337,7 @@
*
* @return false when error(not a Value-length) occur
* return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeValueLength(int startIndex) {
if ((wspData[startIndex] & 0xff) > WAP_PDU_LENGTH_QUOTE) {
@@ -185,22 +347,22 @@
unsigned32bit = wspData[startIndex];
dataLength = 1;
} else {
- decodeUintvarInteger(startIndex+1);
- dataLength ++;
+ decodeUintvarInteger(startIndex + 1);
+ dataLength++;
}
return true;
}
/**
- * Decode the "Extension-media" type for WSP PDU.
- *
- * @param startIndex The starting position of the "Extension-media" in this PDU.
- *
- * @return false on error, such as if there is no Extension-media at startIndex.
- * Side-effects: updates stringValue (available with getValueString()), which will be
- * null on error. The length of the data in the PDU is available with getValue32(), 0
- * on error.
- */
+ * Decode the "Extension-media" type for WSP PDU.
+ *
+ * @param startIndex The starting position of the "Extension-media" in this PDU.
+ *
+ * @return false on error, such as if there is no Extension-media at startIndex.
+ * Side-effects: updates stringValue (available with
+ * getValueString()), which will be null on error. The length of the
+ * data in the PDU is available with getValue32(), 0 on error.
+ */
public boolean decodeExtensionMedia(int startIndex) {
int index = startIndex;
dataLength = 0;
@@ -212,7 +374,7 @@
index++;
}
- dataLength = index - startIndex + 1;
+ dataLength = index - startIndex + 1;
stringValue = new String(wspData, startIndex, dataLength - 1);
return rtrn;
@@ -225,7 +387,7 @@
*
* @return false when error(not a Constrained-encoding) occur
* return value can be retrieved first by getValueString() and second by getValue32() method
- * length of data in pdu can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeConstrainedEncoding(int startIndex) {
if (decodeShortInteger(startIndex) == true) {
@@ -240,31 +402,162 @@
*
* @param startIndex The starting position of the "Content-type" in this pdu
*
- * @return false when error(not a Content-type) occur
- * return value can be retrieved first by getValueString() and second by getValue32()
- * method length of data in pdu can be retrieved by getValue32() method
+ * @return false when error(not a Content-type) occurs
+ * If a content type exists in the headers (either as inline string, or as well-known
+ * value), getValueString() will return it. If a 'well known value' is encountered that
+ * cannot be mapped to a string mime type, getValueString() will return null, and
+ * getValue32() will return the unknown content type value.
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
+ * Any content type parameters will be accessible via getContentParameters()
*/
public boolean decodeContentType(int startIndex) {
int mediaPrefixLength;
- long mediaFieldLength;
+ contentParameters = new HashMap<String, String>();
- if (decodeValueLength(startIndex) == false) {
- return decodeConstrainedEncoding(startIndex);
- }
- mediaPrefixLength = getDecodedDataLength();
- mediaFieldLength = getValue32();
- if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) {
- dataLength += mediaPrefixLength;
- stringValue = null;
- return true;
- }
- if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) {
- dataLength += mediaPrefixLength;
- return true;
+ try {
+ if (decodeValueLength(startIndex) == false) {
+ boolean found = decodeConstrainedEncoding(startIndex);
+ if (found) {
+ expandWellKnownMimeType();
+ }
+ return found;
+ }
+ int headersLength = (int) unsigned32bit;
+ mediaPrefixLength = getDecodedDataLength();
+ if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) {
+ dataLength += mediaPrefixLength;
+ int readLength = dataLength;
+ stringValue = null;
+ expandWellKnownMimeType();
+ long wellKnownValue = unsigned32bit;
+ String mimeType = stringValue;
+ if (readContentParameters(startIndex + dataLength,
+ (headersLength - (dataLength - mediaPrefixLength)), 0)) {
+ dataLength += readLength;
+ unsigned32bit = wellKnownValue;
+ stringValue = mimeType;
+ return true;
+ }
+ return false;
+ }
+ if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) {
+ dataLength += mediaPrefixLength;
+ int readLength = dataLength;
+ expandWellKnownMimeType();
+ long wellKnownValue = unsigned32bit;
+ String mimeType = stringValue;
+ if (readContentParameters(startIndex + dataLength,
+ (headersLength - (dataLength - mediaPrefixLength)), 0)) {
+ dataLength += readLength;
+ unsigned32bit = wellKnownValue;
+ stringValue = mimeType;
+ return true;
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //something doesn't add up
+ return false;
}
return false;
}
+ private boolean readContentParameters(int startIndex, int leftToRead, int accumulator) {
+
+ int totalRead = 0;
+
+ if (leftToRead > 0) {
+ byte nextByte = wspData[startIndex];
+ String value = null;
+ String param = null;
+ if ((nextByte & 0x80) == 0x00 && nextByte > 31) { // untyped
+ decodeTokenText(startIndex);
+ param = stringValue;
+ totalRead += dataLength;
+ } else { // typed
+ if (decodeIntegerValue(startIndex)) {
+ totalRead += dataLength;
+ int wellKnownParameterValue = (int) unsigned32bit;
+ param = WELL_KNOWN_PARAMETERS.get(wellKnownParameterValue);
+ if (param == null) {
+ param = "unassigned/0x" + Long.toHexString(wellKnownParameterValue);
+ }
+ // special case for the "Q" parameter, value is a uintvar
+ if (wellKnownParameterValue == Q_VALUE) {
+ if (decodeUintvarInteger(startIndex + totalRead)) {
+ totalRead += dataLength;
+ value = String.valueOf(unsigned32bit);
+ contentParameters.put(param, value);
+ return readContentParameters(startIndex + totalRead, leftToRead
+ - totalRead, accumulator + totalRead);
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+
+ if (decodeNoValue(startIndex + totalRead)) {
+ totalRead += dataLength;
+ value = null;
+ } else if (decodeIntegerValue(startIndex + totalRead)) {
+ totalRead += dataLength;
+ int intValue = (int) unsigned32bit;
+ if (intValue == 0) {
+ value = "";
+ } else {
+ value = String.valueOf(intValue);
+ }
+ } else {
+ decodeTokenText(startIndex + totalRead);
+ totalRead += dataLength;
+ value = stringValue;
+ if (value.startsWith("\"")) {
+ // quoted string, so remove the quote
+ value = value.substring(1);
+ }
+ }
+ contentParameters.put(param, value);
+ return readContentParameters(startIndex + totalRead, leftToRead - totalRead,
+ accumulator + totalRead);
+
+ } else {
+ dataLength = accumulator;
+ return true;
+ }
+ }
+
+ /**
+ * Check if the next byte is No-Value
+ *
+ * @param startIndex The starting position of the "Content length" in this pdu
+ *
+ * @return true if and only if the next byte is 0x00
+ */
+ private boolean decodeNoValue(int startIndex) {
+ if (wspData[startIndex] == 0) {
+ dataLength = 1;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Populate stringValue with the mime type corresponding to the value in unsigned32bit
+ *
+ * Sets unsigned32bit to -1 if stringValue is already populated
+ */
+ private void expandWellKnownMimeType() {
+ if (stringValue == null) {
+ int binaryContentType = (int) unsigned32bit;
+ stringValue = WELL_KNOWN_MIME_TYPES.get(binaryContentType);
+ } else {
+ unsigned32bit = -1;
+ }
+ }
+
/**
* Decode the "Content length" type for WSP pdu
*
@@ -272,7 +565,7 @@
*
* @return false when error(not a Content length) occur
* return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeContentLength(int startIndex) {
return decodeIntegerValue(startIndex);
@@ -285,7 +578,7 @@
*
* @return false when error(not a Content location) occur
* return value can be retrieved by getValueString() method
- * length of data in pdu can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeContentLocation(int startIndex) {
return decodeTextString(startIndex);
@@ -298,7 +591,8 @@
*
* @return false when error(not a X-Wap-Application-Id) occur
* return value can be retrieved first by getValueString() and second by getValue32()
- * method length of data in pdu can be retrieved by getValue32() method
+ * method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeXWapApplicationId(int startIndex) {
if (decodeIntegerValue(startIndex) == true) {
@@ -315,7 +609,7 @@
*
* @return false when error(not a X-Wap-Content-URI) occur
* return value can be retrieved by getValueString() method
- * length of data in pdu can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeXWapContentURI(int startIndex) {
return decodeTextString(startIndex);
@@ -328,7 +622,7 @@
*
* @return false when error(not a X-Wap-Initiator-URI) occur
* return value can be retrieved by getValueString() method
- * length of data in pdu can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeXWapInitiatorURI(int startIndex) {
return decodeTextString(startIndex);
@@ -354,4 +648,18 @@
public String getValueString() {
return stringValue;
}
+
+ /**
+ * Any parameters encountered as part of a decodeContentType() invocation.
+ *
+ * @return a map of content parameters keyed by their names, or null if
+ * decodeContentType() has not been called If any unassigned
+ * well-known parameters are encountered, the key of the map will be
+ * 'unassigned/0x...', where '...' is the hex value of the
+ * unassigned parameter. If a parameter has No-Value the value will be null.
+ *
+ */
+ public HashMap<String, String> getContentParameters() {
+ return contentParameters;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java b/telephony/java/com/android/internal/telephony/cat/AppInterface.java
similarity index 86%
rename from telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
rename to telephony/java/com/android/internal/telephony/cat/AppInterface.java
index 58f1f97..2eb6ccb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
+++ b/telephony/java/com/android/internal/telephony/cat/AppInterface.java
@@ -14,29 +14,29 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
- * Interface for communication between STK App and STK Telephony
+ * Interface for communication between STK App and CAT Telephony
*
* {@hide}
*/
public interface AppInterface {
/*
- * Intent's actions which are broadcasted by the Telephony once a new STK
+ * Intent's actions which are broadcasted by the Telephony once a new CAT
* proactive command, session end arrive.
*/
- public static final String STK_CMD_ACTION =
+ public static final String CAT_CMD_ACTION =
"android.intent.action.stk.command";
- public static final String STK_SESSION_END_ACTION =
+ public static final String CAT_SESSION_END_ACTION =
"android.intent.action.stk.session_end";
/*
* Callback function from app to telephony to pass a result code and user's
- * input back to the SIM.
+ * input back to the ICC.
*/
- void onCmdResponse(StkResponseMessage resMsg);
+ void onCmdResponse(CatResponseMessage resMsg);
/*
* Enumeration for representing "Type of Command" of proactive commands.
@@ -58,7 +58,8 @@
SET_UP_EVENT_LIST(0x05),
SET_UP_IDLE_MODE_TEXT(0x28),
SET_UP_MENU(0x25),
- SET_UP_CALL(0x10);
+ SET_UP_CALL(0x10),
+ PROVIDE_LOCAL_INFORMATION(0x26);
private int mValue;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java b/telephony/java/com/android/internal/telephony/cat/BerTlv.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java
rename to telephony/java/com/android/internal/telephony/cat/BerTlv.java
index 19d3279..774bfa3 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java
+++ b/telephony/java/com/android/internal/telephony/cat/BerTlv.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import java.util.List;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
similarity index 89%
rename from telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java
rename to telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
index 5425a43..5155bb2 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.os.Parcel;
import android.os.Parcelable;
/**
- * Class used to pass STK messages from telephony to application. Application
+ * Class used to pass CAT messages from telephony to application. Application
* should call getXXX() to get commands's specific values.
*
*/
-public class StkCmdMessage implements Parcelable {
+public class CatCmdMessage implements Parcelable {
// members
CommandDetails mCmdDet;
private TextMessage mTextMsg;
@@ -50,7 +50,7 @@
public TextMessage callMsg;
}
- StkCmdMessage(CommandParams cmdParams) {
+ CatCmdMessage(CommandParams cmdParams) {
mCmdDet = cmdParams.cmdDet;
switch(getCmdType()) {
case SET_UP_MENU:
@@ -88,7 +88,7 @@
}
}
- public StkCmdMessage(Parcel in) {
+ public CatCmdMessage(Parcel in) {
mCmdDet = in.readParcelable(null);
mTextMsg = in.readParcelable(null);
mMenu = in.readParcelable(null);
@@ -130,13 +130,13 @@
}
}
- public static final Parcelable.Creator<StkCmdMessage> CREATOR = new Parcelable.Creator<StkCmdMessage>() {
- public StkCmdMessage createFromParcel(Parcel in) {
- return new StkCmdMessage(in);
+ public static final Parcelable.Creator<CatCmdMessage> CREATOR = new Parcelable.Creator<CatCmdMessage>() {
+ public CatCmdMessage createFromParcel(Parcel in) {
+ return new CatCmdMessage(in);
}
- public StkCmdMessage[] newArray(int size) {
- return new StkCmdMessage[size];
+ public CatCmdMessage[] newArray(int size) {
+ return new CatCmdMessage[size];
}
};
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java b/telephony/java/com/android/internal/telephony/cat/CatException.java
similarity index 80%
rename from telephony/java/com/android/internal/telephony/gsm/stk/StkException.java
rename to telephony/java/com/android/internal/telephony/cat/CatException.java
index 86de366..1bf1369 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatException.java
@@ -14,18 +14,18 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.util.AndroidException;
/**
- * Base class for all the exceptions in STK service.
+ * Base class for all the exceptions in CAT service.
*
* {@hide}
*/
-class StkException extends AndroidException {
- public StkException() {
+class CatException extends AndroidException {
+ public CatException() {
super();
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java b/telephony/java/com/android/internal/telephony/cat/CatLog.java
similarity index 84%
rename from telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java
rename to telephony/java/com/android/internal/telephony/cat/CatLog.java
index bd6bc8f..e19ff43 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatLog.java
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.util.Log;
-public abstract class StkLog {
+public abstract class CatLog {
static final boolean DEBUG = true;
public static void d(Object caller, String msg) {
@@ -27,7 +27,7 @@
}
String className = caller.getClass().getName();
- Log.d("STK", className.substring(className.lastIndexOf('.') + 1) + ": "
+ Log.d("CAT", className.substring(className.lastIndexOf('.') + 1) + ": "
+ msg);
}
@@ -36,6 +36,6 @@
return;
}
- Log.d("STK", caller + ": " + msg);
+ Log.d("CAT", caller + ": " + msg);
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java b/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
similarity index 91%
rename from telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java
rename to telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
index 04a52e6..cfcac36 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
-public class StkResponseMessage {
+public class CatResponseMessage {
CommandDetails cmdDet = null;
ResultCode resCode = ResultCode.OK;
int usersMenuSelection = 0;
@@ -24,7 +24,7 @@
boolean usersYesNoSelection = false;
boolean usersConfirm = false;
- public StkResponseMessage(StkCmdMessage cmdMsg) {
+ public CatResponseMessage(CatCmdMessage cmdMsg) {
this.cmdDet = cmdMsg.mCmdDet;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java b/telephony/java/com/android/internal/telephony/cat/CatService.java
similarity index 68%
rename from telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
rename to telephony/java/com/android/internal/telephony/cat/CatService.java
index 29ed95c..1e23e34 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.content.Context;
import android.content.Intent;
@@ -22,12 +22,13 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
+import android.os.SystemProperties;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.gsm.SimCard;
-import com.android.internal.telephony.gsm.SIMFileHandler;
-import com.android.internal.telephony.gsm.SIMRecords;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccFileHandler;
+import com.android.internal.telephony.IccRecords;
import android.util.Config;
@@ -111,17 +112,17 @@
*
* {@hide}
*/
-public class StkService extends Handler implements AppInterface {
+public class CatService extends Handler implements AppInterface {
// Class members
- private static SIMRecords mSimRecords;
+ private static IccRecords mIccRecords;
// Service members.
- private static StkService sInstance;
+ private static CatService sInstance;
private CommandsInterface mCmdIf;
private Context mContext;
- private StkCmdMessage mCurrntCmd = null;
- private StkCmdMessage mMenuCmd = null;
+ private CatCmdMessage mCurrntCmd = null;
+ private CatCmdMessage mMenuCmd = null;
private RilMessageDecoder mMsgDecoder = null;
@@ -136,7 +137,7 @@
static final int MSG_ID_RIL_MSG_DECODED = 10;
// Events to signal SIM presence or absent in the device.
- private static final int MSG_ID_SIM_LOADED = 20;
+ private static final int MSG_ID_ICC_RECORDS_LOADED = 20;
private static final int DEV_ID_KEYPAD = 0x01;
private static final int DEV_ID_DISPLAY = 0x02;
@@ -146,10 +147,10 @@
private static final int DEV_ID_NETWORK = 0x83;
/* Intentionally private for singleton */
- private StkService(CommandsInterface ci, SIMRecords sr, Context context,
- SIMFileHandler fh, SimCard sc) {
- if (ci == null || sr == null || context == null || fh == null
- || sc == null) {
+ private CatService(CommandsInterface ci, IccRecords ir, Context context,
+ IccFileHandler fh, IccCard ic) {
+ if (ci == null || ir == null || context == null || fh == null
+ || ic == null) {
throw new NullPointerException(
"Service: Input parameters must not be null");
}
@@ -160,33 +161,33 @@
mMsgDecoder = RilMessageDecoder.getInstance(this, fh);
// Register ril events handling.
- mCmdIf.setOnStkSessionEnd(this, MSG_ID_SESSION_END, null);
- mCmdIf.setOnStkProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null);
- mCmdIf.setOnStkEvent(this, MSG_ID_EVENT_NOTIFY, null);
- mCmdIf.setOnStkCallSetUp(this, MSG_ID_CALL_SETUP, null);
+ mCmdIf.setOnCatSessionEnd(this, MSG_ID_SESSION_END, null);
+ mCmdIf.setOnCatProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null);
+ mCmdIf.setOnCatEvent(this, MSG_ID_EVENT_NOTIFY, null);
+ mCmdIf.setOnCatCallSetUp(this, MSG_ID_CALL_SETUP, null);
//mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null);
- mSimRecords = sr;
+ mIccRecords = ir;
// Register for SIM ready event.
- mSimRecords.registerForRecordsLoaded(this, MSG_ID_SIM_LOADED, null);
+ mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
mCmdIf.reportStkServiceIsRunning(null);
- StkLog.d(this, "StkService: is running");
+ CatLog.d(this, "Is running");
}
public void dispose() {
- mSimRecords.unregisterForRecordsLoaded(this);
- mCmdIf.unSetOnStkSessionEnd(this);
- mCmdIf.unSetOnStkProactiveCmd(this);
- mCmdIf.unSetOnStkEvent(this);
- mCmdIf.unSetOnStkCallSetUp(this);
+ mIccRecords.unregisterForRecordsLoaded(this);
+ mCmdIf.unSetOnCatSessionEnd(this);
+ mCmdIf.unSetOnCatProactiveCmd(this);
+ mCmdIf.unSetOnCatEvent(this);
+ mCmdIf.unSetOnCatCallSetUp(this);
this.removeCallbacksAndMessages(null);
}
protected void finalize() {
- StkLog.d(this, "Service finalized");
+ CatLog.d(this, "Service finalized");
}
private void handleRilMsg(RilMessage rilMsg) {
@@ -241,55 +242,53 @@
*
*/
private void handleProactiveCommand(CommandParams cmdParams) {
- StkLog.d(this, cmdParams.getCommandType().name());
+ CatLog.d(this, cmdParams.getCommandType().name());
- StkCmdMessage cmdMsg = new StkCmdMessage(cmdParams);
+ CatCmdMessage cmdMsg = new CatCmdMessage(cmdParams);
switch (cmdParams.getCommandType()) {
- case SET_UP_MENU:
- if (removeMenu(cmdMsg.getMenu())) {
- mMenuCmd = null;
- } else {
- mMenuCmd = cmdMsg;
- }
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0,
- null);
- break;
- case DISPLAY_TEXT:
- // when application is not required to respond, send an immediate
- // response.
- if (!cmdMsg.geTextMessage().responseNeeded) {
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false,
- 0, null);
- }
- break;
- case REFRESH:
- // ME side only handles refresh commands which meant to remove IDLE
- // MODE TEXT.
- cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT
- .value();
- break;
- case SET_UP_IDLE_MODE_TEXT:
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false,
- 0, null);
- break;
- case LAUNCH_BROWSER:
- case SELECT_ITEM:
- case GET_INPUT:
- case GET_INKEY:
- case SEND_DTMF:
- case SEND_SMS:
- case SEND_SS:
- case SEND_USSD:
- case PLAY_TONE:
- case SET_UP_CALL:
- // nothing to do on telephony!
- break;
- default:
- StkLog.d(this, "Unsupported command");
- return;
+ case SET_UP_MENU:
+ if (removeMenu(cmdMsg.getMenu())) {
+ mMenuCmd = null;
+ } else {
+ mMenuCmd = cmdMsg;
+ }
+ sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+ break;
+ case DISPLAY_TEXT:
+ // when application is not required to respond, send an immediate response.
+ if (!cmdMsg.geTextMessage().responseNeeded) {
+ sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+ }
+ break;
+ case REFRESH:
+ // ME side only handles refresh commands which meant to remove IDLE
+ // MODE TEXT.
+ cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value();
+ break;
+ case SET_UP_IDLE_MODE_TEXT:
+ sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+ break;
+ case PROVIDE_LOCAL_INFORMATION:
+ sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+ return;
+ case LAUNCH_BROWSER:
+ case SELECT_ITEM:
+ case GET_INPUT:
+ case GET_INKEY:
+ case SEND_DTMF:
+ case SEND_SMS:
+ case SEND_SS:
+ case SEND_USSD:
+ case PLAY_TONE:
+ case SET_UP_CALL:
+ // nothing to do on telephony!
+ break;
+ default:
+ CatLog.d(this, "Unsupported command");
+ return;
}
mCurrntCmd = cmdMsg;
- Intent intent = new Intent(AppInterface.STK_CMD_ACTION);
+ Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
intent.putExtra("STK CMD", cmdMsg);
mContext.sendBroadcast(intent);
}
@@ -299,10 +298,10 @@
*
*/
private void handleSessionEnd() {
- StkLog.d(this, "SESSION END");
+ CatLog.d(this, "SESSION END");
mCurrntCmd = mMenuCmd;
- Intent intent = new Intent(AppInterface.STK_SESSION_END_ACTION);
+ Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION);
mContext.sendBroadcast(intent);
}
@@ -315,6 +314,11 @@
}
ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ Input cmdInput = null;
+ if (mCurrntCmd != null) {
+ cmdInput = mCurrntCmd.geInput();
+ }
+
// command details
int tag = ComprehensionTlvTag.COMMAND_DETAILS.value();
if (cmdDet.compRequired) {
@@ -327,7 +331,13 @@
buf.write(cmdDet.commandQualifier);
// device identities
- tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
+ // According to TS102.223/TS31.111 section 6.8 Structure of
+ // TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N,
+ // the ME should set the CR(comprehension required) flag to
+ // comprehension not required.(CR=0)"
+ // Since DEVICE_IDENTITIES and DURATION TLVs have Min=N,
+ // the CR flag is not set.
+ tag = ComprehensionTlvTag.DEVICE_IDENTITIES.value();
buf.write(tag);
buf.write(0x02); // length
buf.write(DEV_ID_TERMINAL); // source device id
@@ -348,17 +358,65 @@
// Fill optional data for each corresponding command
if (resp != null) {
resp.format(buf);
+ } else {
+ encodeOptionalTags(cmdDet, resultCode, cmdInput, buf);
}
byte[] rawData = buf.toByteArray();
String hexString = IccUtils.bytesToHexString(rawData);
if (Config.LOGD) {
- StkLog.d(this, "TERMINAL RESPONSE: " + hexString);
+ CatLog.d(this, "TERMINAL RESPONSE: " + hexString);
}
mCmdIf.sendTerminalResponse(hexString, null);
}
+ private void encodeOptionalTags(CommandDetails cmdDet,
+ ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) {
+ switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) {
+ case GET_INKEY:
+ // ETSI TS 102 384,27.22.4.2.8.4.2.
+ // If it is a response for GET_INKEY command and the response timeout
+ // occured, then add DURATION TLV for variable timeout case.
+ if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) &&
+ (cmdInput != null) && (cmdInput.duration != null)) {
+ getInKeyResponse(buf, cmdInput);
+ }
+ break;
+ case PROVIDE_LOCAL_INFORMATION:
+ if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) &&
+ (resultCode.value() == ResultCode.OK.value())) {
+ getPliResponse(buf);
+ }
+ break;
+ default:
+ CatLog.d(this, "encodeOptionalTags() Unsupported Cmd:" + cmdDet.typeOfCommand);
+ break;
+ }
+ }
+
+ private void getInKeyResponse(ByteArrayOutputStream buf, Input cmdInput) {
+ int tag = ComprehensionTlvTag.DURATION.value();
+
+ buf.write(tag);
+ buf.write(0x02); // length
+ buf.write(cmdInput.duration.timeUnit.SECOND.value()); // Time (Unit,Seconds)
+ buf.write(cmdInput.duration.timeInterval); // Time Duration
+ }
+
+ private void getPliResponse(ByteArrayOutputStream buf) {
+
+ // Locale Language Setting
+ String lang = SystemProperties.get("persist.sys.language");
+
+ if (lang != null) {
+ // tag
+ int tag = ComprehensionTlvTag.LANGUAGE.value();
+ buf.write(tag);
+ ResponseData.writeLength(buf, lang.length());
+ buf.write(lang.getBytes(), 0, lang.length());
+ }
+ }
private void sendMenuSelection(int menuId, boolean helpRequired) {
@@ -446,35 +504,35 @@
}
/**
- * Used for instantiating/updating the Service from the GsmPhone constructor.
+ * Used for instantiating/updating the Service from the GsmPhone or CdmaPhone constructor.
*
* @param ci CommandsInterface object
- * @param sr SIMRecords object
+ * @param ir IccRecords object
* @param context phone app context
- * @param fh SIM file handler
- * @param sc GSM SIM card
+ * @param fh Icc file handler
+ * @param ic Icc card
* @return The only Service object in the system
*/
- public static StkService getInstance(CommandsInterface ci, SIMRecords sr,
- Context context, SIMFileHandler fh, SimCard sc) {
+ public static CatService getInstance(CommandsInterface ci, IccRecords ir,
+ Context context, IccFileHandler fh, IccCard ic) {
if (sInstance == null) {
- if (ci == null || sr == null || context == null || fh == null
- || sc == null) {
+ if (ci == null || ir == null || context == null || fh == null
+ || ic == null) {
return null;
}
- HandlerThread thread = new HandlerThread("Stk Telephony service");
+ HandlerThread thread = new HandlerThread("Cat Telephony service");
thread.start();
- sInstance = new StkService(ci, sr, context, fh, sc);
- StkLog.d(sInstance, "NEW sInstance");
- } else if ((sr != null) && (mSimRecords != sr)) {
- StkLog.d(sInstance, "Reinitialize the Service with SIMRecords");
- mSimRecords = sr;
+ sInstance = new CatService(ci, ir, context, fh, ic);
+ CatLog.d(sInstance, "NEW sInstance");
+ } else if ((ir != null) && (mIccRecords != ir)) {
+ CatLog.d(sInstance, "Reinitialize the Service with SIMRecords");
+ mIccRecords = ir;
// re-Register for SIM ready event.
- mSimRecords.registerForRecordsLoaded(sInstance, MSG_ID_SIM_LOADED, null);
- StkLog.d(sInstance, "sr changed reinitialize and return current sInstance");
+ mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null);
+ CatLog.d(sInstance, "sr changed reinitialize and return current sInstance");
} else {
- StkLog.d(sInstance, "Return current sInstance");
+ CatLog.d(sInstance, "Return current sInstance");
}
return sInstance;
}
@@ -496,7 +554,7 @@
case MSG_ID_PROACTIVE_COMMAND:
case MSG_ID_EVENT_NOTIFY:
case MSG_ID_REFRESH:
- StkLog.d(this, "ril message arrived");
+ CatLog.d(this, "ril message arrived");
String data = null;
if (msg.obj != null) {
AsyncResult ar = (AsyncResult) msg.obj;
@@ -513,20 +571,20 @@
case MSG_ID_CALL_SETUP:
mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null));
break;
- case MSG_ID_SIM_LOADED:
+ case MSG_ID_ICC_RECORDS_LOADED:
break;
case MSG_ID_RIL_MSG_DECODED:
handleRilMsg((RilMessage) msg.obj);
break;
case MSG_ID_RESPONSE:
- handleCmdResponse((StkResponseMessage) msg.obj);
+ handleCmdResponse((CatResponseMessage) msg.obj);
break;
default:
- throw new AssertionError("Unrecognized STK command: " + msg.what);
+ throw new AssertionError("Unrecognized CAT command: " + msg.what);
}
}
- public synchronized void onCmdResponse(StkResponseMessage resMsg) {
+ public synchronized void onCmdResponse(CatResponseMessage resMsg) {
if (resMsg == null) {
return;
}
@@ -535,7 +593,7 @@
msg.sendToTarget();
}
- private boolean validateResponse(StkResponseMessage resMsg) {
+ private boolean validateResponse(CatResponseMessage resMsg) {
if (mCurrntCmd != null) {
return (resMsg.cmdDet.compareTo(mCurrntCmd.mCmdDet));
}
@@ -548,13 +606,13 @@
return true;
}
} catch (NullPointerException e) {
- StkLog.d(this, "Unable to get Menu's items size");
+ CatLog.d(this, "Unable to get Menu's items size");
return true;
}
return false;
}
- private void handleCmdResponse(StkResponseMessage resMsg) {
+ private void handleCmdResponse(CatResponseMessage resMsg) {
// Make sure the response details match the last valid command. An invalid
// response is a one that doesn't have a corresponding proactive command
// and sending it can "confuse" the baseband/ril.
@@ -563,7 +621,7 @@
// by the framework inside the history stack. That activity will be
// available for relaunch using the latest application dialog
// (long press on the home button). Relaunching that activity can send
- // the same command's result again to the StkService and can cause it to
+ // the same command's result again to the CatService and can cause it to
// get out of sync with the SIM.
if (!validateResponse(resMsg)) {
return;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java
rename to telephony/java/com/android/internal/telephony/cat/CommandDetails.java
index e81ff98..e3f0798 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java b/telephony/java/com/android/internal/telephony/cat/CommandParams.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
rename to telephony/java/com/android/internal/telephony/cat/CommandParams.java
index 3da652f..22a5c8c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandParams.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
similarity index 92%
rename from telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java
rename to telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
index ce4c459..12204a0 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.gsm.SIMFileHandler;
+import com.android.internal.telephony.IccFileHandler;
import java.util.Iterator;
import java.util.List;
@@ -52,8 +52,11 @@
static final int REFRESH_NAA_INIT = 0x03;
static final int REFRESH_UICC_RESET = 0x04;
+ // Command Qualifier values for PLI command
+ static final int LANGUAGE_SETTING = 0x04;
+
static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller,
- SIMFileHandler fh) {
+ IccFileHandler fh) {
if (sInstance != null) {
return sInstance;
}
@@ -63,7 +66,7 @@
return null;
}
- private CommandParamsFactory(RilMessageDecoder caller, SIMFileHandler fh) {
+ private CommandParamsFactory(RilMessageDecoder caller, IccFileHandler fh) {
mCaller = caller;
mIconLoader = IconLoader.getInstance(this, fh);
}
@@ -79,7 +82,7 @@
try {
cmdDet = ValueParser.retrieveCommandDetails(ctlvCmdDet);
} catch (ResultException e) {
- StkLog.d(this, "Failed to procees command details");
+ CatLog.d(this, "Failed to procees command details");
}
}
}
@@ -112,7 +115,10 @@
AppInterface.CommandType cmdType = AppInterface.CommandType
.fromInt(cmdDet.typeOfCommand);
if (cmdType == null) {
- sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
+ // This PROACTIVE COMMAND is presently not handled. Hence set
+ // result code as BEYOND_TERMINAL_CAPABILITY in TR.
+ mCmdParams = new CommandParams(cmdDet);
+ sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
return;
}
@@ -155,10 +161,13 @@
case PLAY_TONE:
cmdPending = processPlayTone(cmdDet, ctlvs);
break;
+ case PROVIDE_LOCAL_INFORMATION:
+ cmdPending = processProvideLocalInfo(cmdDet, ctlvs);
+ break;
default:
// unsupported proactive commands
mCmdParams = new CommandParams(cmdDet);
- sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
+ sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
return;
}
} catch (ResultException e) {
@@ -259,7 +268,7 @@
List<ComprehensionTlv> ctlvs)
throws ResultException {
- StkLog.d(this, "process DisplayText");
+ CatLog.d(this, "process DisplayText");
TextMessage textMsg = new TextMessage();
IconId iconId = null;
@@ -319,7 +328,7 @@
private boolean processSetUpIdleModeText(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process SetUpIdleModeText");
+ CatLog.d(this, "process SetUpIdleModeText");
TextMessage textMsg = new TextMessage();
IconId iconId = null;
@@ -362,7 +371,7 @@
private boolean processGetInkey(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process GetInkey");
+ CatLog.d(this, "process GetInkey");
Input input = new Input();
IconId iconId = null;
@@ -380,6 +389,12 @@
iconId = ValueParser.retrieveIconId(ctlv);
}
+ // parse duration
+ ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
+ if (ctlv != null) {
+ input.duration = ValueParser.retrieveDuration(ctlv);
+ }
+
input.minLen = 1;
input.maxLen = 1;
@@ -412,7 +427,7 @@
private boolean processGetInput(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process GetInput");
+ CatLog.d(this, "process GetInput");
Input input = new Input();
IconId iconId = null;
@@ -476,7 +491,7 @@
private boolean processRefresh(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) {
- StkLog.d(this, "process Refresh");
+ CatLog.d(this, "process Refresh");
// REFRESH proactive command is rerouted by the baseband and handled by
// the telephony layer. IDLE TEXT should be removed for a REFRESH command
@@ -505,7 +520,7 @@
private boolean processSelectItem(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process SelectItem");
+ CatLog.d(this, "process SelectItem");
Menu menu = new Menu();
IconId titleIconId = null;
@@ -534,7 +549,7 @@
ctlv = searchForTag(ComprehensionTlvTag.ITEM_ID, ctlvs);
if (ctlv != null) {
- // STK items are listed 1...n while list start at 0, need to
+ // CAT items are listed 1...n while list start at 0, need to
// subtract one.
menu.defaultItem = ValueParser.retrieveItemId(ctlv) - 1;
}
@@ -602,7 +617,7 @@
private boolean processEventNotify(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process EventNotify");
+ CatLog.d(this, "process EventNotify");
TextMessage textMsg = new TextMessage();
IconId iconId = null;
@@ -645,7 +660,7 @@
private boolean processSetUpEventList(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) {
- StkLog.d(this, "process SetUpEventList");
+ CatLog.d(this, "process SetUpEventList");
//
// ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.EVENT_LIST,
// ctlvs);
@@ -670,10 +685,10 @@
* asynchronous processing is required.
* @throws ResultException
*/
- private boolean processLaunchBrowser(CommandDetails cmdDet,
+ private boolean processLaunchBrowser(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process LaunchBrowser");
+ CatLog.d(this, "process LaunchBrowser");
TextMessage confirmMsg = new TextMessage();
IconId iconId = null;
@@ -744,10 +759,10 @@
* asynchronous processing is required.t
* @throws ResultException
*/
- private boolean processPlayTone(CommandDetails cmdDet,
+ private boolean processPlayTone(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process PlayTone");
+ CatLog.d(this, "process PlayTone");
Tone tone = null;
TextMessage textMsg = new TextMessage();
@@ -810,9 +825,9 @@
* @return true if the command is processing is pending and additional
* asynchronous processing is required.
*/
- private boolean processSetupCall(CommandDetails cmdDet,
+ private boolean processSetupCall(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process SetupCall");
+ CatLog.d(this, "process SetupCall");
Iterator<ComprehensionTlv> iter = ctlvs.iterator();
ComprehensionTlv ctlv = null;
@@ -863,4 +878,20 @@
}
return false;
}
+
+ private boolean processProvideLocalInfo(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
+ throws ResultException {
+ CatLog.d(this, "process ProvideLocalInfo");
+ switch (cmdDet.commandQualifier) {
+ case LANGUAGE_SETTING:
+ CatLog.d(this, "PLI [LANGUAGE_SETTING]");
+ mCmdParams = new CommandParams(cmdDet);
+ break;
+ default:
+ CatLog.d(this, "PLI[" + cmdDet.commandQualifier + "] Command Not Supported");
+ mCmdParams = new CommandParams(cmdDet);
+ throw new ResultException(ResultCode.BEYOND_TERMINAL_CAPABILITY);
+ }
+ return false;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
rename to telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
index ffde6a3..99f662d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
+++ b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import java.util.ArrayList;
import java.util.List;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java b/telephony/java/com/android/internal/telephony/cat/Duration.java
similarity index 94%
rename from telephony/java/com/android/internal/telephony/gsm/stk/Duration.java
rename to telephony/java/com/android/internal/telephony/cat/Duration.java
index 9d8cc97..e8cd404 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java
+++ b/telephony/java/com/android/internal/telephony/cat/Duration.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.os.Parcel;
import android.os.Parcelable;
/**
- * Class for representing "Duration" object for STK.
+ * Class for representing "Duration" object for CAT.
*
* {@hide}
*/
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java b/telephony/java/com/android/internal/telephony/cat/FontSize.java
similarity index 96%
rename from telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java
rename to telephony/java/com/android/internal/telephony/cat/FontSize.java
index bd4f49f..02c7ea0 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java
+++ b/telephony/java/com/android/internal/telephony/cat/FontSize.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java b/telephony/java/com/android/internal/telephony/cat/IconLoader.java
similarity index 95%
rename from telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java
rename to telephony/java/com/android/internal/telephony/cat/IconLoader.java
index fc02d2a..2fa1811 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java
+++ b/telephony/java/com/android/internal/telephony/cat/IconLoader.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
-import com.android.internal.telephony.gsm.SIMFileHandler;
+import com.android.internal.telephony.IccFileHandler;
import android.graphics.Bitmap;
import android.graphics.Color;
@@ -40,7 +40,7 @@
private ImageDescriptor mId = null;
private Bitmap mCurrentIcon = null;
private int mRecordNumber;
- private SIMFileHandler mSimFH = null;
+ private IccFileHandler mSimFH = null;
private Message mEndMsg = null;
private byte[] mIconData = null;
// multi icons state members
@@ -68,19 +68,19 @@
private static final int CLUT_ENTRY_SIZE = 3;
- private IconLoader(Looper looper , SIMFileHandler fh) {
+ private IconLoader(Looper looper , IccFileHandler fh) {
super(looper);
mSimFH = fh;
mIconsCache = new HashMap<Integer, Bitmap>(50);
}
- static IconLoader getInstance(Handler caller, SIMFileHandler fh) {
+ static IconLoader getInstance(Handler caller, IccFileHandler fh) {
if (sLoader != null) {
return sLoader;
}
if (fh != null) {
- HandlerThread thread = new HandlerThread("Stk Icon Loader");
+ HandlerThread thread = new HandlerThread("Cat Icon Loader");
thread.start();
return new IconLoader(thread.getLooper(), fh);
}
@@ -163,7 +163,7 @@
break;
}
} catch (Exception e) {
- StkLog.d(this, "Icon load failed");
+ CatLog.d(this, "Icon load failed");
// post null icon back to the caller.
postIcon();
}
@@ -254,7 +254,7 @@
}
if (pixelIndex != numOfPixels) {
- StkLog.d("IconLoader", "parseToBnW; size error");
+ CatLog.d("IconLoader", "parseToBnW; size error");
}
return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java b/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
similarity index 95%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java
rename to telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
index 880b9e5..711d977 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java
+++ b/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
* {@hide}
@@ -69,7 +69,7 @@
d.length = ((rawData[valueIndex++] & 0xff) << 8 | (rawData[valueIndex++] & 0xff));
} catch (IndexOutOfBoundsException e) {
- StkLog.d("ImageDescripter", "parse; failed parsing image descriptor");
+ CatLog.d("ImageDescripter", "parse; failed parsing image descriptor");
d = null;
}
return d;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java b/telephony/java/com/android/internal/telephony/cat/Input.java
similarity index 91%
rename from telephony/java/com/android/internal/telephony/gsm/stk/Input.java
rename to telephony/java/com/android/internal/telephony/cat/Input.java
index 19f724b..13a5ad4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java
+++ b/telephony/java/com/android/internal/telephony/cat/Input.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
import android.os.Parcel;
import android.os.Parcelable;
/**
- * Container class for STK GET INPUT, GET IN KEY commands parameters.
+ * Container class for CAT GET INPUT, GET IN KEY commands parameters.
*
*/
public class Input implements Parcelable {
@@ -36,6 +36,7 @@
public boolean echo;
public boolean yesNo;
public boolean helpAvailable;
+ public Duration duration;
Input() {
text = "";
@@ -49,6 +50,7 @@
echo = false;
yesNo = false;
helpAvailable = false;
+ duration = null;
}
private Input(Parcel in) {
@@ -63,6 +65,7 @@
echo = in.readInt() == 1 ? true : false;
yesNo = in.readInt() == 1 ? true : false;
helpAvailable = in.readInt() == 1 ? true : false;
+ duration = in.readParcelable(null);
}
public int describeContents() {
@@ -81,6 +84,7 @@
dest.writeInt(echo ? 1 : 0);
dest.writeInt(yesNo ? 1 : 0);
dest.writeInt(helpAvailable ? 1 : 0);
+ dest.writeParcelable(duration, 0);
}
public static final Parcelable.Creator<Input> CREATOR = new Parcelable.Creator<Input>() {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Item.java b/telephony/java/com/android/internal/telephony/cat/Item.java
similarity index 97%
rename from telephony/java/com/android/internal/telephony/gsm/stk/Item.java
rename to telephony/java/com/android/internal/telephony/cat/Item.java
index b2f338c..d4702bb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Item.java
+++ b/telephony/java/com/android/internal/telephony/cat/Item.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
import android.os.Parcel;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java b/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
similarity index 95%
rename from telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java
rename to telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
index 302273c..af043d1 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java
+++ b/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java b/telephony/java/com/android/internal/telephony/cat/Menu.java
similarity index 96%
rename from telephony/java/com/android/internal/telephony/gsm/stk/Menu.java
rename to telephony/java/com/android/internal/telephony/cat/Menu.java
index 331f69d..7bbae01 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java
+++ b/telephony/java/com/android/internal/telephony/cat/Menu.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
import android.os.Parcel;
@@ -24,7 +24,7 @@
import java.util.List;
/**
- * Container class for STK menu (SET UP MENU, SELECT ITEM) parameters.
+ * Container class for CAT menu (SET UP MENU, SELECT ITEM) parameters.
*
*/
public class Menu implements Parcelable {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java b/telephony/java/com/android/internal/telephony/cat/PresentationType.java
similarity index 94%
rename from telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java
rename to telephony/java/com/android/internal/telephony/cat/PresentationType.java
index 71bdcdc..7c8cd8c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java
+++ b/telephony/java/com/android/internal/telephony/cat/PresentationType.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java b/telephony/java/com/android/internal/telephony/cat/ResponseData.java
similarity index 90%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java
rename to telephony/java/com/android/internal/telephony/cat/ResponseData.java
index afd1bba..677d66b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java
+++ b/telephony/java/com/android/internal/telephony/cat/ResponseData.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import com.android.internal.telephony.EncodeException;
import com.android.internal.telephony.GsmAlphabet;
@@ -28,6 +28,16 @@
* the ByteArrayOutputStream object.
*/
public abstract void format(ByteArrayOutputStream buf);
+
+ public static void writeLength(ByteArrayOutputStream buf, int length) {
+ // As per ETSI 102.220 Sec7.1.2, if the total length is greater
+ // than 0x7F, it should be coded in two bytes and the first byte
+ // should be 0x81.
+ if (length > 0x7F) {
+ buf.write(0x81);
+ }
+ buf.write(length);
+ }
}
class SelectItemResponseData extends ResponseData {
@@ -120,7 +130,7 @@
}
// length - one more for data coding scheme.
- buf.write(data.length + 1);
+ writeLength(buf, data.length + 1);
// data coding scheme
if (mIsUcs2) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java b/telephony/java/com/android/internal/telephony/cat/ResultCode.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java
rename to telephony/java/com/android/internal/telephony/cat/ResultCode.java
index b96a524..8544175 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java
+++ b/telephony/java/com/android/internal/telephony/cat/ResultCode.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java b/telephony/java/com/android/internal/telephony/cat/ResultException.java
similarity index 95%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java
rename to telephony/java/com/android/internal/telephony/cat/ResultException.java
index 2eb16c9..1c2cb63 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java
+++ b/telephony/java/com/android/internal/telephony/cat/ResultException.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
@@ -22,7 +22,7 @@
*
* {@hide}
*/
-public class ResultException extends StkException {
+public class ResultException extends CatException {
private ResultCode mResult;
private int mAdditionalInfo;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java b/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
similarity index 87%
rename from telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java
rename to telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
index a82177c..a197c9a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java
+++ b/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
-import com.android.internal.telephony.gsm.SIMFileHandler;
+import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccUtils;
import android.os.Handler;
@@ -26,7 +26,7 @@
/**
* Class used for queuing raw ril messages, decoding them into CommanParams
- * objects and sending the result back to the STK Service.
+ * objects and sending the result back to the CAT Service.
*/
class RilMessageDecoder extends HierarchicalStateMachine {
@@ -51,7 +51,7 @@
* @param fh
* @return RilMesssageDecoder
*/
- public static synchronized RilMessageDecoder getInstance(Handler caller, SIMFileHandler fh) {
+ public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh) {
if (sInstance == null) {
sInstance = new RilMessageDecoder(caller, fh);
sInstance.start();
@@ -85,12 +85,12 @@
}
private void sendCmdForExecution(RilMessage rilMsg) {
- Message msg = mCaller.obtainMessage(StkService.MSG_ID_RIL_MSG_DECODED,
+ Message msg = mCaller.obtainMessage(CatService.MSG_ID_RIL_MSG_DECODED,
new RilMessage(rilMsg));
msg.sendToTarget();
}
- private RilMessageDecoder(Handler caller, SIMFileHandler fh) {
+ private RilMessageDecoder(Handler caller, IccFileHandler fh) {
super("RilMessageDecoder");
addState(mStateStart);
@@ -108,7 +108,7 @@
transitionTo(mStateCmdParamsReady);
}
} else {
- StkLog.d(this, "StateStart unexpected expecting START=" +
+ CatLog.d(this, "StateStart unexpected expecting START=" +
CMD_START + " got " + msg.what);
}
return true;
@@ -123,7 +123,7 @@
sendCmdForExecution(mCurrentRilMessage);
transitionTo(mStateStart);
} else {
- StkLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY="
+ CatLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY="
+ CMD_PARAMS_READY + " got " + msg.what);
deferMessage(msg);
}
@@ -136,21 +136,21 @@
mCurrentRilMessage = rilMsg;
switch(rilMsg.mId) {
- case StkService.MSG_ID_SESSION_END:
- case StkService.MSG_ID_CALL_SETUP:
+ case CatService.MSG_ID_SESSION_END:
+ case CatService.MSG_ID_CALL_SETUP:
mCurrentRilMessage.mResCode = ResultCode.OK;
sendCmdForExecution(mCurrentRilMessage);
decodingStarted = false;
break;
- case StkService.MSG_ID_PROACTIVE_COMMAND:
- case StkService.MSG_ID_EVENT_NOTIFY:
- case StkService.MSG_ID_REFRESH:
+ case CatService.MSG_ID_PROACTIVE_COMMAND:
+ case CatService.MSG_ID_EVENT_NOTIFY:
+ case CatService.MSG_ID_REFRESH:
byte[] rawData = null;
try {
rawData = IccUtils.hexStringToBytes((String) rilMsg.mData);
} catch (Exception e) {
// zombie messages are dropped
- StkLog.d(this, "decodeMessageParams dropping zombie messages");
+ CatLog.d(this, "decodeMessageParams dropping zombie messages");
decodingStarted = false;
break;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java b/telephony/java/com/android/internal/telephony/cat/TextAlignment.java
similarity index 96%
rename from telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java
rename to telephony/java/com/android/internal/telephony/cat/TextAlignment.java
index c5dd50e..7fb58a5 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextAlignment.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java b/telephony/java/com/android/internal/telephony/cat/TextAttribute.java
similarity index 96%
rename from telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java
rename to telephony/java/com/android/internal/telephony/cat/TextAttribute.java
index ace4300..0dea640 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextAttribute.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java b/telephony/java/com/android/internal/telephony/cat/TextColor.java
similarity index 96%
rename from telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java
rename to telephony/java/com/android/internal/telephony/cat/TextColor.java
index 126fc62..6447e74 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextColor.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java b/telephony/java/com/android/internal/telephony/cat/TextMessage.java
similarity index 97%
rename from telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java
rename to telephony/java/com/android/internal/telephony/cat/TextMessage.java
index 3b6a09a..5ffd076 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextMessage.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
import android.os.Parcel;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java b/telephony/java/com/android/internal/telephony/cat/Tone.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/Tone.java
rename to telephony/java/com/android/internal/telephony/cat/Tone.java
index b64e777d..27b4489 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java
+++ b/telephony/java/com/android/internal/telephony/cat/Tone.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java b/telephony/java/com/android/internal/telephony/cat/ToneSettings.java
similarity index 97%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java
rename to telephony/java/com/android/internal/telephony/cat/ToneSettings.java
index 90cc6c1..6375afb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java
+++ b/telephony/java/com/android/internal/telephony/cat/ToneSettings.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java b/telephony/java/com/android/internal/telephony/cat/ValueParser.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java
rename to telephony/java/com/android/internal/telephony/cat/ValueParser.java
index 09a860e..34e4811 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java
+++ b/telephony/java/com/android/internal/telephony/cat/ValueParser.java
@@ -14,11 +14,11 @@
* the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.gsm.stk.Duration.TimeUnit;
+import com.android.internal.telephony.cat.Duration.TimeUnit;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@@ -182,7 +182,7 @@
*/
static ItemsIconId retrieveItemsIconId(ComprehensionTlv ctlv)
throws ResultException {
- StkLog.d("ValueParser", "retrieveItemsIconId:");
+ CatLog.d("ValueParser", "retrieveItemsIconId:");
ItemsIconId id = new ItemsIconId();
byte[] rawValue = ctlv.getRawValue();
diff --git a/telephony/java/com/android/internal/telephony/cat/package.html b/telephony/java/com/android/internal/telephony/cat/package.html
new file mode 100644
index 0000000..5b6bfc6
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cat/package.html
@@ -0,0 +1,5 @@
+<HTML>
+<BODY>
+Provides classes for ICC Toolkit Service (CAT).
+</BODY>
+</HTML>
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index c21b6d9..840d366 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -42,6 +42,7 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.telephony.cat.CatService;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.CommandException;
@@ -109,7 +110,7 @@
PhoneSubInfo mSubInfo;
EriManager mEriManager;
WakeLock mWakeLock;
-
+ CatService mCcatService;
// mNvLoadedRegistrants are informed after the EVENT_NV_READY
private RegistrantList mNvLoadedRegistrants = new RegistrantList();
@@ -161,6 +162,8 @@
mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this);
mSubInfo = new PhoneSubInfo(this);
mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML);
+ mCcatService = CatService.getInstance(mCM, mRuimRecords, mContext,
+ mIccFileHandler, mRuimCard);
mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
mRuimRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
@@ -221,6 +224,7 @@
mCM.unregisterForNVReady(this); //EVENT_NV_READY
mSST.unregisterForNetworkAttach(this); //EVENT_REGISTERED_TO_NETWORK
mCM.unSetOnSuppServiceNotification(this);
+ removeCallbacks(mExitEcmRunnable);
mPendingMmis.clear();
@@ -236,6 +240,7 @@
mRuimSmsInterfaceManager.dispose();
mSubInfo.dispose();
mEriManager.dispose();
+ mCcatService.dispose();
}
}
@@ -251,6 +256,8 @@
this.mCT = null;
this.mSST = null;
this.mEriManager = null;
+ this.mCcatService = null;
+ this.mExitEcmRunnable = null;
}
protected void finalize() {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index c7b1e5c..6665632 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -49,6 +49,7 @@
import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
+import com.android.internal.telephony.cat.CatService;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallForwardInfo;
import com.android.internal.telephony.CallStateException;
@@ -68,7 +69,6 @@
import com.android.internal.telephony.PhoneSubInfo;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.gsm.stk.StkService;
import com.android.internal.telephony.test.SimulatedRadioControl;
import com.android.internal.telephony.IccVmNotSupportedException;
@@ -102,7 +102,7 @@
GsmSMSDispatcher mSMS;
SIMRecords mSIMRecords;
SimCard mSimCard;
- StkService mStkService;
+ CatService mStkService;
ArrayList <GsmMmiCode> mPendingMMIs = new ArrayList<GsmMmiCode>();
SimPhoneBookInterfaceManager mSimPhoneBookIntManager;
SimSmsInterfaceManager mSimSmsIntManager;
@@ -154,7 +154,7 @@
mSimSmsIntManager = new SimSmsInterfaceManager(this);
mSubInfo = new PhoneSubInfo(this);
}
- mStkService = StkService.getInstance(mCM, mSIMRecords, mContext,
+ mStkService = CatService.getInstance(mCM, mSIMRecords, mContext,
(SIMFileHandler)mIccFileHandler, mSimCard);
mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
@@ -972,7 +972,9 @@
}
public void getCallWaiting(Message onComplete) {
- mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
+ //As per 3GPP TS 24.083, section 1.6 UE doesn't need to send service
+ //class parameter in call waiting interrogation to network
+ mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_NONE, onComplete);
}
public void setCallWaiting(boolean enable, Message onComplete) {
@@ -1484,4 +1486,7 @@
Log.e(LOG_TAG, "Error! This functionality is not implemented for GSM.");
}
+ public boolean isCspPlmnEnabled() {
+ return mSIMRecords.isCspPlmnEnabled();
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index aa16fa3..fe7a5cb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -44,6 +44,13 @@
//***** Constants
+ // Max Size of the Short Code (aka Short String from TS 22.030 6.5.2)
+ static final int MAX_LENGTH_SHORT_CODE = 2;
+
+ // TS 22.030 6.5.2 Every Short String USSD command will end with #-key
+ // (known as #-String)
+ static final char END_OF_USSD_COMMAND = '#';
+
// From TS 22.030 6.5.2
static final String ACTION_ACTIVATE = "*";
static final String ACTION_DEACTIVATE = "#";
@@ -446,22 +453,69 @@
}
/**
- * Helper function for newFromDialString. Returns true if dialString appears to be a short code
- * AND conditions are correct for it to be treated as such.
+ * Helper function for newFromDialString. Returns true if dialString appears
+ * to be a short code AND conditions are correct for it to be treated as
+ * such.
*/
static private boolean isShortCode(String dialString, GSMPhone phone) {
// Refer to TS 22.030 Figure 3.5.3.2:
- // A 1 or 2 digit "short code" is treated as USSD if it is entered while on a call or
- // does not satisfy the condition (exactly 2 digits && starts with '1').
- return ((dialString != null && dialString.length() <= 2)
- && !PhoneNumberUtils.isEmergencyNumber(dialString)
- && (phone.isInCall()
- || !((dialString.length() == 2 && dialString.charAt(0) == '1')
- /* While contrary to TS 22.030, there is strong precedence
- * for treating "0" and "00" as call setup strings.
- */
- || dialString.equals("0")
- || dialString.equals("00"))));
+ if (dialString == null) {
+ return false;
+ }
+
+ // Illegal dial string characters will give a ZERO length.
+ // At this point we do not want to crash as any application with
+ // call privileges may send a non dial string.
+ // It return false as when the dialString is equal to NULL.
+ if (dialString.length() == 0) {
+ return false;
+ }
+
+ if (PhoneNumberUtils.isEmergencyNumber(dialString)) {
+ return false;
+ } else {
+ return isShortCodeUSSD(dialString, phone);
+ }
+ }
+
+ /**
+ * Helper function for isShortCode. Returns true if dialString appears to be
+ * a short code and it is a USSD structure
+ *
+ * According to the 3PGG TS 22.030 specification Figure 3.5.3.2: A 1 or 2
+ * digit "short code" is treated as USSD if it is entered while on a call or
+ * does not satisfy the condition (exactly 2 digits && starts with '1'), there
+ * are however exceptions to this rule (see below)
+ *
+ * Exception (1) to Call initiation is: If the user of the device is already in a call
+ * and enters a Short String without any #-key at the end and the length of the Short String is
+ * equal or less then the MAX_LENGTH_SHORT_CODE [constant that is equal to 2]
+ *
+ * The phone shall initiate a USSD/SS commands.
+ *
+ * Exception (2) to Call initiation is: If the user of the device enters one
+ * Digit followed by the #-key. This rule defines this String as the
+ * #-String which is a USSD/SS command.
+ *
+ * The phone shall initiate a USSD/SS command.
+ */
+ static private boolean isShortCodeUSSD(String dialString, GSMPhone phone) {
+ if (dialString != null) {
+ if (phone.isInCall()) {
+ // The maximum length of a Short Code (aka Short String) is 2
+ if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
+ return true;
+ }
+ }
+
+ // The maximum length of a Short Code (aka Short String) is 2
+ if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
+ if (dialString.charAt(dialString.length() - 1) == END_OF_USSD_COMMAND) {
+ return true;
+ }
+ }
+ }
+ return false;
}
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
index 206e62f..e8d10f9 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
@@ -81,6 +81,7 @@
case EF_SPN_CPHS:
case EF_SPN_SHORT_CPHS:
case EF_INFO_CPHS:
+ case EF_CSP_CPHS:
return MF_SIM + DF_GSM;
case EF_PBR:
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index d711a80..c80c608 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -73,6 +73,7 @@
* mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table
*/
private byte[] mCphsInfo = null;
+ boolean mCspPlmnEnabled = true;
byte[] efMWIS = null;
byte[] efCPHS_MWI =null;
@@ -93,6 +94,7 @@
static final int SPN_RULE_SHOW_PLMN = 0x02;
// From TS 51.011 EF[SPDI] section
+ static final int TAG_SPDI = 0xA3;
static final int TAG_SPDI_PLMN_LIST = 0x80;
// Full Name IEI from TS 24.008
@@ -140,6 +142,7 @@
private static final int EVENT_SET_MSISDN_DONE = 30;
private static final int EVENT_SIM_REFRESH = 31;
private static final int EVENT_GET_CFIS_DONE = 32;
+ private static final int EVENT_GET_CSP_CPHS_DONE = 33;
// ***** Constructor
@@ -559,6 +562,13 @@
break;
case EVENT_GET_CPHS_MAILBOX_DONE:
case EVENT_GET_MBDN_DONE:
+ //Resetting the voice mail number and voice mail tag to null
+ //as these should be updated from the data read from EF_MBDN.
+ //If they are not reset, incase of invalid data/exception these
+ //variables are retaining their previous values and are
+ //causing invalid voice mailbox info display to user.
+ voiceMailNum = null;
+ voiceMailTag = null;
isRecordLoadResponse = true;
ar = (AsyncResult)msg.obj;
@@ -994,6 +1004,22 @@
((GSMPhone) phone).notifyCallForwardingIndicator();
break;
+ case EVENT_GET_CSP_CPHS_DONE:
+ isRecordLoadResponse = true;
+
+ ar = (AsyncResult)msg.obj;
+
+ if (ar.exception != null) {
+ Log.e(LOG_TAG,"Exception in fetching EF_CSP data " + ar.exception);
+ break;
+ }
+
+ data = (byte[])ar.result;
+
+ Log.i(LOG_TAG,"EF_CSP: " + IccUtils.bytesToHexString(data));
+ handleEfCspData(data);
+ break;
+
}}catch (RuntimeException exc) {
// I don't want these exceptions to be fatal
Log.w(LOG_TAG, "Exception parsing SIM record", exc);
@@ -1017,6 +1043,12 @@
new AdnRecordLoader(phone).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1,
1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
break;
+ case EF_CSP_CPHS:
+ recordsToLoad++;
+ Log.i(LOG_TAG, "[CSP] SIM Refresh for EF_CSP_CPHS");
+ phone.getIccFileHandler().loadEFTransparent(EF_CSP_CPHS,
+ obtainMessage(EVENT_GET_CSP_CPHS_DONE));
+ break;
default:
// For now, fetch all records if this is not a
// voicemail number.
@@ -1247,6 +1279,9 @@
iccFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE));
recordsToLoad++;
+ iccFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE));
+ recordsToLoad++;
+
// XXX should seek instead of examining them all
if (false) { // XXX
iccFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
@@ -1426,8 +1461,12 @@
byte[] plmnEntries = null;
- // There should only be one TAG_SPDI_PLMN_LIST
for ( ; tlv.isValidObject() ; tlv.nextObject()) {
+ // Skip SPDI tag, if existant
+ if (tlv.getTag() == TAG_SPDI) {
+ tlv = new SimTlv(tlv.getData(), 0, tlv.getData().length);
+ }
+ // There should only be one TAG_SPDI_PLMN_LIST
if (tlv.getTag() == TAG_SPDI_PLMN_LIST) {
plmnEntries = tlv.getData();
break;
@@ -1464,4 +1503,53 @@
Log.d(LOG_TAG, "[SIMRecords] " + s);
}
+ /**
+ * Return true if "Restriction of menu options for manual PLMN selection"
+ * bit is set or EF_CSP data is unavailable, return false otherwise.
+ */
+ public boolean isCspPlmnEnabled() {
+ return mCspPlmnEnabled;
+ }
+
+ /**
+ * Parse EF_CSP data and check if
+ * "Restriction of menu options for manual PLMN selection" is
+ * Enabled/Disabled
+ *
+ * @param data EF_CSP hex data.
+ */
+ private void handleEfCspData(byte[] data) {
+ // As per spec CPHS4_2.WW6, CPHS B.4.7.1, EF_CSP contains CPHS defined
+ // 18 bytes (i.e 9 service groups info) and additional data specific to
+ // operator. The valueAddedServicesGroup is not part of standard
+ // services. This is operator specific and can be programmed any where.
+ // Normally this is programmed as 10th service after the standard
+ // services.
+ int usedCspGroups = data.length / 2;
+ // This is the "Servive Group Number" of "Value Added Services Group".
+ byte valueAddedServicesGroup = (byte)0xC0;
+
+ mCspPlmnEnabled = true;
+ for (int i = 0; i < usedCspGroups; i++) {
+ if (data[2 * i] == valueAddedServicesGroup) {
+ Log.i(LOG_TAG, "[CSP] found ValueAddedServicesGroup, value "
+ + data[(2 * i) + 1]);
+ if ((data[(2 * i) + 1] & 0x80) == 0x80) {
+ // Bit 8 is for
+ // "Restriction of menu options for manual PLMN selection".
+ // Operator Selection menu should be enabled.
+ mCspPlmnEnabled = true;
+ } else {
+ mCspPlmnEnabled = false;
+ // Operator Selection menu should be disabled.
+ // Operator Selection Mode should be set to Automatic.
+ Log.i(LOG_TAG,"[CSP] Set Automatic Network Selection");
+ phone.setNetworkSelectionModeAutomatic(null);
+ }
+ return;
+ }
+ }
+
+ Log.w(LOG_TAG, "[CSP] Value Added Service Group (0xC0), not found!");
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 50dd402..9a3c476 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -930,6 +930,8 @@
// TP-Message-Type-Indicator
// 9.2.3
case 0:
+ case 3: //GSM 03.40 9.2.3.1: MTI == 3 is Reserved.
+ //This should be processed in the same way as MTI == 0 (Deliver)
parseSmsDeliver(p, firstByte);
break;
case 2:
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
old mode 100644
new mode 100755
index 41e527c..b642541
--- a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
@@ -53,6 +53,7 @@
private ArrayList<byte[]> mIapFileRecord;
private ArrayList<byte[]> mEmailFileRecord;
private Map<Integer, ArrayList<String>> mEmailsForAdnRec;
+ private boolean mRefreshCache = false;
private static final int EVENT_PBR_LOAD_DONE = 1;
private static final int EVENT_USIM_ADN_LOAD_DONE = 2;
@@ -91,11 +92,19 @@
mEmailFileRecord = null;
mPbrFile = null;
mIsPbrPresent = true;
+ mRefreshCache = false;
}
public ArrayList<AdnRecord> loadEfFilesFromUsim() {
synchronized (mLock) {
- if (!mPhoneBookRecords.isEmpty()) return mPhoneBookRecords;
+ if (!mPhoneBookRecords.isEmpty()) {
+ if (mRefreshCache) {
+ mRefreshCache = false;
+ refreshCache();
+ }
+ return mPhoneBookRecords;
+ }
+
if (!mIsPbrPresent) return null;
// Check if the PBR file is present in the cache, if not read it
@@ -116,6 +125,20 @@
return mPhoneBookRecords;
}
+ private void refreshCache() {
+ if (mPbrFile == null) return;
+ mPhoneBookRecords.clear();
+
+ int numRecs = mPbrFile.mFileIds.size();
+ for (int i = 0; i < numRecs; i++) {
+ readAdnFileAndWait(i);
+ }
+ }
+
+ public void invalidateCache() {
+ mRefreshCache = true;
+ }
+
private void readPbrFileAndWait() {
mPhone.getIccFileHandler().loadEFLinearFixedAll(EF_PBR, obtainMessage(EVENT_PBR_LOAD_DONE));
try {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/package.html b/telephony/java/com/android/internal/telephony/gsm/stk/package.html
deleted file mode 100644
index c285b57..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/stk/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<HTML>
-<BODY>
-Provides classes for SIM Toolkit Service.
-</BODY>
-</HTML>
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java
new file mode 100644
index 0000000..d31b294
--- /dev/null
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java
@@ -0,0 +1,853 @@
+/*
+ * Copyright (C) 2010 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;
+
+import com.android.internal.telephony.WspTypeDecoder;
+import com.android.internal.util.HexDump;
+
+import java.io.ByteArrayOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+public class Wap230WspContentTypeTest extends TestCase {
+
+ public static final Map<Integer, String> WELL_KNOWN_SHORT_MIME_TYPES
+ = new HashMap<Integer, String>();
+ public static final Map<Integer, String> WELL_KNOWN_LONG_MIME_TYPES
+ = new HashMap<Integer, String>();
+ public static final Map<Integer, String> WELL_KNOWN_PARAMETERS
+ = new HashMap<Integer, String>();
+
+ static {
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x00, "*/*");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x01, "text/*");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x02, "text/html");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x03, "text/plain");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x04, "text/x-hdml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x05, "text/x-ttml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x06, "text/x-vCalendar");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x07, "text/x-vCard");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x08, "text/vnd.wap.wml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x09, "text/vnd.wap.wmlscript");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x0A, "text/vnd.wap.wta-event");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x0B, "multipart/*");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x0C, "multipart/mixed");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x0D, "multipart/form-data");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x0E, "multipart/byterantes");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x0F, "multipart/alternative");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x10, "application/*");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x11, "application/java-vm");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x12, "application/x-www-form-urlencoded");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x13, "application/x-hdmlc");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x14, "application/vnd.wap.wmlc");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x15, "application/vnd.wap.wmlscriptc");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x16, "application/vnd.wap.wta-eventc");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x17, "application/vnd.wap.uaprof");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x18, "application/vnd.wap.wtls-ca-certificate");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x19, "application/vnd.wap.wtls-user-certificate");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x1A, "application/x-x509-ca-cert");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x1B, "application/x-x509-user-cert");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x1C, "image/*");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x1D, "image/gif");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x1E, "image/jpeg");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x1F, "image/tiff");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x20, "image/png");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x21, "image/vnd.wap.wbmp");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x22, "application/vnd.wap.multipart.*");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x23, "application/vnd.wap.multipart.mixed");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x24, "application/vnd.wap.multipart.form-data");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x25, "application/vnd.wap.multipart.byteranges");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x26, "application/vnd.wap.multipart.alternative");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x27, "application/xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x28, "text/xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x29, "application/vnd.wap.wbxml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x2A, "application/x-x968-cross-cert");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x2B, "application/x-x968-ca-cert");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x2C, "application/x-x968-user-cert");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x2D, "text/vnd.wap.si");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x2E, "application/vnd.wap.sic");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x2F, "text/vnd.wap.sl");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x30, "application/vnd.wap.slc");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x31, "text/vnd.wap.co");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x32, "application/vnd.wap.coc");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x33, "application/vnd.wap.multipart.related");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x34, "application/vnd.wap.sia");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x35, "text/vnd.wap.connectivity-xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x36, "application/vnd.wap.connectivity-wbxml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x37, "application/pkcs7-mime");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x38, "application/vnd.wap.hashed-certificate");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x39, "application/vnd.wap.signed-certificate");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x3A, "application/vnd.wap.cert-response");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x3B, "application/xhtml+xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x3C, "application/wml+xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x3D, "text/css");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x3E, "application/vnd.wap.mms-message");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x3F, "application/vnd.wap.rollover-certificate");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x40, "application/vnd.wap.locc+wbxml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x41, "application/vnd.wap.loc+xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x42, "application/vnd.syncml.dm+wbxml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x43, "application/vnd.syncml.dm+xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x44, "application/vnd.syncml.notification");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x45, "application/vnd.wap.xhtml+xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x46, "application/vnd.wv.csp.cir");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x47, "application/vnd.oma.dd+xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x48, "application/vnd.oma.drm.message");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x49, "application/vnd.oma.drm.content");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x4A, "application/vnd.oma.drm.rights+xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x4B, "application/vnd.oma.drm.rights+wbxml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x4C, "application/vnd.wv.csp+xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x4D, "application/vnd.wv.csp+wbxml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x4E, "application/vnd.syncml.ds.notification");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x4F, "audio/*");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x50, "video/*");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x51, "application/vnd.oma.dd2+xml");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x52, "application/mikey");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x53, "application/vnd.oma.dcd");
+ WELL_KNOWN_SHORT_MIME_TYPES.put(0x54, "application/vnd.oma.dcdc");
+
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0201, "application/vnd.uplanet.cacheop-wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0202, "application/vnd.uplanet.signal");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0203, "application/vnd.uplanet.alert-wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0204, "application/vnd.uplanet.list-wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0205, "application/vnd.uplanet.listcmd-wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0206, "application/vnd.uplanet.channel-wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0207, "application/vnd.uplanet.provisioning-status-uri");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0208, "x-wap.multipart/vnd.uplanet.header-set");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0209, "application/vnd.uplanet.bearer-choice-wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x020A, "application/vnd.phonecom.mmc-wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x020B, "application/vnd.nokia.syncset+wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x020C, "image/x-up-wpng");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0300, "application/iota.mmc-wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0301, "application/iota.mmc-xml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0302, "application/vnd.syncml+xml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0303, "application/vnd.syncml+wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0304, "text/vnd.wap.emn+xml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0305, "text/calendar");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0306, "application/vnd.omads-email+xml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0307, "application/vnd.omads-file+xml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0308, "application/vnd.omads-folder+xml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0309, "text/directory;profile=vCard");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x030A, "application/vnd.wap.emn+wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x030B, "application/vnd.nokia.ipdc-purchase-response");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x030C, "application/vnd.motorola.screen3+xml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x030D, "application/vnd.motorola.screen3+gzip");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x030E, "application/vnd.cmcc.setting+wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x030F, "application/vnd.cmcc.bombing+wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0310, "application/vnd.docomo.pf");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0311, "application/vnd.docomo.ub");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0312, "application/vnd.omaloc-supl-init");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0313, "application/vnd.oma.group-usage-list+xml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0314, "application/oma-directory+xml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0315, "application/vnd.docomo.pf2");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0316, "application/vnd.oma.drm.roap-trigger+wbxml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0317, "application/vnd.sbm.mid2");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0318, "application/vnd.wmf.bootstrap");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x0319, "application/vnc.cmcc.dcd+xml");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x031A, "application/vnd.sbm.cid");
+ WELL_KNOWN_LONG_MIME_TYPES.put(0x031B, "application/vnd.oma.bcast.provisioningtrigger");
+
+ WELL_KNOWN_PARAMETERS.put(0x00, "Q");
+ WELL_KNOWN_PARAMETERS.put(0x01, "Charset");
+ WELL_KNOWN_PARAMETERS.put(0x02, "Level");
+ WELL_KNOWN_PARAMETERS.put(0x03, "Type");
+ WELL_KNOWN_PARAMETERS.put(0x07, "Differences");
+ WELL_KNOWN_PARAMETERS.put(0x08, "Padding");
+ WELL_KNOWN_PARAMETERS.put(0x09, "Type");
+ WELL_KNOWN_PARAMETERS.put(0x0E, "Max-Age");
+ WELL_KNOWN_PARAMETERS.put(0x10, "Secure");
+ WELL_KNOWN_PARAMETERS.put(0x11, "SEC");
+ WELL_KNOWN_PARAMETERS.put(0x12, "MAC");
+ WELL_KNOWN_PARAMETERS.put(0x13, "Creation-date");
+ WELL_KNOWN_PARAMETERS.put(0x14, "Modification-date");
+ WELL_KNOWN_PARAMETERS.put(0x15, "Read-date");
+ WELL_KNOWN_PARAMETERS.put(0x16, "Size");
+ WELL_KNOWN_PARAMETERS.put(0x17, "Name");
+ WELL_KNOWN_PARAMETERS.put(0x18, "Filename");
+ WELL_KNOWN_PARAMETERS.put(0x19, "Start");
+ WELL_KNOWN_PARAMETERS.put(0x1A, "Start-info");
+ WELL_KNOWN_PARAMETERS.put(0x1B, "Comment");
+ WELL_KNOWN_PARAMETERS.put(0x1C, "Domain");
+ WELL_KNOWN_PARAMETERS.put(0x1D, "Path");
+
+ }
+
+ final int WSP_DEFINED_SHORT_MIME_TYPE_COUNT = 85;
+ final int WSP_DEFINED_LONG_MIME_TYPE_COUNT = 85;
+
+ private static final byte WSP_STRING_TERMINATOR = 0x00;
+ private static final byte WSP_SHORT_INTEGER_MASK = (byte) 0x80;
+ private static final byte WSP_LENGTH_QUOTE = 0x1F;
+ private static final byte WSP_QUOTE = 0x22;
+
+ private static final short LONG_MIME_TYPE_OMA_DIRECTORY_XML = 0x0314;
+ private static final short LONG_MIME_TYPE_UNASSIGNED = 0x052C;
+
+ private static final byte SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE = 0x3F;
+ private static final byte SHORT_MIME_TYPE_UNASSIGNED = 0x60;
+
+ private static final String STRING_MIME_TYPE_ROLLOVER_CERTIFICATE
+ = "application/vnd.wap.rollover-certificate";
+
+ private static final byte TYPED_PARAM_Q = 0x00;
+ private static final byte TYPED_PARAM_DOMAIN = 0x1C;
+ private static final byte PARAM_UNASSIGNED = 0x42;
+ private static final byte PARAM_NO_VALUE = 0x00;
+ private static final byte TYPED_PARAM_SEC = 0x11;
+ private static final byte TYPED_PARAM_MAC = 0x12;
+
+ public void testHasExpectedNumberOfShortMimeTypes() {
+ assertEquals(WSP_DEFINED_SHORT_MIME_TYPE_COUNT, WELL_KNOWN_SHORT_MIME_TYPES.size());
+ }
+
+ public void testHasExpectedNumberOfLongMimeTypes() {
+ assertEquals(WSP_DEFINED_LONG_MIME_TYPE_COUNT, WELL_KNOWN_LONG_MIME_TYPES.size());
+ }
+
+ public void testWellKnownShortIntegerMimeTypeValues() {
+
+ for (int value : Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.keySet()) {
+ WspTypeDecoder unit = new WspTypeDecoder(
+ HexDump.toByteArray((byte) (value | WSP_SHORT_INTEGER_MASK)));
+ assertTrue(unit.decodeContentType(0));
+ String mimeType = unit.getValueString();
+ int wellKnownValue = (int) unit.getValue32();
+ assertEquals(Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.get(value), mimeType);
+ assertEquals(value, wellKnownValue);
+ assertEquals(1, unit.getDecodedDataLength());
+ }
+ }
+
+ public void testWellKnownLongIntegerMimeTypeValues() {
+ byte headerLength = 3;
+ byte typeLength = 2;
+ for (int value : Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.keySet()) {
+ byte[] data = new byte[10];
+ data[0] = headerLength;
+ data[1] = typeLength;
+ data[2] = (byte) (value >> 8);
+ data[3] = (byte) (value & 0xFF);
+ WspTypeDecoder unit = new WspTypeDecoder(data);
+ assertTrue(unit.decodeContentType(0));
+ String mimeType = unit.getValueString();
+ int wellKnownValue = (int) unit.getValue32();
+ assertEquals(Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.get(value), mimeType);
+ assertEquals(value, wellKnownValue);
+ assertEquals(4, unit.getDecodedDataLength());
+ }
+ }
+
+ public void testDecodeReturnsFalse_WhenOnlyAZeroBytePresent() {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x00);
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertFalse(unit.decodeContentType(0));
+ }
+
+ public void testConstrainedMediaExtensionMedia() throws Exception {
+
+ String testType = "application/wibble";
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(testType.getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+ String mimeType = unit.getValueString();
+ assertEquals(testType, mimeType);
+ assertEquals(-1, unit.getValue32());
+ assertEquals(19, unit.getDecodedDataLength());
+ }
+
+ public void testGeneralFormShortLengthExtensionMedia() throws Exception {
+
+ String testType = "12345678901234567890123456789";
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(testType.length() + 1);
+ out.write(testType.getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+ assertEquals(testType, mimeType);
+ assertEquals(-1, unit.getValue32());
+ assertEquals(31, unit.getDecodedDataLength());
+ }
+
+ public void testGeneralFormShortLengthWellKnownShortInteger() {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x01);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+ assertEquals(2, unit.getDecodedDataLength());
+
+ }
+
+ public void testGeneralFormShortLengthWellKnownShortIntegerWithUnknownValue() {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x01);
+ out.write(SHORT_MIME_TYPE_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+ assertNull(mimeType);
+ assertEquals(SHORT_MIME_TYPE_UNASSIGNED, unit.getValue32());
+ assertEquals(2, unit.getDecodedDataLength());
+
+ }
+
+ public void testGeneralFormShortLengthWellKnownLongInteger() {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ out.write(0x03); // header length
+ out.write(0x02); // type length (2 octets)
+ out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML >> 8);
+ out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML & 0xFF);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals("application/oma-directory+xml", mimeType);
+ assertEquals(LONG_MIME_TYPE_OMA_DIRECTORY_XML, unit.getValue32());
+ assertEquals(4, unit.getDecodedDataLength());
+ }
+
+ public void testGeneralFormShortLengthWellKnownLongIntegerWithUnknownValue() {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ out.write(0x03); // Value-length, short-length
+ out.write(0x02); // long-integer length (2 octets)
+ out.write(LONG_MIME_TYPE_UNASSIGNED >> 8);
+ out.write(LONG_MIME_TYPE_UNASSIGNED & 0xFF);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertNull(mimeType);
+ assertEquals(LONG_MIME_TYPE_UNASSIGNED, unit.getValue32());
+ assertEquals(4, unit.getDecodedDataLength());
+
+ }
+
+ public void testGeneralFormLengthQuoteWellKnownShortInteger() {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ out.write(WSP_LENGTH_QUOTE);
+ out.write(0x01); // Length as UINTVAR
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+ assertEquals(3, unit.getDecodedDataLength());
+
+ }
+
+ public void testGeneralFormLengthQuoteWellKnownShortIntegerWithUnknownValue() {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ out.write(WSP_LENGTH_QUOTE);
+ out.write(0x01); // Length as UINTVAR
+ out.write(SHORT_MIME_TYPE_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+ assertNull(mimeType);
+ assertEquals(SHORT_MIME_TYPE_UNASSIGNED, unit.getValue32());
+ assertEquals(3, unit.getDecodedDataLength());
+ }
+
+ public void testGeneralFormLengthQuoteWellKnownLongInteger() {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ out.write(WSP_LENGTH_QUOTE);
+ out.write(0x03); // Length as UINTVAR
+ out.write(0x02); // long-integer length (2 octets)
+ out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML >> 8);
+ out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML & 0xFF);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals("application/oma-directory+xml", mimeType);
+ assertEquals(LONG_MIME_TYPE_OMA_DIRECTORY_XML, unit.getValue32());
+ assertEquals(5, unit.getDecodedDataLength());
+
+ }
+
+ public void testGeneralFormLengthQuoteWellKnownLongIntegerWithUnknownValue() {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ out.write(WSP_LENGTH_QUOTE);
+ out.write(0x03); // Length as UINTVAR
+ out.write(0x02); // long-integer length (2 octets)
+ out.write(LONG_MIME_TYPE_UNASSIGNED >> 8);
+ out.write(LONG_MIME_TYPE_UNASSIGNED & 0xFF);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertNull(mimeType);
+ assertEquals(LONG_MIME_TYPE_UNASSIGNED, unit.getValue32());
+ assertEquals(5, unit.getDecodedDataLength());
+
+ }
+
+ public void testGeneralFormLengthQuoteExtensionMedia() throws Exception {
+
+ String testType = "application/wibble";
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ out.write(WSP_LENGTH_QUOTE);
+ out.write(testType.length() + 1); // Length as UINTVAR
+
+ out.write(testType.getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(testType, mimeType);
+ assertEquals(-1, unit.getValue32());
+ assertEquals(21, unit.getDecodedDataLength());
+
+ }
+
+ public void testGeneralFormLengthQuoteExtensionMediaWithNiceLongMimeType() throws Exception {
+
+ String testType =
+ "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
+ +"01234567890123456789012345678901234567890123456789012345678901234567890123456789";
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ out.write(WSP_LENGTH_QUOTE);
+ out.write(0x81); // Length as UINTVAR (161 decimal, 0xA1), 2 bytes
+ out.write(0x21);
+
+ out.write(testType.getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(testType, mimeType);
+ assertEquals(-1, unit.getValue32());
+ assertEquals(164, unit.getDecodedDataLength());
+
+ }
+
+ public void testConstrainedMediaExtensionMediaWithSpace() throws Exception {
+
+ String testType = " application/wibble";
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(testType.getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(testType, mimeType);
+ assertEquals(-1, unit.getValue32());
+ assertEquals(20, unit.getDecodedDataLength());
+
+ }
+
+ public void testTypedParamWellKnownShortIntegerNoValue() {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x03); // Value-length, short-length
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
+ out.write(PARAM_NO_VALUE);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+
+ assertEquals(4, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals(null, params.get("Domain"));
+
+ }
+
+ public void testTypedParamWellKnownShortIntegerTokenText() throws Exception {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x14); // Value-length, short-length
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
+ out.write("wdstechnology.com".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+
+ assertEquals(out.toByteArray().length, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("wdstechnology.com", params.get("Domain"));
+
+ }
+
+ public void testTypedParamWellKnownLongIntegerTokenText() throws Exception {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x15);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write(0x01);
+ out.write(TYPED_PARAM_DOMAIN);
+ out.write("wdstechnology.com".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+
+ assertEquals(22, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("wdstechnology.com", params.get("Domain"));
+
+ }
+
+ public void testTypedParamWellKnownShortIntegerQuotedText() throws Exception {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x15);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
+ out.write(WSP_QUOTE);
+ out.write("wdstechnology.com".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(0x3F, unit.getValue32());
+ assertEquals(22, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("wdstechnology.com", params.get("Domain"));
+
+ }
+
+ public void testTypedParamWellKnownShortIntegerCompactIntegerValue() {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x3);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write(TYPED_PARAM_SEC | WSP_SHORT_INTEGER_MASK);
+ out.write(0x01 | WSP_SHORT_INTEGER_MASK);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(0x3F, unit.getValue32());
+ assertEquals(4, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("1", params.get("SEC"));
+
+ }
+
+ public void testTypedParamWellKnownShortIntegerMultipleParameters() throws Exception {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x0B);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write(TYPED_PARAM_SEC | WSP_SHORT_INTEGER_MASK);
+ out.write(0x01 | WSP_SHORT_INTEGER_MASK);
+ out.write(TYPED_PARAM_MAC | WSP_SHORT_INTEGER_MASK);
+ out.write(WSP_QUOTE);
+ out.write("imapc".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+ assertEquals(12, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("1", params.get("SEC"));
+ assertEquals("imapc", params.get("MAC"));
+ }
+
+ public void testUntypedParamIntegerValueShortInteger() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x0A);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write("MYPARAM".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR); // EOS
+ out.write(0x45 | WSP_SHORT_INTEGER_MASK);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+ assertEquals(11, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("69", params.get("MYPARAM"));
+ }
+
+ public void testUntypedParamIntegerValueLongInteger() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x0C);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write("MYPARAM".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+ out.write(0x02); // Short Length
+ out.write(0x42); // Long Integer byte 1
+ out.write(0x69); // Long Integer byte 2
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(0x3F, unit.getValue32());
+ assertEquals(13, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("17001", params.get("MYPARAM"));
+ }
+
+ public void testUntypedParamTextNoValue() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x0A);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write("MYPARAM".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+ out.write(PARAM_NO_VALUE);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+ assertEquals(11, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals(null, params.get("MYPARAM"));
+
+ }
+
+ public void testUntypedParamTextTokenText() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x11);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write("MYPARAM".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+ out.write("myvalue".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+ assertEquals(18, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("myvalue", params.get("MYPARAM"));
+ }
+
+ public void testUntypedParamTextQuotedString() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x11);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write("MYPARAM".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+ out.write(WSP_QUOTE);
+ out.write("myvalue".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+ assertEquals(19, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("myvalue", params.get("MYPARAM"));
+
+ }
+
+ public void testDecodesReturnsFalse_ForParamWithMissingValue() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x09);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write("MYPARAM".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertFalse(unit.decodeContentType(0));
+ }
+
+ public void testTypedParamTextQValue() {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x04);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write(TYPED_PARAM_Q);
+ out.write(0x83); // Q value byte 1
+ out.write(0x31); // Q value byte 2
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(0x3F, unit.getValue32());
+ assertEquals(5, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("433", params.get("Q"));
+
+ }
+
+ public void testTypedParamUnassignedWellKnownShortIntegerTokenText() throws Exception {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x14);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write(PARAM_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
+ out.write("wdstechnology.com".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+
+ assertEquals(21, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("wdstechnology.com", params.get("unassigned/0x42"));
+
+ }
+
+ public void testTypedParamUnassignedWellKnownLongIntegerTokenText() throws Exception {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x15);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write(0x01); // Short-length of well-known parameter token
+ out.write(PARAM_UNASSIGNED);
+ out.write("wdstechnology.com".getBytes("US-ASCII"));
+ out.write(WSP_STRING_TERMINATOR);
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertTrue(unit.decodeContentType(0));
+
+ String mimeType = unit.getValueString();
+
+ assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
+ assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
+
+ assertEquals(22, unit.getDecodedDataLength());
+
+ Map<String, String> params = unit.getContentParameters();
+ assertEquals("wdstechnology.com", params.get("unassigned/0x42"));
+ }
+
+ public void testDecodesReturnsFalse_WhenParamValueNotTerminated() throws Exception {
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write(0x15);
+ out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
+ out.write(0x01);
+ out.write(PARAM_UNASSIGNED);
+ out.write("wdstechnology.com".getBytes("US-ASCII"));
+
+ WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
+ assertFalse(unit.decodeContentType(0));
+ }
+}
\ No newline at end of file
diff --git a/tests/CoreTests/android/AndroidManifest.xml b/tests/CoreTests/android/AndroidManifest.xml
index f02673c..8331f0c 100644
--- a/tests/CoreTests/android/AndroidManifest.xml
+++ b/tests/CoreTests/android/AndroidManifest.xml
@@ -24,6 +24,7 @@
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
<uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- location test permissions -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
diff --git a/tests/CoreTests/android/core/HttpHeaderTest.java b/tests/CoreTests/android/core/HttpHeaderTest.java
new file mode 100644
index 0000000..a5d48578
--- /dev/null
+++ b/tests/CoreTests/android/core/HttpHeaderTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 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.core;
+
+import android.test.AndroidTestCase;
+import org.apache.http.util.CharArrayBuffer;
+
+import android.net.http.Headers;
+
+public class HttpHeaderTest extends AndroidTestCase {
+
+ static final String LAST_MODIFIED = "Last-Modified: Fri, 18 Jun 2010 09:56:47 GMT";
+ static final String CACHE_CONTROL_MAX_AGE = "Cache-Control:max-age=15";
+ static final String CACHE_CONTROL_PRIVATE = "Cache-Control: private";
+
+ /**
+ * Tests that cache control header supports multiple instances of the header,
+ * according to HTTP specification.
+ *
+ * The HTTP specification states the following about the fields:
+ * Multiple message-header fields with the same field-name MAY be present
+ * in a message if and only if the entire field-value for that header field
+ * is defined as a comma-separated list [i.e., #(values)]. It MUST be
+ * possible to combine the multiple header fields into one "field-name:
+ * field-value" pair, without changing the semantics of the message, by
+ * appending each subsequent field-value to the first, each separated by a
+ * comma. The order in which header fields with the same field-name are
+ * received is therefore significant to the interpretation of the combined
+ * field value, and thus a proxy MUST NOT change the order of these field
+ * values when a message is forwarded.
+ */
+ public void testCacheControl() throws Exception {
+ Headers h = new Headers();
+ CharArrayBuffer buffer = new CharArrayBuffer(64);
+
+ buffer.append(CACHE_CONTROL_MAX_AGE);
+ h.parseHeader(buffer);
+
+ buffer.clear();
+ buffer.append(LAST_MODIFIED);
+ h.parseHeader(buffer);
+ assertEquals("max-age=15", h.getCacheControl());
+
+ buffer.clear();
+ buffer.append(CACHE_CONTROL_PRIVATE);
+ h.parseHeader(buffer);
+ assertEquals("max-age=15,private", h.getCacheControl());
+ }
+}
diff --git a/tests/CoreTests/android/core/ProxyTest.java b/tests/CoreTests/android/core/ProxyTest.java
new file mode 100644
index 0000000..12acfe8
--- /dev/null
+++ b/tests/CoreTests/android/core/ProxyTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 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.core;
+
+import org.apache.http.HttpHost;
+
+import android.content.Context;
+import android.net.Proxy;
+import android.test.AndroidTestCase;
+
+/**
+ * Proxy tests
+ */
+public class ProxyTest extends AndroidTestCase {
+ private Context mContext;
+ private HttpHost mHttpHost;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mContext = getContext();
+ mHttpHost = null;
+ String proxyHost = Proxy.getHost(mContext);
+ int proxyPort = Proxy.getPort(mContext);
+ if (proxyHost != null) {
+ mHttpHost = new HttpHost(proxyHost, proxyPort, "http");
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /**
+ * Bad url parameter should not cause any exception.
+ */
+ public void testProxyGetPreferredHttpHost_UrlBad() throws Exception {
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, null));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, ""));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad:"));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad"));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad:\\"));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "bad://#"));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "://#"));
+ }
+
+ /**
+ * Proxy (if available) should be returned when url parameter is not localhost.
+ */
+ public void testProxyGetPreferredHttpHost_UrlNotlLocalhost() throws Exception {
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://"));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://example.com"));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://example.com/"));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "http://192.168.0.1/"));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "file:///foo/bar"));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "rtsp://example.com"));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "rtsp://example.com/"));
+ assertEquals(mHttpHost, Proxy.getPreferredHttpHost(mContext, "javascript:alert(1)"));
+ }
+
+ /**
+ * No proxy should be returned when url parameter is localhost.
+ */
+ public void testProxyGetPreferredHttpHost_UrlLocalhost() throws Exception {
+ assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost"));
+ assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost/"));
+ assertNull(Proxy.getPreferredHttpHost(mContext, "http://localhost/hej.html"));
+ assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1"));
+ assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1/"));
+ assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1/hej.html"));
+ assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1:80/"));
+ assertNull(Proxy.getPreferredHttpHost(mContext, "http://127.0.0.1:8080/"));
+ assertNull(Proxy.getPreferredHttpHost(mContext, "rtsp://127.0.0.1/"));
+ assertNull(Proxy.getPreferredHttpHost(mContext, "rtsp://localhost/"));
+ assertNull(Proxy.getPreferredHttpHost(mContext, "https://localhost/"));
+ }
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java
index e741177..73d7363 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java
@@ -31,6 +31,7 @@
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.os.Bundle;
+import android.os.Environment;
public abstract class FileList extends ListActivity
@@ -179,10 +180,9 @@
getListView().setSelection(mFocusIndex);
}
- protected void setupPath()
- {
- mPath = "/sdcard/android/layout_tests";
- mBaseLength = mPath.length();
+ protected void setupPath() {
+ mPath = Environment.getExternalStorageDirectory() + "/android/layout_tests";
+ mBaseLength = mPath.length();
}
protected String mPath;
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
index 322b0d2..6cfce41 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
@@ -18,6 +18,7 @@
import com.android.dumprendertree.forwarder.ForwardService;
+import android.os.Environment;
import android.util.Log;
import java.io.BufferedOutputStream;
@@ -32,11 +33,17 @@
public class FsUtils {
private static final String LOGTAG = "FsUtils";
- static final String HTTP_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/";
- static final String HTTPS_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/ssl/";
- static final String HTTP_LOCAL_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/local/";
- static final String HTTP_MEDIA_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/media/";
- static final String HTTP_WML_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/wml/";
+ static final String EXTERNAL_DIR = Environment.getExternalStorageDirectory().toString();
+ static final String HTTP_TESTS_PREFIX =
+ EXTERNAL_DIR + "/android/layout_tests/http/tests/";
+ static final String HTTPS_TESTS_PREFIX =
+ EXTERNAL_DIR + "/android/layout_tests/http/tests/ssl/";
+ static final String HTTP_LOCAL_TESTS_PREFIX =
+ EXTERNAL_DIR + "/android/layout_tests/http/tests/local/";
+ static final String HTTP_MEDIA_TESTS_PREFIX =
+ EXTERNAL_DIR + "/android/layout_tests/http/tests/media/";
+ static final String HTTP_WML_TESTS_PREFIX =
+ EXTERNAL_DIR + "/android/layout_tests/http/tests/wml/";
private FsUtils() {
//no creation of instances
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
index 042158a..9ccf549 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
@@ -18,12 +18,12 @@
import com.android.dumprendertree.TestShellActivity.DumpDataType;
import com.android.dumprendertree.forwarder.AdbUtils;
-import com.android.dumprendertree.forwarder.ForwardServer;
import com.android.dumprendertree.forwarder.ForwardService;
import android.app.Instrumentation;
import android.content.Intent;
import android.os.Bundle;
+import android.os.Environment;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
@@ -92,10 +92,11 @@
public MyTestRecorder(boolean resume) {
try {
- File resultsPassedFile = new File("/sdcard/layout_tests_passed.txt");
- File resultsFailedFile = new File("/sdcard/layout_tests_failed.txt");
- File resultsIgnoreResultFile = new File("/sdcard/layout_tests_ignored.txt");
- File noExpectedResultFile = new File("/sdcard/layout_tests_nontext.txt");
+ File externalDir = Environment.getExternalStorageDirectory();
+ File resultsPassedFile = new File(externalDir, "layout_tests_passed.txt");
+ File resultsFailedFile = new File(externalDir, "layout_tests_failed.txt");
+ File resultsIgnoreResultFile = new File(externalDir, "layout_tests_ignored.txt");
+ File noExpectedResultFile = new File(externalDir, "layout_tests_nontext.txt");
mBufferedOutputPassedStream =
new BufferedOutputStream(new FileOutputStream(resultsPassedFile, resume));
@@ -128,11 +129,12 @@
private static final String LOGTAG = "LayoutTests";
static final int DEFAULT_TIMEOUT_IN_MILLIS = 5000;
- static final String LAYOUT_TESTS_ROOT = "/sdcard/android/layout_tests/";
- static final String LAYOUT_TESTS_RESULT_DIR = "/sdcard/android/layout_tests_results/";
- static final String ANDROID_EXPECTED_RESULT_DIR = "/sdcard/android/expected_results/";
- static final String LAYOUT_TESTS_LIST_FILE = "/sdcard/android/layout_tests_list.txt";
- static final String TEST_STATUS_FILE = "/sdcard/android/running_test.txt";
+ static final String EXTERNAL_DIR = Environment.getExternalStorageDirectory().toString();
+ static final String LAYOUT_TESTS_ROOT = EXTERNAL_DIR + "/android/layout_tests/";
+ static final String LAYOUT_TESTS_RESULT_DIR = EXTERNAL_DIR + "/android/layout_tests_results/";
+ static final String ANDROID_EXPECTED_RESULT_DIR = EXTERNAL_DIR + "/android/expected_results/";
+ static final String LAYOUT_TESTS_LIST_FILE = EXTERNAL_DIR + "/android/layout_tests_list.txt";
+ static final String TEST_STATUS_FILE = EXTERNAL_DIR + "/android/running_test.txt";
static final String LAYOUT_TESTS_RESULTS_REFERENCE_FILES[] = {
"results/layout_tests_passed.txt",
"results/layout_tests_failed.txt",
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
index 2ef342f..9352f39 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
@@ -22,6 +22,7 @@
import android.content.Intent;
import android.os.Bundle;
import android.os.Debug;
+import android.os.Environment;
import android.os.Process;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
@@ -35,7 +36,8 @@
public class LoadTestsAutoTest extends ActivityInstrumentationTestCase2<TestShellActivity> {
private final static String LOGTAG = "LoadTest";
- private final static String LOAD_TEST_RESULT = "/sdcard/load_test_result.txt";
+ private final static String LOAD_TEST_RESULT =
+ Environment.getExternalStorageDirectory() + "/load_test_result.txt";
private boolean mFinished;
static final String LOAD_TEST_RUNNER_FILES[] = {
"run_page_cycler.py"
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java b/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java
index 82671eb..9c4b57256 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java
@@ -18,6 +18,7 @@
import android.content.Intent;
import android.os.Bundle;
+import android.os.Environment;
import android.util.Log;
import java.io.BufferedOutputStream;
@@ -28,7 +29,8 @@
private static final int MENU_START = 0x01;
private static String LOGTAG = "MenuActivity";
- static final String LAYOUT_TESTS_LIST_FILE = "/sdcard/android/layout_tests_list.txt";
+ static final String LAYOUT_TESTS_LIST_FILE =
+ Environment.getExternalStorageDirectory() + "/android/layout_tests_list.txt";
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
index 9bc0962..d146fc7 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
@@ -18,6 +18,7 @@
import android.app.Activity;
import android.content.Intent;
+import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.test.ActivityInstrumentationTestCase2;
@@ -37,10 +38,16 @@
private static final String LOGTAG = "ReliabilityTest";
private static final String PKG_NAME = "com.android.dumprendertree";
- private static final String TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt";
- private static final String TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt";
- private static final String TEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt";
- private static final String TEST_LOAD_TIME_FILE = "/sdcard/android/reliability_load_time.txt";
+ private static final String EXTERNAL_DIR =
+ Environment.getExternalStorageDirectory().toString();
+ private static final String TEST_LIST_FILE = EXTERNAL_DIR +
+ "/android/reliability_tests_list.txt";
+ private static final String TEST_STATUS_FILE = EXTERNAL_DIR +
+ "/android/reliability_running_test.txt";
+ private static final String TEST_TIMEOUT_FILE = EXTERNAL_DIR +
+ "/android/reliability_timeout_test.txt";
+ private static final String TEST_LOAD_TIME_FILE = EXTERNAL_DIR +
+ "/android/reliability_load_time.txt";
private static final String TEST_DONE = "#DONE";
static final String RELIABILITY_TEST_RUNNER_FILES[] = {
"run_reliability_tests.py"
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index 81d5b08..7475719 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -30,6 +30,7 @@
import android.graphics.Bitmap.Config;
import android.net.http.SslError;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
@@ -862,7 +863,8 @@
static final String SAVE_IMAGE = "SaveImage";
static final int DRAW_RUNS = 5;
- static final String DRAW_TIME_LOG = "/sdcard/android/page_draw_time.txt";
+ static final String DRAW_TIME_LOG = Environment.getExternalStorageDirectory() +
+ "/android/page_draw_time.txt";
private boolean mGeolocationPermissionSet;
private boolean mGeolocationPermission;
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java
index 8b7de6e..25dd04fd 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java
@@ -21,6 +21,7 @@
import java.io.FileReader;
import java.io.IOException;
+import android.os.Environment;
import android.util.Log;
public class ForwardService {
@@ -33,7 +34,8 @@
private static final String DEFAULT_TEST_HOST = "android-browser-test.mtv.corp.google.com";
- private static final String FORWARD_HOST_CONF = "/sdcard/drt_forward_host.txt";
+ private static final String FORWARD_HOST_CONF =
+ Environment.getExternalStorageDirectory() + "/drt_forward_host.txt";
private ForwardService() {
int addr = getForwardHostAddr();
diff --git a/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java b/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java
index 98d0a50..4cfdf6c 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java
@@ -28,6 +28,7 @@
import android.database.Cursor;
import android.location.LocationManager;
import android.os.Bundle;
+import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
@@ -210,12 +211,11 @@
}
private String getUniqueFileName(String ext) {
- File dir = new File("/sdcard/locationtracker");
+ File dir = new File(Environment.getExternalStorageDirectory() + "/locationtracker");
if (!dir.exists()) {
dir.mkdir();
}
- return "/sdcard/locationtracker/tracking-" +
- DateUtils.getCurrentTimestamp() + "." + ext;
+ return dir + "/tracking-" + DateUtils.getCurrentTimestamp() + "." + ext;
}
private void launchSettings() {
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 21f3be4..37976ee 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -16,24 +16,19 @@
package com.android.statusbartest;
-import android.app.ListActivity;
import android.app.PendingIntent;
-import android.widget.ArrayAdapter;
-import android.view.View;
-import android.widget.ListView;
import android.content.Context;
import android.content.ContentResolver;
import android.content.Intent;
import android.app.Notification;
import android.app.NotificationManager;
+import android.os.Environment;
import android.os.Vibrator;
-import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.net.Uri;
import android.os.SystemClock;
import android.widget.RemoteViews;
-import android.widget.TextView;
import android.os.PowerManager;
public class NotificationTestList extends TestActivity
@@ -70,7 +65,8 @@
pm.goToSleep(SystemClock.uptimeMillis());
Notification n = new Notification();
- n.sound = Uri.parse("file:///sdcard/virtual-void.mp3");
+ n.sound = Uri.parse("file://" + Environment.getExternalStorageDirectory() +
+ "/virtual-void.mp3");
Log.d(TAG, "n.sound=" + n.sound);
mNM.notify(1, n);
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 22dbda3..59f2312 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -321,6 +321,7 @@
private static String LS = System.getProperty("line.separator");
private static String[] sDnsPropNames;
+ private Runnable mReleaseWakeLockCallback;
/**
* A structure for supplying information about a supplicant state
@@ -1430,7 +1431,7 @@
int netId = -1;
String[] lines = reply.split("\n");
for (String line : lines) {
- String[] prop = line.split(" *= *");
+ String[] prop = line.split(" *= *", 2);
if (prop.length < 2)
continue;
String name = prop[0];
@@ -2415,11 +2416,11 @@
setBluetoothCoexistenceMode(
WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
}
-
+
powerMode = getPowerMode();
if (powerMode < 0) {
- // Handle the case where supplicant driver does not support
- // getPowerModeCommand.
+ // Handle the case where supplicant driver does not support
+ // getPowerModeCommand.
powerMode = DRIVER_POWER_MODE_AUTO;
}
if (powerMode != DRIVER_POWER_MODE_ACTIVE) {