diff options
21 files changed, 421 insertions, 310 deletions
diff --git a/api/current.xml b/api/current.xml index 779d1228709e..a1dc293257f4 100644 --- a/api/current.xml +++ b/api/current.xml @@ -23732,6 +23732,50 @@ visibility="public" > </field> +<field name="EXTRA_DATA_KEY" + type="java.lang.String" + transient="false" + volatile="false" + value=""intent_extra_data_key"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="INTENT_ACTION_SEARCHABLES_CHANGED" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.search.action.SEARCHABLES_CHANGED"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="INTENT_ACTION_SEARCH_SETTINGS_CHANGED" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.search.action.SETTINGS_CHANGED"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="INTENT_ACTION_WEB_SEARCH_SETTINGS" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.search.action.WEB_SEARCH_SETTINGS"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="MENU_KEY" type="char" transient="false" @@ -23765,6 +23809,17 @@ visibility="public" > </field> +<field name="SHORTCUT_MIME_TYPE" + type="java.lang.String" + transient="false" + volatile="false" + value=""vnd.android.cursor.item/vnd.android.search.suggest"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="SUGGEST_COLUMN_FORMAT" type="java.lang.String" transient="false" @@ -23831,6 +23886,17 @@ visibility="public" > </field> +<field name="SUGGEST_COLUMN_INTENT_EXTRA_DATA" + type="java.lang.String" + transient="false" + volatile="false" + value=""suggest_intent_extra_data"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="SUGGEST_COLUMN_QUERY" type="java.lang.String" transient="false" @@ -23842,6 +23908,28 @@ visibility="public" > </field> +<field name="SUGGEST_COLUMN_SHORTCUT_ID" + type="java.lang.String" + transient="false" + volatile="false" + value=""suggest_shortcut_id"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING" + type="java.lang.String" + transient="false" + volatile="false" + value=""suggest_spinner_while_refreshing"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="SUGGEST_COLUMN_TEXT_1" type="java.lang.String" transient="false" @@ -23875,6 +23963,17 @@ visibility="public" > </field> +<field name="SUGGEST_NEVER_MAKE_SHORTCUT" + type="java.lang.String" + transient="false" + volatile="false" + value=""_-1"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="SUGGEST_URI_PATH_QUERY" type="java.lang.String" transient="false" @@ -23886,6 +23985,17 @@ visibility="public" > </field> +<field name="SUGGEST_URI_PATH_SHORTCUT" + type="java.lang.String" + transient="false" + volatile="false" + value=""search_suggest_shortcut"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="USER_QUERY" type="java.lang.String" transient="false" diff --git a/core/java/android/app/ISearchManager.aidl b/core/java/android/app/ISearchManager.aidl index 84a6085c4b75..bd725443e13a 100644 --- a/core/java/android/app/ISearchManager.aidl +++ b/core/java/android/app/ISearchManager.aidl @@ -37,4 +37,5 @@ interface ISearchManager { ISearchManagerCallback searchManagerCallback, int ident); void stopSearch(); + boolean isVisible(); } diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index 906361c3bcb5..27c637652d5e 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -354,7 +354,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS } show(); } - updateUI(); return true; @@ -490,6 +489,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS */ private void updateUI() { if (mSearchable != null) { + mDecor.setVisibility(View.VISIBLE); updateSearchAutoComplete(); updateSearchButton(); updateSearchAppIcon(); @@ -994,7 +994,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS }; @Override - public void dismiss() { + public void hide() { if (!isShowing()) return; // We made sure the IME was displayed, so also make sure it is closed @@ -1005,10 +1005,10 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS imm.hideSoftInputFromWindow( getWindow().getDecorView().getWindowToken(), 0); } - - super.dismiss(); + + super.hide(); } - + /** * React to the user typing while in the suggestions list. First, check for action * keys. If not handled, try refocusing regular characters into the EditText. @@ -1234,8 +1234,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS } /** - * Launches an intent and dismisses the search dialog (unless the intent - * is one of the special intents that modifies the state of the search dialog). + * Launches an intent, including any special intent handling. Doesn't dismiss the dialog + * since that will be handled in {@link SearchDialogWrapper#performActivityResuming} */ private void launchIntent(Intent intent) { if (intent == null) { @@ -1244,8 +1244,15 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS if (handleSpecialIntent(intent)){ return; } - dismiss(); + Log.d(LOG_TAG, "launching " + intent); getContext().startActivity(intent); + + // in global search mode, SearchDialogWrapper#performActivityResuming will handle hiding + // the dialog when the next activity starts, but for in-app search, we still need to + // dismiss the dialog. + if (!mGlobalSearchMode) { + dismiss(); + } } /** diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java index b795a5431ede..c98d966ce7bd 100644 --- a/core/java/android/app/SearchManager.java +++ b/core/java/android/app/SearchManager.java @@ -1188,8 +1188,6 @@ public class SearchManager /** * Intent extra data key: This key will be used for the extra populated by the * {@link #SUGGEST_COLUMN_INTENT_EXTRA_DATA} column. - * - * {@hide} */ public final static String EXTRA_DATA_KEY = "intent_extra_data_key"; @@ -1269,16 +1267,12 @@ public class SearchManager * result indicates the shortcut refers to a no longer valid sugggestion. * * @see #SUGGEST_COLUMN_SHORTCUT_ID - * - * @hide pending API council approval */ public final static String SUGGEST_URI_PATH_SHORTCUT = "search_suggest_shortcut"; /** * MIME type for shortcut validation. You'll use this in your suggestions content provider * in the getType() function. - * - * @hide pending API council approval */ public final static String SHORTCUT_MIME_TYPE = "vnd.android.cursor.item/vnd.android.search.suggest"; @@ -1389,9 +1383,7 @@ public class SearchManager * this element exists at the given row, this is the data that will be used when * forming the suggestion's intent. If not provided, the Intent's extra data field will be null. * This column allows suggestions to provide additional arbitrary data which will be included as - * an extra under the key EXTRA_DATA_KEY. - * - * @hide Pending API council approval. + * an extra under the key {@link #EXTRA_DATA_KEY}. */ public final static String SUGGEST_COLUMN_INTENT_EXTRA_DATA = "suggest_intent_extra_data"; /** @@ -1425,8 +1417,6 @@ public class SearchManager * {@link #SUGGEST_NEVER_MAKE_SHORTCUT}, the result will not be stored as a shortcut. * Otherwise, the shortcut id will be used to check back for validation via * {@link #SUGGEST_URI_PATH_SHORTCUT}. - * - * @hide Pending API council approval. */ public final static String SUGGEST_COLUMN_SHORTCUT_ID = "suggest_shortcut_id"; @@ -1443,8 +1433,6 @@ public class SearchManager * Column name for suggestions cursor. <i>Optional.</i> This column is used to specify * that a spinner should be shown in lieu of an icon2 while the shortcut of this suggestion * is being refreshed. - * - * @hide Pending API council approval. */ public final static String SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING = "suggest_spinner_while_refreshing"; @@ -1452,8 +1440,6 @@ public class SearchManager /** * Column value for suggestion column {@link #SUGGEST_COLUMN_SHORTCUT_ID} when a suggestion * should not be stored as a shortcut in global search. - * - * @hide Pending API council approval. */ public final static String SUGGEST_NEVER_MAKE_SHORTCUT = "_-1"; @@ -1500,8 +1486,6 @@ public class SearchManager * Intent action for starting a web search provider's settings activity. * Web search providers should handle this intent if they have provider-specific * settings to implement. - * - * @hide Pending API council approval. */ public final static String INTENT_ACTION_WEB_SEARCH_SETTINGS = "android.search.action.WEB_SEARCH_SETTINGS"; @@ -1510,11 +1494,17 @@ public class SearchManager * Intent action broadcasted to inform that the searchables list or default have changed. * Components should handle this intent if they cache any searchable data and wish to stay * up to date on changes. - * - * @hide Pending API council approval. */ public final static String INTENT_ACTION_SEARCHABLES_CHANGED = "android.search.action.SEARCHABLES_CHANGED"; + + /** + * Intent action broadcasted to inform that the search settings have changed in some way. + * Either searchables have been enabled or disabled, or a different web search provider + * has been chosen. + */ + public final static String INTENT_ACTION_SEARCH_SETTINGS_CHANGED + = "android.search.action.SETTINGS_CHANGED"; /** * If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION}, @@ -1534,7 +1524,6 @@ public class SearchManager private int mIdent; // package private since they are used by the inner class SearchManagerCallback - /* package */ boolean mIsShowing = false; /* package */ final Handler mHandler; /* package */ OnDismissListener mDismissListener = null; /* package */ OnCancelListener mCancelListener = null; @@ -1600,12 +1589,9 @@ public class SearchManager ComponentName launchActivity, Bundle appSearchData, boolean globalSearch) { - if (DBG) debug("startSearch(), mIsShowing=" + mIsShowing); - if (mIsShowing) return; if (mIdent == 0) throw new IllegalArgumentException( "Called from outside of an Activity context"); try { - mIsShowing = true; // activate the search manager and start it up! mService.startSearch(initialQuery, selectInitialQuery, launchActivity, appSearchData, globalSearch, mSearchManagerCallback, mIdent); @@ -1626,15 +1612,10 @@ public class SearchManager * @see #startSearch */ public void stopSearch() { - if (DBG) debug("stopSearch(), mIsShowing=" + mIsShowing); - if (!mIsShowing) return; + if (DBG) debug("stopSearch()"); try { mService.stopSearch(); - // onDismiss will also clear this, but we do it here too since onDismiss() is - // called asynchronously. - mIsShowing = false; } catch (RemoteException ex) { - Log.e(TAG, "stopSearch() failed: " + ex); } } @@ -1648,8 +1629,13 @@ public class SearchManager * @hide */ public boolean isVisible() { - if (DBG) debug("isVisible(), mIsShowing=" + mIsShowing); - return mIsShowing; + if (DBG) debug("isVisible()"); + try { + return mService.isVisible(); + } catch (RemoteException e) { + Log.e(TAG, "isVisible() failed: " + e); + return false; + } } /** @@ -1701,7 +1687,6 @@ public class SearchManager private final Runnable mFireOnDismiss = new Runnable() { public void run() { if (DBG) debug("mFireOnDismiss"); - mIsShowing = false; if (mDismissListener != null) { mDismissListener.onDismiss(); } @@ -1711,7 +1696,6 @@ public class SearchManager private final Runnable mFireOnCancel = new Runnable() { public void run() { if (DBG) debug("mFireOnCancel"); - // doesn't need to clear mIsShowing since onDismiss() always gets called too if (mCancelListener != null) { mCancelListener.onCancel(); } diff --git a/core/java/android/content/AbstractTableMerger.java b/core/java/android/content/AbstractTableMerger.java index 9c760d94ad63..9f609a390ba6 100644 --- a/core/java/android/content/AbstractTableMerger.java +++ b/core/java/android/content/AbstractTableMerger.java @@ -369,30 +369,33 @@ public abstract class AbstractTableMerger // An existing server item has changed // If serverSyncVersion is null, there is no edit URL; // server won't let this change be written. - // Just hold onto it, I guess, in case the server permissions - // change later. - if (serverSyncVersion != null) { - boolean recordChanged = (localSyncVersion == null) || - !serverSyncVersion.equals(localSyncVersion); - if (recordChanged) { - if (localSyncDirty) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "remote record " + serverSyncId - + " conflicts with local _sync_id " + localSyncID - + ", local _id " + localRowId); - } - conflict = true; - } else { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, - "remote record " + - serverSyncId + - " updates local _sync_id " + - localSyncID + ", local _id " + - localRowId); - } - update = true; + boolean recordChanged = (localSyncVersion == null) || + (serverSyncVersion == null) || + !serverSyncVersion.equals(localSyncVersion); + if (recordChanged) { + if (localSyncDirty) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "remote record " + serverSyncId + + " conflicts with local _sync_id " + localSyncID + + ", local _id " + localRowId); } + conflict = true; + } else { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, + "remote record " + + serverSyncId + + " updates local _sync_id " + + localSyncID + ", local _id " + + localRowId); + } + update = true; + } + } else { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, + "Skipping update: localSyncVersion: " + localSyncVersion + + ", serverSyncVersion: " + serverSyncVersion); } } } else { diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 528def5c4011..e203fd590258 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -508,6 +508,19 @@ public abstract class BatteryStats implements Parcelable { public abstract long getBatteryUptime(long curTime); /** + * @deprecated use getRadioDataUptime + */ + public long getRadioDataUptimeMs() { + return getRadioDataUptime() / 1000; + } + + /** + * Returns the time that the radio was on for data transfers. + * @return the uptime in microseconds while unplugged + */ + public abstract long getRadioDataUptime(); + + /** * Returns the current battery realtime in microseconds. * * @param curTime the amount of elapsed realtime in microseconds. @@ -1128,7 +1141,14 @@ public abstract class BatteryStats implements Parcelable { } if (!didOne) sb.append("No activity"); pw.println(sb.toString()); - + + sb.setLength(0); + sb.append(prefix); + sb.append(" Radio data uptime when unplugged: "); + sb.append(getRadioDataUptime() / 1000); + sb.append(" ms"); + pw.println(sb.toString()); + sb.setLength(0); sb.append(prefix); sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000); diff --git a/core/java/android/server/search/SearchDialogWrapper.java b/core/java/android/server/search/SearchDialogWrapper.java index 70c7d7313bae..d3ef5de8634f 100644 --- a/core/java/android/server/search/SearchDialogWrapper.java +++ b/core/java/android/server/search/SearchDialogWrapper.java @@ -45,8 +45,6 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { private static final String TAG = "SearchManagerService"; private static final boolean DBG = false; - private static final String DISABLE_SEARCH_PROPERTY = "dev.disablesearchdialog"; - private static final String SEARCH_UI_THREAD_NAME = "SearchDialog"; private static final int SEARCH_UI_THREAD_PRIORITY = android.os.Process.THREAD_PRIORITY_DEFAULT; @@ -88,12 +86,11 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { // Identity of currently resumed activity. private int mResumedIdent = 0; - - // Allows disabling of search dialog for stress testing runs - private final boolean mDisabledOnBoot; // True if we have registered our receivers. private boolean mReceiverRegistered; + + private volatile boolean mVisible = false; /** * Creates a new search dialog wrapper and a search UI thread. The search dialog itself will @@ -104,8 +101,6 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { public SearchDialogWrapper(Context context) { mContext = context; - mDisabledOnBoot = !TextUtils.isEmpty(SystemProperties.get(DISABLE_SEARCH_PROPERTY)); - // Create the search UI thread HandlerThread t = new HandlerThread(SEARCH_UI_THREAD_NAME, SEARCH_UI_THREAD_PRIORITY); t.start(); @@ -115,6 +110,10 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { mSearchUiThread.sendEmptyMessage(MSG_INIT); } + public boolean isVisible() { + return mVisible; + } + /** * Initializes the search UI. * Must be called from the search UI thread. @@ -151,8 +150,10 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { - if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - performStopSearch(); + if (!"search".equals(intent.getStringExtra("reason"))) { + if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + performStopSearch(); + } } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { if (DBG) debug(Intent.ACTION_CONFIGURATION_CHANGED); performOnConfigurationChanged(); @@ -205,7 +206,7 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { * Can be called from any thread. */ public void activityResuming(int ident) { - if (DBG) debug("startSearch()"); + if (DBG) debug("activityResuming(ident=" + ident + ")"); Message msg = Message.obtain(); msg.what = MSG_ACTIVITY_RESUMING; msg.arg1 = ident; @@ -256,20 +257,6 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { } - void updateDialogVisibility() { - if (mStartedIdent != 0) { - // mResumedIdent == 0 means we have just booted and the user - // hasn't yet gone anywhere. - if (mResumedIdent == 0 || mStartedIdent == mResumedIdent) { - if (DBG) Log.v(TAG, "******************* DIALOG: show"); - mSearchDialog.show(); - } else { - if (DBG) Log.v(TAG, "******************* DIALOG: hide"); - mSearchDialog.hide(); - } - } - } - /** * Actually launches the search UI. * This must be called on the search UI thread. @@ -283,19 +270,20 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { int ident) { if (DBG) debug("performStartSearch()"); - if (mDisabledOnBoot) { - Log.d(TAG, "ignoring start search request because " + DISABLE_SEARCH_PROPERTY - + " system property is set."); - return; - } - registerBroadcastReceiver(); mCallback = searchManagerCallback; + + // clean up any hidden dialog that we were waiting to resume + if (mStartedIdent != 0) { + mSearchDialog.dismiss(); + } + mStartedIdent = ident; if (DBG) Log.v(TAG, "******************* DIALOG: start"); + mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData, globalSearch); - updateDialogVisibility(); + mVisible = true; } /** @@ -306,6 +294,7 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { if (DBG) debug("performStopSearch()"); if (DBG) Log.v(TAG, "******************* DIALOG: cancel"); mSearchDialog.cancel(); + mVisible = false; mStartedIdent = 0; } @@ -317,7 +306,21 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { if (DBG) debug("performResumingActivity(): mStartedIdent=" + mStartedIdent + ", resuming: " + ident); this.mResumedIdent = ident; - updateDialogVisibility(); + if (mStartedIdent != 0) { + if (mStartedIdent == mResumedIdent) { + // we are resuming into the activity where we previously hid the dialog, bring it + // back + if (DBG) Log.v(TAG, "******************* DIALOG: show"); + mSearchDialog.show(); + mVisible = true; + } else { + // resuming into some other activity; hide ourselves in case we ever come back + // so we can show ourselves quickly again + if (DBG) Log.v(TAG, "******************* DIALOG: hide"); + mSearchDialog.hide(); + mVisible = false; + } + } } /** @@ -333,27 +336,38 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { */ public void onDismiss(DialogInterface dialog) { if (DBG) debug("onDismiss()"); - if (mCallback != null) { - try { - // should be safe to do on the search UI thread, since it's a oneway interface - mCallback.onDismiss(); - } catch (DeadObjectException ex) { - // The process that hosted the callback has died, do nothing - } catch (RemoteException ex) { - Log.e(TAG, "onDismiss() failed: " + ex); - } - // we don't need the callback anymore, release it - mCallback = null; - } + mStartedIdent = 0; + mVisible = false; + callOnDismiss(); + + // we don't need the callback anymore, release it + mCallback = null; unregisterBroadcastReceiver(); } + /** * Called by {@link SearchDialog} when the user or activity cancels search. * Whenever this method is called, {@link #onDismiss} is always called afterwards. */ public void onCancel(DialogInterface dialog) { if (DBG) debug("onCancel()"); + callOnCancel(); + } + + private void callOnDismiss() { + if (mCallback == null) return; + try { + // should be safe to do on the search UI thread, since it's a oneway interface + mCallback.onDismiss(); + } catch (DeadObjectException ex) { + // The process that hosted the callback has died, do nothing + } catch (RemoteException ex) { + Log.e(TAG, "onDismiss() failed: " + ex); + } + } + + private void callOnCancel() { if (mCallback != null) { try { // should be safe to do on the search UI thread, since it's a oneway interface diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java index 762991260dad..fdeb8f9e3fc2 100644 --- a/core/java/android/server/search/SearchManagerService.java +++ b/core/java/android/server/search/SearchManagerService.java @@ -238,4 +238,8 @@ public class SearchManagerService extends ISearchManager.Stub { getSearchDialog().stopSearch(); } + public boolean isVisible() { + return mSearchDialog != null && mSearchDialog.isVisible(); + } + } diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java index 4794fe1e9c7f..bb6b4b0385d8 100755 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -820,14 +820,14 @@ public class TextToSpeech { if (speechRate > 0) { int rate = (int)(speechRate*100); mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] = String.valueOf(rate); - result = mITts.setSpeechRate(mPackageName, rate); + // the rate is not set here, instead it is cached so it will be associated + // with all upcoming utterances. + if (speechRate > 0.0f) { + result = TTS_SUCCESS; + } else { + result = TTS_ERROR; + } } - } catch (RemoteException e) { - // TTS died; restart it. - Log.e("TextToSpeech.java - setSpeechRate", "RemoteException"); - e.printStackTrace(); - mStarted = false; - initTts(); } catch (NullPointerException e) { // TTS died; restart it. Log.e("TextToSpeech.java - setSpeechRate", "NullPointerException"); @@ -907,7 +907,9 @@ public class TextToSpeech { * @param loc * The locale describing the language to be used. * - * @return Code indicating the support status for the locale. See the TTS_LANG_ codes. + * @return code indicating the support status for the locale. See {@link #TTS_LANG_AVAILABLE}, + * {@link #TTS_LANG_COUNTRY_AVAILABLE}, {@link #TTS_LANG_COUNTRY_VAR_AVAILABLE}, + * {@link #TTS_LANG_MISSING_DATA} and {@link #TTS_LANG_NOT_SUPPORTED}. */ public int setLanguage(Locale loc) { synchronized (mStartLock) { @@ -919,6 +921,7 @@ public class TextToSpeech { mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language(); mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country(); mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = loc.getVariant(); + result = mITts.setLanguage(mPackageName, mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1], mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1], @@ -994,8 +997,9 @@ public class TextToSpeech { * @param loc * The Locale describing the language to be used. * - * @return one of TTS_LANG_NOT_SUPPORTED, TTS_LANG_MISSING_DATA, TTS_LANG_AVAILABLE, - * TTS_LANG_COUNTRY_AVAILABLE, TTS_LANG_COUNTRY_VAR_AVAILABLE. + * @return code indicating the support status for the locale. See {@link #TTS_LANG_AVAILABLE}, + * {@link #TTS_LANG_COUNTRY_AVAILABLE}, {@link #TTS_LANG_COUNTRY_VAR_AVAILABLE}, + * {@link #TTS_LANG_MISSING_DATA} and {@link #TTS_LANG_NOT_SUPPORTED}. */ public int isLanguageAvailable(Locale loc) { synchronized (mStartLock) { diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 0df587f1bda7..4bc00de33e81 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -1296,11 +1296,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe } } - // Max height available on the screen for a popup. If this AutoCompleteTextView has - // the dropDownAlwaysVisible attribute, and the input method is not currently required, - // we then we ask for the height ignoring any bottom decorations like the input method. - // Otherwise we respect the input method. - boolean ignoreBottomDecorations = mDropDownAlwaysVisible && + // Max height available on the screen for a popup. + boolean ignoreBottomDecorations = mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; final int maxHeight = mPopup.getMaxAvailableHeight( getDropDownAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index a03802dff012..a449e5f00919 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -16,6 +16,7 @@ package com.android.internal.os; +import android.bluetooth.BluetoothHeadset; import android.os.BatteryStats; import android.os.NetStat; import android.os.Parcel; @@ -128,7 +129,10 @@ public final class BatteryStatsImpl extends BatteryStats { boolean mBluetoothOn; StopwatchTimer mBluetoothOnTimer; - + + /** Bluetooth headset object */ + BluetoothHeadset mBtHeadset; + /** * These provide time bases that discount the time the device is plugged * in to power. @@ -160,6 +164,9 @@ public final class BatteryStatsImpl extends BatteryStats { private long mRadioDataUptime; private long mRadioDataStart; + private int mBluetoothPingCount; + private int mBluetoothPingStart = -1; + /* * Holds a SamplingTimer associated with each kernel wakelock name being tracked. */ @@ -920,14 +927,18 @@ public final class BatteryStatsImpl extends BatteryStats { dataTransfer[STATS_UNPLUGGED] = currentBytes; } - private long getCurrentRadioDataUptimeMs() { + /** + * Radio uptime in microseconds when transferring data. This value is very approximate. + * @return + */ + private long getCurrentRadioDataUptime() { try { File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms"); if (!awakeTimeFile.exists()) return 0; BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile)); String line = br.readLine(); br.close(); - return Long.parseLong(line); + return Long.parseLong(line) * 1000; } catch (NumberFormatException nfe) { // Nothing } catch (IOException ioe) { @@ -936,14 +947,44 @@ public final class BatteryStatsImpl extends BatteryStats { return 0; } + /** + * @deprecated use getRadioDataUptime + */ public long getRadioDataUptimeMs() { + return getRadioDataUptime() / 1000; + } + + /** + * Returns the duration that the cell radio was up for data transfers. + */ + public long getRadioDataUptime() { if (mRadioDataStart == -1) { return mRadioDataUptime; } else { - return getCurrentRadioDataUptimeMs() - mRadioDataStart; + return getCurrentRadioDataUptime() - mRadioDataStart; } } + private int getCurrentBluetoothPingCount() { + if (mBtHeadset != null) { + return mBtHeadset.getBatteryUsageHint(); + } + return -1; + } + + public int getBluetoothPingCount() { + if (mBluetoothPingStart == -1) { + return mBluetoothPingCount; + } else if (mBtHeadset != null) { + return getCurrentBluetoothPingCount() - mBluetoothPingStart; + } + return -1; + } + + public void setBtHeadset(BluetoothHeadset headset) { + mBtHeadset = headset; + } + public void doUnplug(long batteryUptime, long batteryRealtime) { for (int iu = mUidStats.size() - 1; iu >= 0; iu--) { Uid u = mUidStats.valueAt(iu); @@ -961,8 +1002,11 @@ public final class BatteryStatsImpl extends BatteryStats { doDataUnplug(mTotalDataRx, NetStat.getTotalRxBytes()); doDataUnplug(mTotalDataTx, NetStat.getTotalTxBytes()); // Track radio awake time - mRadioDataStart = getCurrentRadioDataUptimeMs(); + mRadioDataStart = getCurrentRadioDataUptime(); mRadioDataUptime = 0; + // Track bt headset ping count + mBluetoothPingStart = getCurrentBluetoothPingCount(); + mBluetoothPingCount = 0; } public void doPlug(long batteryUptime, long batteryRealtime) { @@ -985,8 +1029,12 @@ public final class BatteryStatsImpl extends BatteryStats { doDataPlug(mTotalDataRx, NetStat.getTotalRxBytes()); doDataPlug(mTotalDataTx, NetStat.getTotalTxBytes()); // Track radio awake time - mRadioDataUptime = getRadioDataUptimeMs(); + mRadioDataUptime = getRadioDataUptime(); mRadioDataStart = -1; + + // Track bt headset ping count + mBluetoothPingCount = getBluetoothPingCount(); + mBluetoothPingStart = -1; } public void noteStartGps(int uid) { @@ -3335,6 +3383,9 @@ public final class BatteryStatsImpl extends BatteryStats { mRadioDataUptime = in.readLong(); mRadioDataStart = -1; + mBluetoothPingCount = in.readInt(); + mBluetoothPingStart = -1; + mKernelWakelockStats.clear(); int NKW = in.readInt(); for (int ikw = 0; ikw < NKW; ikw++) { @@ -3415,7 +3466,9 @@ public final class BatteryStatsImpl extends BatteryStats { out.writeLong(getTotalTcpBytesSent(STATS_UNPLUGGED)); // Write radio uptime for data - out.writeLong(getRadioDataUptimeMs()); + out.writeLong(getRadioDataUptime()); + + out.writeInt(getBluetoothPingCount()); out.writeInt(mKernelWakelockStats.size()); for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java index 4a8d8b182f90..94f703add469 100644 --- a/core/java/com/android/internal/os/PowerProfile.java +++ b/core/java/com/android/internal/os/PowerProfile.java @@ -87,6 +87,11 @@ public class PowerProfile { public static final String POWER_BLUETOOTH_ACTIVE = "bluetooth.active"; /** + * Power consumption when Bluetooth driver gets an AT command. + */ + public static final String POWER_BLUETOOTH_AT_CMD = "bluetooth.at"; + + /** * Power consumption when screen is on, not including the backlight power. */ public static final String POWER_SCREEN_ON = "screen.on"; diff --git a/core/res/res/layout/search_dropdown_app_selector.xml b/core/res/res/layout/search_dropdown_app_selector.xml deleted file mode 100644 index f86645fa829d..000000000000 --- a/core/res/res/layout/search_dropdown_app_selector.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* //device/apps/common/res/layout/search_dropdown_app_selector.xml -** -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="?android:attr/listPreferredItemHeight" - android:orientation="horizontal" - android:gravity="center_vertical" - android:baselineAligned="false" - > - - <ImageView android:id="@+id/search_app_icon1" - android:layout_width="32dip" - android:layout_height="32dip" - android:layout_gravity="center_vertical" - android:scaleType="fitCenter" - android:src="@android:drawable/ic_search_category_default" /> - - <TextView android:id="@+id/search_app_text1" - style="?android:attr/dropDownItemStyle" - android:singleLine="true" - android:layout_height="wrap_content" - android:layout_width="0dip" - android:layout_weight="1" - android:layout_gravity="center_vertical" /> - -</LinearLayout> diff --git a/core/res/res/layout/search_dropdown_item_2line.xml b/core/res/res/layout/search_dropdown_item_2line.xml deleted file mode 100644 index 5546b6636bb9..000000000000 --- a/core/res/res/layout/search_dropdown_item_2line.xml +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml -** -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="?android:attr/searchResultListItemHeight" - android:orientation="horizontal" - android:gravity="center_vertical" - android:baselineAligned="false" - > - - <TwoLineListItem - android:paddingTop="1dip" - android:paddingBottom="1dip" - android:gravity="center_vertical" - android:layout_width="0dip" - android:layout_weight="1" - android:layout_height="wrap_content" - android:mode="twoLine" > - - <TextView - android:id="@android:id/text1" - style="?android:attr/dropDownItemStyle" - android:textAppearance="?android:attr/textAppearanceSearchResultTitle" - android:singleLine="true" - android:layout_width="fill_parent" - android:layout_height="wrap_content" /> - - <TextView - android:id="@android:id/text2" - style="?android:attr/dropDownItemStyle" - android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle" - android:textColor="?android:attr/textColorSecondaryInverse" - android:singleLine="true" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_below="@android:id/text1" - android:layout_alignLeft="@android:id/text1" /> - - </TwoLineListItem> - -</LinearLayout> diff --git a/core/res/res/layout/search_dropdown_item_icons_1line.xml b/core/res/res/layout/search_dropdown_item_icons_1line.xml deleted file mode 100644 index 4f65d746b4eb..000000000000 --- a/core/res/res/layout/search_dropdown_item_icons_1line.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml -** -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - - <!-- NOTE: The appearance of the inner text element must match the appearance --> - <!-- of the text element in apps/common/res/layout/simple_dropdown_item_1line.xml --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:paddingLeft="4dip" - android:paddingRight="2dip" - android:layout_width="fill_parent" - android:layout_height="?android:attr/searchResultListItemHeight" - android:orientation="horizontal" - android:gravity="center_vertical" - android:baselineAligned="false" - > - - <ImageView android:id="@android:id/icon1" - android:layout_width="48dip" - android:layout_height="48dip" - android:layout_gravity="center_vertical" - android:scaleType="centerInside" /> - - <TextView android:id="@android:id/text1" - style="?android:attr/dropDownItemStyle" - android:textAppearance="?android:attr/textAppearanceSearchResultTitle" - android:singleLine="true" - android:layout_height="wrap_content" - android:layout_width="0dip" - android:layout_weight="1" /> - - <ImageView android:id="@android:id/icon2" - android:layout_width="48dip" - android:layout_height="48dip" - android:layout_gravity="center_vertical" - android:scaleType="centerInside" /> - -</LinearLayout> diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp index 80eb3cb39071..82067be1d8f1 100644 --- a/packages/TtsService/jni/android_tts_SynthProxy.cpp +++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp @@ -59,6 +59,9 @@ struct afterSynthData_t { // ---------------------------------------------------------------------------- static fields_t javaTTSFields; +// TODO move to synth member once we have multiple simultaneous engines running +static Mutex engineMutex; + // ---------------------------------------------------------------------------- class SynthProxyJniStorage { public : @@ -330,6 +333,8 @@ android_tts_SynthProxy_setLanguage(JNIEnv *env, jobject thiz, jint jniData, return result; } + Mutex::Autolock l(engineMutex); + SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData; const char *langNativeString = env->GetStringUTFChars(language, 0); const char *countryNativeString = env->GetStringUTFChars(country, 0); @@ -389,6 +394,8 @@ android_tts_SynthProxy_setSpeechRate(JNIEnv *env, jobject thiz, jint jniData, char buffer [bufSize]; sprintf(buffer, "%d", speechRate); + Mutex::Autolock l(engineMutex); + SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData; LOGI("setting speech rate to %d", speechRate); @@ -411,6 +418,8 @@ android_tts_SynthProxy_setPitch(JNIEnv *env, jobject thiz, jint jniData, return result; } + Mutex::Autolock l(engineMutex); + int bufSize = 10; char buffer [bufSize]; sprintf(buffer, "%d", pitch); @@ -443,6 +452,8 @@ android_tts_SynthProxy_synthesizeToFile(JNIEnv *env, jobject thiz, jint jniData, return result; } + Mutex::Autolock l(engineMutex); + // Retrieve audio parameters before writing the file header AudioSystem::audio_format encoding = DEFAULT_TTS_FORMAT; uint32_t rate = DEFAULT_TTS_RATE; @@ -545,10 +556,11 @@ android_tts_SynthProxy_speak(JNIEnv *env, jobject thiz, jint jniData, return result; } + Mutex::Autolock l(engineMutex); + SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData; if (pSynthData->mAudioOut) { - pSynthData->mAudioOut->stop(); pSynthData->mAudioOut->start(); } @@ -600,6 +612,8 @@ android_tts_SynthProxy_shutdown(JNIEnv *env, jobject thiz, jint jniData) return; } + Mutex::Autolock l(engineMutex); + SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData; if (pSynthData->mNativeSynthInterface) { pSynthData->mNativeSynthInterface->shutdown(); diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java index 28801f8b50ad..9a4c97da58ce 100755 --- a/packages/TtsService/src/android/tts/TtsService.java +++ b/packages/TtsService/src/android/tts/TtsService.java @@ -546,7 +546,7 @@ public class TtsService extends Service implements OnCompletionListener { if (!synthAvailable) { Thread.sleep(100); Thread synth = (new Thread(new SynthThread())); - synth.setPriority(Thread.MIN_PRIORITY); + //synth.setPriority(Thread.MIN_PRIORITY); synth.start(); return; } @@ -608,7 +608,7 @@ public class TtsService extends Service implements OnCompletionListener { } } Thread synth = (new Thread(new SynthThread())); - synth.setPriority(Thread.MIN_PRIORITY); + //synth.setPriority(Thread.MIN_PRIORITY); synth.start(); } @@ -623,7 +623,7 @@ public class TtsService extends Service implements OnCompletionListener { if (!synthAvailable) { Thread.sleep(100); Thread synth = (new Thread(new SynthThread())); - synth.setPriority(Thread.MIN_PRIORITY); + //synth.setPriority(Thread.MIN_PRIORITY); synth.start(); return; } @@ -677,7 +677,7 @@ public class TtsService extends Service implements OnCompletionListener { } } Thread synth = (new Thread(new SynthThread())); - synth.setPriority(Thread.MIN_PRIORITY); + //synth.setPriority(Thread.MIN_PRIORITY); synth.start(); } diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 5425709fa994..2937ed00b45a 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -27,6 +27,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND; import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND; import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; +import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; import static android.view.WindowManager.LayoutParams.FLAG_SYSTEM_ERROR; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; @@ -1857,7 +1858,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo // is running. if (!mDisplayFrozen) { Animation a; - if ((lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) { + if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) { a = new FadeInOutAnimation(enter); if (DEBUG_ANIM) Log.v(TAG, "applying FadeInOutAnimation for a window in compatibility mode"); @@ -5871,7 +5872,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) { container.intersect(mCompatibleScreenFrame); - display.intersect(mCompatibleScreenFrame); + if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) { + display.intersect(mCompatibleScreenFrame); + } } final int pw = container.right - container.left; @@ -6588,12 +6591,17 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo return false; } final Rect frame = shownFrame ? mShownFrame : mFrame; - if (frame.left <= 0 && frame.top <= 0 - && frame.right >= screenWidth - && frame.bottom >= screenHeight) { - return true; + + if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) { + return frame.left <= mCompatibleScreenFrame.left && + frame.top <= mCompatibleScreenFrame.top && + frame.right >= mCompatibleScreenFrame.right && + frame.bottom >= mCompatibleScreenFrame.bottom; + } else { + return frame.left <= 0 && frame.top <= 0 + && frame.right >= screenWidth + && frame.bottom >= screenHeight; } - return false; } /** @@ -6610,16 +6618,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 && // only if it's visible mHasDrawn && mViewVisibility == View.VISIBLE && - // and only if the application wanted to fill the screen - mAttrs.width == mAttrs.FILL_PARENT && - mAttrs.height == mAttrs.FILL_PARENT && - // and only if the window is not hidden - mFrame.left == mCompatibleScreenFrame.left && + // and only if the application fills the compatible screen + mFrame.left <= mCompatibleScreenFrame.left && + mFrame.top <= mCompatibleScreenFrame.top && + mFrame.right >= mCompatibleScreenFrame.right && + mFrame.bottom >= mCompatibleScreenFrame.bottom && // and starting window do not need background filler - mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING && - // and only if the screen is bigger - ((mFrame.right - mFrame.right) < screenWidth || - (mFrame.bottom - mFrame.top) < screenHeight); + mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING; } boolean isFullscreen(int screenWidth, int screenHeight) { diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java index 39a1ee050226..c834b34e3568 100644 --- a/services/java/com/android/server/am/BatteryStatsService.java +++ b/services/java/com/android/server/am/BatteryStatsService.java @@ -41,7 +41,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub { final BatteryStatsImpl mStats; Context mContext; - + BatteryStatsService(String filename) { mStats = new BatteryStatsImpl(filename); } diff --git a/tests/AndroidTests/AndroidManifest.xml b/tests/AndroidTests/AndroidManifest.xml index 55d4d64bf547..845f54749641 100644 --- a/tests/AndroidTests/AndroidManifest.xml +++ b/tests/AndroidTests/AndroidManifest.xml @@ -48,6 +48,7 @@ <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_GSERVICES" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="com.android.unit_tests.permission.TEST_GRANTED" /> diff --git a/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java b/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java new file mode 100755 index 000000000000..7dc13141e0c6 --- /dev/null +++ b/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java @@ -0,0 +1,46 @@ +/* + * 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 com.android.unit_tests; + +import android.net.vpn.L2tpIpsecProfile; +import android.net.vpn.VpnType; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +/** + * Unit test class to test VPN api + * Use the below command to run the vpn unit test only + * runtest vpntest or + * adb shell am instrument -e class 'com.android.unit_tests.VpnTest' + * -w com.android.unit_tests/android.test.InstrumentationTestRunner + */ +public class VpnTest extends AndroidTestCase { + + @Override + public void setUp() { + } + + @Override + public void tearDown() { + } + + @SmallTest + public void testGetType() { + L2tpIpsecProfile li = new L2tpIpsecProfile(); + assertTrue(VpnType.L2TP_IPSEC== li.getType()); + } +} |