diff options
Diffstat (limited to 'tests')
186 files changed, 4939 insertions, 3114 deletions
diff --git a/tests/AccessibilityEventsLogger/Android.mk b/tests/AccessibilityEventsLogger/Android.mk new file mode 100644 index 0000000..52bc579 --- /dev/null +++ b/tests/AccessibilityEventsLogger/Android.mk @@ -0,0 +1,13 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := AccessibilityEventsLogger +LOCAL_CERTIFICATE := platform + +LOCAL_PROGUARD_ENABLED := disabled + +include $(BUILD_PACKAGE) diff --git a/tests/AccessibilityEventsLogger/AndroidManifest.xml b/tests/AccessibilityEventsLogger/AndroidManifest.xml new file mode 100644 index 0000000..d86769f --- /dev/null +++ b/tests/AccessibilityEventsLogger/AndroidManifest.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="com.android.tests.accessibilityeventlogger" + android:versionCode="1" + android:versionName="0.0" > + + <uses-sdk + android:minSdkVersion="18" + android:targetSdkVersion="18" /> + + <application + android:allowBackup="true" + android:enabled="true" + android:label="@string/app_name" > + + <service + android:name=".AELogger" + android:enabled="true" + android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" + android:configChanges="locale" > + <intent-filter> + <action android:name="android.accessibilityservice.AccessibilityService"/> + + <category android:name="android.accessibilityservice.category.FEEDBACK_GENERIC"/> + <category android:name="android.accessibilityservice.category.FEEDBACK_VISUAL"/> + <category android:name="android.accessibilityservice.category.FEEDBACK_AUDIBLE"/> + </intent-filter> + + <meta-data + android:name="android.accessibilityservice" + android:resource="@xml/accessibilityservice" /> + </service> + </application> +</manifest> diff --git a/tests/AccessibilityEventsLogger/res/values/strings.xml b/tests/AccessibilityEventsLogger/res/values/strings.xml new file mode 100644 index 0000000..353f912 --- /dev/null +++ b/tests/AccessibilityEventsLogger/res/values/strings.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 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. +--> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- CHAR LIMIT=none --> + <string name="app_name"> + Accessibility Event Logger + </string> + + <!-- CHAR LIMIT=none --> + <string name="service_description"> + Debugging service + </string> +</resources> diff --git a/tests/AccessibilityEventsLogger/res/xml/accessibilityservice.xml b/tests/AccessibilityEventsLogger/res/xml/accessibilityservice.xml new file mode 100644 index 0000000..69ecd61 --- /dev/null +++ b/tests/AccessibilityEventsLogger/res/xml/accessibilityservice.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 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. +--> + +<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" + android:accessibilityEventTypes="typeAllMask" + android:accessibilityFeedbackType="feedbackGeneric|feedbackVisual|feedbackAudible" + android:canRetrieveWindowContent="true" + android:accessibilityFlags="flagDefault" + android:description="@string/service_description" + android:notificationTimeout="0" /> diff --git a/tests/AccessibilityEventsLogger/src/com/android/tests/accessibilityeventslogger/AELogger.java b/tests/AccessibilityEventsLogger/src/com/android/tests/accessibilityeventslogger/AELogger.java new file mode 100644 index 0000000..27d8eb9 --- /dev/null +++ b/tests/AccessibilityEventsLogger/src/com/android/tests/accessibilityeventslogger/AELogger.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015 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.tests.accessibilityeventslogger; + +import android.accessibilityservice.AccessibilityService; +import android.accessibilityservice.AccessibilityServiceInfo; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; +import android.widget.Toast; + +import java.util.Locale; + +public class AELogger extends AccessibilityService { + private static final String TAG = AELogger.class.getCanonicalName(); + + private static final int TOAST_EVENT_TYPES = + AccessibilityEvent.TYPE_VIEW_CLICKED | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED; + + @Override + public void onServiceConnected() { + super.onServiceConnected(); + Log.v(TAG, "Service connected."); + } + + + @Override + public void onInterrupt() { + // Do nothing + } + + @Override + public void onAccessibilityEvent(AccessibilityEvent event) { + final String eventClass = event.getClassName().toString(); + final String eventText = String.valueOf(event.getText()).toLowerCase(Locale.getDefault()); + final String eventType = AccessibilityEvent.eventTypeToString(event.getEventType()); + + Log.d(TAG, String.format( + "typ=%s cls=%s pkg=%s txt=%s dsc=%s", + eventType, + eventClass, + event.getPackageName(), + eventText, + event.getContentDescription() + )); + + // Show selected event types + if (0 != (TOAST_EVENT_TYPES & event.getEventType())) { + final Toast toast = Toast.makeText(this, + eventType + ": " + eventClass, Toast.LENGTH_SHORT); + toast.show(); + } + } +} diff --git a/tests/ActivityTests/AndroidManifest.xml b/tests/ActivityTests/AndroidManifest.xml index 33d40ad..7b9c9f1 100644 --- a/tests/ActivityTests/AndroidManifest.xml +++ b/tests/ActivityTests/AndroidManifest.xml @@ -24,6 +24,8 @@ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <uses-permission android:name="android.permission.MANAGE_USERS" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> + <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> + <uses-sdk android:targetSdkVersion="22" /> <application android:label="ActivityTest"> <activity android:name="ActivityTestMain"> <intent-filter> @@ -75,5 +77,7 @@ <provider android:name="SingleUserProvider" android:authorities="com.google.android.test.activity.single_user" android:singleUser="true" android:exported="true" /> + <receiver android:name="TrackTimeReceiver" /> + <receiver android:name="AlarmSpamReceiver" /> </application> </manifest> diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java index 4281c68..5fbfe8a 100644 --- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java +++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java @@ -22,7 +22,9 @@ import java.util.List; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; +import android.app.AlarmManager; import android.app.AlertDialog; +import android.app.PendingIntent; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -30,14 +32,18 @@ import android.content.ContentProviderClient; import android.content.Intent; import android.content.ServiceConnection; import android.graphics.BitmapFactory; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; +import android.os.PowerManager; import android.os.RemoteException; +import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.graphics.Bitmap; +import android.provider.Settings; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -57,6 +63,8 @@ public class ActivityTestMain extends Activity { static final String KEY_CONFIGURATION = "configuration"; ActivityManager mAm; + PowerManager mPower; + AlarmManager mAlarm; Configuration mOverrideConfig; int mSecondUser; @@ -65,6 +73,7 @@ public class ActivityTestMain extends Activity { ServiceConnection mIsolatedConnection; static final int MSG_SPAM = 1; + static final int MSG_SPAM_ALARM = 2; final Handler mHandler = new Handler() { @Override @@ -81,6 +90,15 @@ public class ActivityTestMain extends Activity { startActivity(intent, options); scheduleSpam(!fg); } break; + case MSG_SPAM_ALARM: { + long when = SystemClock.elapsedRealtime(); + Intent intent = new Intent(ActivityTestMain.this, AlarmSpamReceiver.class); + intent.setAction("com.example.SPAM_ALARM=" + when); + PendingIntent pi = PendingIntent.getBroadcast(ActivityTestMain.this, + 0, intent, 0); + mAlarm.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME, when+(30*1000), pi); + scheduleSpamAlarm(30*1000); + } break; } super.handleMessage(msg); } @@ -144,7 +162,9 @@ public class ActivityTestMain extends Activity { Log.i(TAG, "Referrer: " + getReferrer()); - mAm = (ActivityManager)getSystemService(ACTIVITY_SERVICE); + mAm = getSystemService(ActivityManager.class); + mPower = getSystemService(PowerManager.class); + mAlarm = getSystemService(AlarmManager.class); if (savedInstanceState != null) { mOverrideConfig = savedInstanceState.getParcelable(KEY_CONFIGURATION); if (mOverrideConfig != null) { @@ -412,6 +432,50 @@ public class ActivityTestMain extends Activity { return true; } }); + menu.add("Track time").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override public boolean onMenuItemClick(MenuItem item) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, "We are sharing this with you!"); + ActivityOptions options = ActivityOptions.makeBasic(); + Intent receiveIntent = new Intent(ActivityTestMain.this, TrackTimeReceiver.class); + receiveIntent.putExtra("something", "yeah, this is us!"); + options.requestUsageTimeReport(PendingIntent.getBroadcast(ActivityTestMain.this, + 0, receiveIntent, PendingIntent.FLAG_CANCEL_CURRENT)); + startActivity(Intent.createChooser(intent, "Who do you love?"), options.toBundle()); + return true; + } + }); + menu.add("Transaction fail").setOnMenuItemClickListener( + new MenuItem.OnMenuItemClickListener() { + @Override public boolean onMenuItemClick(MenuItem item) { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.putExtra("gulp", new int[1024 * 1024]); + startActivity(intent); + return true; + } + }); + menu.add("Spam idle alarm").setOnMenuItemClickListener( + new MenuItem.OnMenuItemClickListener() { + @Override public boolean onMenuItemClick(MenuItem item) { + scheduleSpamAlarm(0); + return true; + } + }); + menu.add("Ignore battery optimizations").setOnMenuItemClickListener( + new MenuItem.OnMenuItemClickListener() { + @Override public boolean onMenuItemClick(MenuItem item) { + Intent intent; + if (!mPower.isIgnoringBatteryOptimizations(getPackageName())) { + intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); + intent.setData(Uri.fromParts("package", getPackageName(), null)); + } else { + intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS); + } + startActivity(intent); + return true; + } + }); return true; } @@ -443,6 +507,7 @@ public class ActivityTestMain extends Activity { @Override protected void onStop() { super.onStop(); + mHandler.removeMessages(MSG_SPAM_ALARM); for (ServiceConnection conn : mConnections) { unbindService(conn); } @@ -512,6 +577,12 @@ public class ActivityTestMain extends Activity { mHandler.sendMessageDelayed(msg, 500); } + void scheduleSpamAlarm(long delay) { + mHandler.removeMessages(MSG_SPAM_ALARM); + Message msg = mHandler.obtainMessage(MSG_SPAM_ALARM); + mHandler.sendMessageDelayed(msg, delay); + } + private View scrollWrap(View view) { ScrollView scroller = new ScrollView(this); scroller.addView(view, new ScrollView.LayoutParams(ScrollView.LayoutParams.MATCH_PARENT, diff --git a/tests/WebViewTests/res/layout/webview_layout.xml b/tests/ActivityTests/src/com/google/android/test/activity/AlarmSpamReceiver.java index d266d21..0cb1ffb 100644 --- a/tests/WebViewTests/res/layout/webview_layout.xml +++ b/tests/ActivityTests/src/com/google/android/test/activity/AlarmSpamReceiver.java @@ -1,6 +1,5 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - * Copyright (C) 2009 The Android Open Source Project +/* + * Copyright (C) 2015 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. @@ -13,13 +12,20 @@ * 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:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent"> + */ - <WebView android:id="@+id/web_page" - android:layout_width="match_parent" - android:layout_height="match_parent" /> -</LinearLayout> +package com.google.android.test.activity; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.UserHandle; +import android.util.Log; + +public class AlarmSpamReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + Log.i("AlarmSpamReceiver", "Received spam = " + intent); + } +} diff --git a/tests/ActivityTests/src/com/google/android/test/activity/TrackTimeReceiver.java b/tests/ActivityTests/src/com/google/android/test/activity/TrackTimeReceiver.java new file mode 100644 index 0000000..0cc0090 --- /dev/null +++ b/tests/ActivityTests/src/com/google/android/test/activity/TrackTimeReceiver.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2015 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.google.android.test.activity; + +import android.app.ActivityOptions; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +public class TrackTimeReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + Bundle data = intent.getExtras(); + data.getLong(ActivityOptions.EXTRA_USAGE_TIME_REPORT); + Log.i("ActivityTest", "Received time: " + data); + } +} diff --git a/tests/Assist/Android.mk b/tests/Assist/Android.mk new file mode 100644 index 0000000..f31c4dd --- /dev/null +++ b/tests/Assist/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := Assist + +include $(BUILD_PACKAGE) diff --git a/tests/Assist/AndroidManifest.xml b/tests/Assist/AndroidManifest.xml new file mode 100644 index 0000000..9d4c4ad --- /dev/null +++ b/tests/Assist/AndroidManifest.xml @@ -0,0 +1,49 @@ +<!-- + ~ Copyright (C) 2015 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 + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.test.assist"> + + <application> + <service android:name="AssistInteractionService" + android:label="Test Assist Interaction Service" + android:permission="android.permission.BIND_VOICE_INTERACTION" + android:process=":interactor"> + <meta-data android:name="android.voice_interaction" + android:resource="@xml/interaction_service" /> + <intent-filter> + <action android:name="android.service.voice.VoiceInteractionService" /> + </intent-filter> + <meta-data + android:name="com.android.systemui.action_assist_icon" + android:resource="@drawable/assistant" /> + <meta-data + android:name="com.android.keyguard.layout" + android:resource="@layout/keyguard_preview" /> + </service> + <service android:name="AssistInteractionSessionService" + android:permission="android.permission.BIND_VOICE_INTERACTION" + android:process=":session"> + </service> + <activity android:name=".AboveKeyguardActivity" + android:label="Test Above Keyguard Activity" + android:theme="@android:style/Theme.NoTitleBar" + android:excludeFromRecents="true" + android:launchMode="singleTask" + android:exported="false" > + </activity> + </application> +</manifest> diff --git a/tests/Assist/res/drawable/assistant.xml b/tests/Assist/res/drawable/assistant.xml new file mode 100644 index 0000000..2a89dda --- /dev/null +++ b/tests/Assist/res/drawable/assistant.xml @@ -0,0 +1,27 @@ +<!-- +Copyright (C) 2014 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="48.0dp" + android:height="48.0dp" + android:viewportWidth="48.0" + android:viewportHeight="48.0"> + <path + android:pathData="M0 0h48v48H0z" + android:fillColor="#00000000"/> + <path + android:fillColor="#FF000000" + android:pathData="M38.0,4.0L10.0,4.0C7.79,4.0 6.0,5.79 6.0,8.0l0.0,28.0c0.0,2.21 1.79,4.0 4.0,4.0l8.0,0.0l6.0,6.0 6.0,-6.0l8.0,0.0c2.21,0.0 4.0,-1.79 4.0,-4.0L36.0,8.0c0.0,-2.21 -1.79,-4.0 -4.0,-4.0zM27.75,25.75L24.0,34.0l-3.75,-8.25L12.0,22.0l8.25,-3.75L24.0,10.0l3.75,8.25L36.0,22.0l-8.25,3.75z"/> +</vector> diff --git a/tests/Assist/res/drawable/navbar_scrim.xml b/tests/Assist/res/drawable/navbar_scrim.xml new file mode 100644 index 0000000..52ed76d --- /dev/null +++ b/tests/Assist/res/drawable/navbar_scrim.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + ~ Copyright (C) 2014 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 + --> + +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <gradient + android:type="linear" + android:angle="90" + android:startColor="#33000000" + android:endColor="#00000000" /> +</shape>
\ No newline at end of file diff --git a/tests/Assist/res/drawable/round_rect.xml b/tests/Assist/res/drawable/round_rect.xml new file mode 100644 index 0000000..55937a0 --- /dev/null +++ b/tests/Assist/res/drawable/round_rect.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2014 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 + --> + +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="#e0e0e0"> + <item> + <shape> + <solid android:color="#ffffff" /> + <corners android:radius="2dp" /> + </shape> + </item> +</ripple>
\ No newline at end of file diff --git a/tests/Assist/res/layout/assist.xml b/tests/Assist/res/layout/assist.xml new file mode 100644 index 0000000..8c4be2d --- /dev/null +++ b/tests/Assist/res/layout/assist.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2015 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 + --> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <com.android.test.assist.ScrimView + android:id="@+id/scrim" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="#60000000"/> + + <View + android:id="@+id/background" + android:layout_width="match_parent" + android:layout_height="350dp" + android:layout_gravity="bottom" + android:background="#e0e0e0"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="350dp" + android:orientation="vertical" + android:layout_gravity="bottom"> + + <FrameLayout + android:id="@+id/card1" + android:layout_width="match_parent" + android:layout_height="150dp" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:layout_marginTop="16dp" + android:elevation="3dp" + android:background="@drawable/round_rect"> + </FrameLayout> + + <View + android:id="@+id/card2" + android:layout_width="match_parent" + android:layout_height="200dp" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:layout_marginTop="16dp" + android:elevation="3dp" + android:background="@drawable/round_rect"/> + + </LinearLayout> + + <com.android.test.assist.ScrimView + android:id="@+id/navbar_scrim" + android:layout_width="match_parent" + android:layout_height="150dp" + android:layout_gravity="bottom" + android:background="@drawable/navbar_scrim"/> +</FrameLayout>
\ No newline at end of file diff --git a/tests/Assist/res/layout/keyguard_preview.xml b/tests/Assist/res/layout/keyguard_preview.xml new file mode 100644 index 0000000..d56c52e --- /dev/null +++ b/tests/Assist/res/layout/keyguard_preview.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2015 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 + --> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:background="#d3d3d3"> + + <View + android:id="@+id/background" + android:layout_width="match_parent" + android:layout_height="350dp" + android:layout_gravity="bottom" + android:elevation="30dp" + android:background="#e0e0e0"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="350dp" + android:orientation="vertical" + android:elevation="30dp" + android:layout_gravity="bottom"> + + <FrameLayout + android:id="@+id/card1" + android:layout_width="match_parent" + android:layout_height="150dp" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:layout_marginTop="16dp" + android:elevation="3dp" + android:background="@drawable/round_rect"> + </FrameLayout> + + <View + android:id="@+id/card2" + android:layout_width="match_parent" + android:layout_height="200dp" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:layout_marginTop="16dp" + android:elevation="3dp" + android:background="@drawable/round_rect"/> + + </LinearLayout> +</FrameLayout>
\ No newline at end of file diff --git a/tests/Assist/res/values/strings.xml b/tests/Assist/res/values/strings.xml new file mode 100644 index 0000000..5331457 --- /dev/null +++ b/tests/Assist/res/values/strings.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> + +<resources> + + <string name="start">Start</string> + <string name="confirm">Confirm</string> + <string name="abort">Abort</string> + <string name="complete">Complete</string> + <string name="abortVoice">Abort Voice</string> + <string name="completeVoice">Complete Voice</string> + <string name="pickVoice">Pick Voice</string> + <string name="cancelVoice">Cancel</string> + +</resources> diff --git a/tests/Assist/res/xml/interaction_service.xml b/tests/Assist/res/xml/interaction_service.xml new file mode 100644 index 0000000..a90c824 --- /dev/null +++ b/tests/Assist/res/xml/interaction_service.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2015 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 + --> + +<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android" + android:sessionService="com.android.test.assist.AssistInteractionSessionService" + android:recognitionService="com.android.test.assist.AssistRecognitionService" + android:supportsAssist="true" + android:supportsLaunchVoiceAssistFromKeyguard="true"/> diff --git a/tests/Assist/res/xml/recognition_service.xml b/tests/Assist/res/xml/recognition_service.xml new file mode 100644 index 0000000..5b52c3c --- /dev/null +++ b/tests/Assist/res/xml/recognition_service.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2015 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 + --> + +<recognition-service/> diff --git a/tests/Assist/src/com/android/test/assist/AboveKeyguardActivity.java b/tests/Assist/src/com/android/test/assist/AboveKeyguardActivity.java new file mode 100644 index 0000000..3e37345 --- /dev/null +++ b/tests/Assist/src/com/android/test/assist/AboveKeyguardActivity.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015 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.test.assist; + +import android.annotation.Nullable; +import android.app.Activity; +import android.os.Bundle; +import android.view.WindowManager; + +import com.android.test.assist.R; + +/** + * An activity which can be shown above the keyguard. + */ +public class AboveKeyguardActivity extends Activity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); + setContentView(R.layout.keyguard_preview); + } +} diff --git a/tests/Assist/src/com/android/test/assist/AssistInteractionService.java b/tests/Assist/src/com/android/test/assist/AssistInteractionService.java new file mode 100644 index 0000000..bf40747 --- /dev/null +++ b/tests/Assist/src/com/android/test/assist/AssistInteractionService.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2015 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.test.assist; + +import android.content.Intent; +import android.service.voice.VoiceInteractionService; + +public class AssistInteractionService extends VoiceInteractionService { + @Override + public void onLaunchVoiceAssistFromKeyguard() { + super.onLaunchVoiceAssistFromKeyguard(); + Intent intent = new Intent(this, AboveKeyguardActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } +} diff --git a/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java b/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java new file mode 100644 index 0000000..851bda9 --- /dev/null +++ b/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2015 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.test.assist; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.app.VoiceInteractor; +import android.content.Context; +import android.graphics.Color; +import android.os.Bundle; +import android.os.Handler; +import android.service.voice.VoiceInteractionSession; +import android.util.Log; +import android.view.View; +import android.view.ViewAnimationUtils; +import android.view.ViewTreeObserver; +import android.view.animation.AnimationUtils; +import android.view.animation.Interpolator; + +/** + * Sample session to show test assist transition. + */ +public class AssistInteractionSession extends VoiceInteractionSession { + + private View mScrim; + private View mBackground; + private View mNavbarScrim; + private View mCard1; + private View mCard2; + + private float mDensity; + + public AssistInteractionSession(Context context) { + super(context); + } + + public AssistInteractionSession(Context context, Handler handler) { + super(context, handler); + } + + @Override + public void onRequestConfirmation(ConfirmationRequest request) { + } + + @Override + public void onRequestPickOption(PickOptionRequest request) { + } + + @Override + public void onRequestCommand(CommandRequest request) { + } + + @Override + public void onCancelRequest(Request request) { + } + + @Override + public void onCreate() { + super.onCreate(); + // Simulate slowness of Assist app + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Override + public View onCreateContentView() { + View v = getLayoutInflater().inflate(R.layout.assist, null); + mScrim = v.findViewById(R.id.scrim); + mBackground = v.findViewById(R.id.background); + mDensity = mScrim.getResources().getDisplayMetrics().density; + mCard1 = v.findViewById(R.id.card1); + mCard2 = v.findViewById(R.id.card2); + mNavbarScrim = v.findViewById(R.id.navbar_scrim); + return v; + } + + @Override + public void onShow(Bundle args, int showFlags) { + super.onShow(args, showFlags); + if ((showFlags & SHOW_SOURCE_ASSIST_GESTURE) != 0) { + mBackground.getViewTreeObserver().addOnPreDrawListener( + new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + mBackground.getViewTreeObserver().removeOnPreDrawListener(this); + playAssistAnimation(); + return true; + } + }); + } + } + + @Override + public void onLockscreenShown() { + super.onLockscreenShown(); + Log.i("Assistant", "Lockscreen was shown"); + } + + private void playAssistAnimation() { + Interpolator linearOutSlowIn = AnimationUtils.loadInterpolator(mBackground.getContext(), + android.R.interpolator.linear_out_slow_in); + Interpolator fastOutSlowIn = AnimationUtils.loadInterpolator(mBackground.getContext(), + android.R.interpolator.fast_out_slow_in); + mScrim.setAlpha(0f); + mScrim.animate() + .alpha(1f) + .setStartDelay(100) + .setDuration(500); + mBackground.setTranslationY(50 * mDensity); + mBackground.animate() + .translationY(0) + .setDuration(300) + .setInterpolator(linearOutSlowIn); + int centerX = mBackground.getWidth()/2; + int centerY = (int) (mBackground.getHeight()/5*3.8f); + int radius = (int) Math.sqrt(centerX*centerX + centerY*centerY) + 1; + Animator animator = ViewAnimationUtils.createCircularReveal(mBackground, centerX, centerY, + 0, radius); + animator.setDuration(300); + animator.setInterpolator(fastOutSlowIn); + animator.start(); + + ValueAnimator colorAnim = ValueAnimator.ofArgb(Color.WHITE, 0xffe0e0e0); + colorAnim.setDuration(300); + colorAnim.setInterpolator(fastOutSlowIn); + colorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + mBackground.setBackgroundColor((Integer) animation.getAnimatedValue()); + } + }); + colorAnim.start(); + + + mCard1.setY(mBackground.getHeight()); + mCard2.setTranslationY(mCard1.getTranslationY()); + mCard1.animate() + .translationY(0) + .setDuration(500) + .setInterpolator(linearOutSlowIn) + .setStartDelay(100); + mCard2.animate() + .translationY(0) + .setInterpolator(linearOutSlowIn) + .setStartDelay(150) + .setDuration(500); + + mNavbarScrim.setAlpha(0f); + mNavbarScrim.animate() + .alpha(1f) + .setDuration(500) + .setStartDelay(100); + } + + @Override + public void onHide() { + super.onHide(); + } +} diff --git a/tests/Assist/src/com/android/test/assist/AssistInteractionSessionService.java b/tests/Assist/src/com/android/test/assist/AssistInteractionSessionService.java new file mode 100644 index 0000000..3c483d6 --- /dev/null +++ b/tests/Assist/src/com/android/test/assist/AssistInteractionSessionService.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015 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.test.assist; + +import android.os.Bundle; +import android.service.voice.VoiceInteractionSession; +import android.service.voice.VoiceInteractionSessionService; + +public class AssistInteractionSessionService extends VoiceInteractionSessionService { + @Override + public VoiceInteractionSession onNewSession(Bundle args) { + return new AssistInteractionSession(this); + } +} diff --git a/tests/Assist/src/com/android/test/assist/AssistRecognitionService.java b/tests/Assist/src/com/android/test/assist/AssistRecognitionService.java new file mode 100644 index 0000000..6e5faa1 --- /dev/null +++ b/tests/Assist/src/com/android/test/assist/AssistRecognitionService.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015 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.test.assist; + +import android.content.Intent; +import android.speech.RecognitionService; + +/** + * Stub recognition service needed to be a complete voice interactor. + */ +public class AssistRecognitionService extends RecognitionService { + + @Override + protected void onStartListening(Intent recognizerIntent, Callback listener) { + } + + @Override + protected void onCancel(Callback listener) { + } + + @Override + protected void onStopListening(Callback listener) { + } +} diff --git a/tests/Assist/src/com/android/test/assist/ScrimView.java b/tests/Assist/src/com/android/test/assist/ScrimView.java new file mode 100644 index 0000000..1b7387b --- /dev/null +++ b/tests/Assist/src/com/android/test/assist/ScrimView.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015 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.test.assist; + +import android.annotation.Nullable; +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; + +public class ScrimView extends View { + + public ScrimView(Context context) { + super(context); + } + + public ScrimView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public ScrimView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + public boolean hasOverlappingRendering() { + return false; + } +} diff --git a/tests/CameraPrewarmTest/Android.mk b/tests/CameraPrewarmTest/Android.mk new file mode 100644 index 0000000..b6316f0 --- /dev/null +++ b/tests/CameraPrewarmTest/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := CameraPrewarmTest + +LOCAL_MODULE_TAGS := tests +LOCAL_CERTIFICATE := platform + +include $(BUILD_PACKAGE) diff --git a/tests/CameraPrewarmTest/AndroidManifest.xml b/tests/CameraPrewarmTest/AndroidManifest.xml new file mode 100644 index 0000000..11b2686 --- /dev/null +++ b/tests/CameraPrewarmTest/AndroidManifest.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2015 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 + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.android.test.cameraprewarm"> + <application android:label="@string/activity_title"> + + <activity android:name=".CameraActivity" + android:theme="@android:style/Theme.NoTitleBar"> + <intent-filter> + <action android:name="android.media.action.STILL_IMAGE_CAMERA" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + <meta-data + android:name="android.media.still_image_camera_preview_service" + android:value="com.google.android.test.cameraprewarm.PrewarmService"> + </meta-data> + </activity> + + <activity android:name=".SecureCameraActivity" + android:theme="@android:style/Theme.NoTitleBar"> + <intent-filter> + <action android:name="android.media.action.STILL_IMAGE_CAMERA_SECURE" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + <meta-data + android:name="android.media.still_image_camera_preview_service" + android:value="com.google.android.test.cameraprewarm.PrewarmService"> + </meta-data> + </activity> + + <service android:name=".PrewarmService" + android:exported="true"> + </service> + + </application> +</manifest> diff --git a/tests/CameraPrewarmTest/res/layout/camera_activity.xml b/tests/CameraPrewarmTest/res/layout/camera_activity.xml new file mode 100644 index 0000000..64437bc --- /dev/null +++ b/tests/CameraPrewarmTest/res/layout/camera_activity.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2015 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:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center"> +</LinearLayout> + diff --git a/tests/CameraPrewarmTest/res/values/strings.xml b/tests/CameraPrewarmTest/res/values/strings.xml new file mode 100644 index 0000000..fe39ac1 --- /dev/null +++ b/tests/CameraPrewarmTest/res/values/strings.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2015 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 + --> + +<resources> + <string name="activity_title">Camera Prewarm test</string> + <string name="search_label">Orilla Search Engine</string> +</resources> diff --git a/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/CameraActivity.java b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/CameraActivity.java new file mode 100644 index 0000000..0b43666 --- /dev/null +++ b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/CameraActivity.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 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.google.android.test.cameraprewarm; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; + +import com.google.android.test.cameraprewarm.R; + +public class CameraActivity extends Activity { + + public final static String TAG = "PrewarmTest"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.camera_activity); + Log.i(TAG, "Activity created"); + } +} diff --git a/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/PrewarmService.java b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/PrewarmService.java new file mode 100644 index 0000000..d080b1a --- /dev/null +++ b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/PrewarmService.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2015 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.google.android.test.cameraprewarm; + +import android.service.media.CameraPrewarmService; +import android.util.Log; + +public class PrewarmService extends CameraPrewarmService { + + @Override + public void onPrewarm() { + Log.i("PrewarmService", "Warming up"); + } + + @Override + public void onCooldown(boolean cameraIntentFired) { + Log.i("PrewarmService", "Cooling down fired=" + cameraIntentFired); + } +} diff --git a/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/SecureCameraActivity.java b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/SecureCameraActivity.java new file mode 100644 index 0000000..530fe00 --- /dev/null +++ b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/SecureCameraActivity.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 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.google.android.test.cameraprewarm; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.WindowManager; + +import com.google.android.test.cameraprewarm.R; + +public class SecureCameraActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.camera_activity); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); + Log.i(CameraActivity.TAG, "Activity created"); + } +} diff --git a/tests/Compatibility/Android.mk b/tests/Compatibility/Android.mk index 0ec4d9d..c2f89dd 100644 --- a/tests/Compatibility/Android.mk +++ b/tests/Compatibility/Android.mk @@ -25,7 +25,7 @@ LOCAL_SRC_FILES := \ LOCAL_PACKAGE_NAME := AppCompatibilityTest - +LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE) include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/Compatibility/AndroidManifest.xml b/tests/Compatibility/AndroidManifest.xml index 2884532..7017431 100644 --- a/tests/Compatibility/AndroidManifest.xml +++ b/tests/Compatibility/AndroidManifest.xml @@ -16,10 +16,12 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.compatibilitytest" > + <uses-sdk android:minSdkVersion="21" + android:targetSdkVersion="21" /> <application > <uses-library android:name="android.test.runner" /> </application> - + <uses-permission android:name="android.permission.REAL_GET_TASKS" /> <instrumentation android:name=".AppCompatibilityRunner" android:targetPackage="com.android.compatibilitytest" diff --git a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java index dd823ae..f81b001 100644 --- a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java +++ b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java @@ -17,13 +17,16 @@ package com.android.compatibilitytest; import android.app.ActivityManager; +import android.app.UiAutomation; +import android.app.UiModeManager; import android.app.ActivityManager.ProcessErrorStateInfo; -import android.app.ActivityManager.RunningAppProcessInfo; +import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.Configuration; import android.os.Bundle; import android.test.InstrumentationTestCase; import android.util.Log; @@ -39,7 +42,7 @@ import java.util.List; */ public class AppCompatibility extends InstrumentationTestCase { - private static final String TAG = "AppCompability"; + private static final String TAG = AppCompatibility.class.getSimpleName(); private static final String PACKAGE_TO_LAUNCH = "package_to_launch"; private static final String APP_LAUNCH_TIMEOUT_MSECS = "app_launch_timeout_ms"; private static final String WORKSPACE_LAUNCH_TIMEOUT_MSECS = "workspace_launch_timeout_ms"; @@ -80,10 +83,12 @@ public class AppCompatibility extends InstrumentationTestCase { if (workspaceLaunchTimeoutMsecs != null) { mWorkspaceLaunchTimeout = Integer.parseInt(workspaceLaunchTimeoutMsecs); } + getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_FREEZE_0); } @Override protected void tearDown() throws Exception { + getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_UNFREEZE); super.tearDown(); } @@ -97,12 +102,21 @@ public class AppCompatibility extends InstrumentationTestCase { String packageName = mArgs.getString(PACKAGE_TO_LAUNCH); if (packageName != null) { Log.d(TAG, "Launching app " + packageName); - ProcessErrorStateInfo err = launchActivity(packageName); + Intent intent = getLaunchIntentForPackage(packageName); + if (intent == null) { + Log.w(TAG, String.format("Skipping %s; no launch intent", packageName)); + return; + } + ProcessErrorStateInfo err = launchActivity(packageName, intent); // Make sure there are no errors when launching the application, // otherwise raise an // exception with the first error encountered. assertNull(getStackTrace(err), err); - assertTrue("App crashed after launch.", processStillUp(packageName)); + try { + assertTrue("App crashed after launch.", processStillUp(packageName)); + } finally { + returnHome(); + } } else { Log.d(TAG, "Missing argument, use " + PACKAGE_TO_LAUNCH + " to specify the package to launch"); @@ -138,6 +152,32 @@ public class AppCompatibility extends InstrumentationTestCase { } } + private void returnHome() { + Intent homeIntent = new Intent(Intent.ACTION_MAIN); + homeIntent.addCategory(Intent.CATEGORY_HOME); + homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + // Send the "home" intent and wait 2 seconds for us to get there + mContext.startActivity(homeIntent); + try { + Thread.sleep(mWorkspaceLaunchTimeout); + } catch (InterruptedException e) { + // ignore + } + } + + private Intent getLaunchIntentForPackage(String packageName) { + UiModeManager umm = (UiModeManager) + getInstrumentation().getContext().getSystemService(Context.UI_MODE_SERVICE); + boolean isLeanback = umm.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION; + Intent intent = null; + if (isLeanback) { + intent = mPackageManager.getLeanbackLaunchIntentForPackage(packageName); + } else { + intent = mPackageManager.getLaunchIntentForPackage(packageName); + } + return intent; + } + /** * Launches and activity and queries for errors. * @@ -146,21 +186,9 @@ public class AppCompatibility extends InstrumentationTestCase { * @return {@link Collection} of {@link ProcessErrorStateInfo} detected * during the app launch. */ - private ProcessErrorStateInfo launchActivity(String packageName) { - // the recommended way to see if this is a tv or not. - boolean isleanback = !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN) - && !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY); - Intent homeIntent = new Intent(Intent.ACTION_MAIN); - homeIntent.addCategory(Intent.CATEGORY_HOME); - homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - Intent intent; - if (isleanback) { - Log.d(TAG, "Leanback and relax! " + packageName); - intent = mPackageManager.getLeanbackLaunchIntentForPackage(packageName); - } else { - intent = mPackageManager.getLaunchIntentForPackage(packageName); - } - assertNotNull("Skipping " + packageName + "; missing launch intent", intent); + private ProcessErrorStateInfo launchActivity(String packageName, Intent intent) { + Log.d(TAG, String.format("launching package \"%s\" with intent: %s", + packageName, intent.toString())); String processName = getProcessName(packageName); @@ -173,16 +201,7 @@ public class AppCompatibility extends InstrumentationTestCase { // ignore } - // Send the "home" intent and wait 2 seconds for us to get there - mContext.startActivity(homeIntent); - try { - Thread.sleep(mWorkspaceLaunchTimeout); - } catch (InterruptedException e) { - // ignore - } - - // See if there are any errors. We wait until down here to give ANRs as - // much time as + // See if there are any errors. We wait until down here to give ANRs as much time as // possible to occur. final Collection<ProcessErrorStateInfo> postErr = mActivityManager.getProcessesInErrorState(); @@ -205,22 +224,13 @@ public class AppCompatibility extends InstrumentationTestCase { * @return True if package is running, false otherwise. */ private boolean processStillUp(String packageName) { - String processName = getProcessName(packageName); - List<RunningAppProcessInfo> runningApps = mActivityManager.getRunningAppProcesses(); - for (RunningAppProcessInfo app : runningApps) { - if (app.processName.equalsIgnoreCase(processName)) { - Log.d(TAG, "Found process " + app.processName); + @SuppressWarnings("deprecation") + List<RunningTaskInfo> infos = mActivityManager.getRunningTasks(100); + for (RunningTaskInfo info : infos) { + if (info.baseActivity.getPackageName().equals(packageName)) { return true; } - for (String relatedPackage : app.pkgList) { - if (relatedPackage.equalsIgnoreCase(processName)) { - Log.d(TAG, "Found process " + app.processName); - return true; - } - } } - Log.d(TAG, "Failed to find process " + processName + " with package name " - + packageName); return false; } } diff --git a/tests/CoreTests/android/Android.mk b/tests/CoreTests/android/Android.mk index bc0e4e4..5f3d0d9 100644 --- a/tests/CoreTests/android/Android.mk +++ b/tests/CoreTests/android/Android.mk @@ -6,7 +6,7 @@ LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES := \ $(call all-subdir-java-files) -LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle conscrypt +LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle conscrypt org.apache.http.legacy LOCAL_PACKAGE_NAME := CoreTests diff --git a/tests/CoreTests/android/AndroidManifest.xml b/tests/CoreTests/android/AndroidManifest.xml index 8331f0c..bf46d15 100644 --- a/tests/CoreTests/android/AndroidManifest.xml +++ b/tests/CoreTests/android/AndroidManifest.xml @@ -35,6 +35,7 @@ <application> <uses-library android:name="android.test.runner" /> + <uses-library android:name="org.apache.http.legacy" android:required="false" /> </application> <instrumentation diff --git a/tests/FixVibrateSetting/src/com/android/fixvibratesetting/FixVibrateSetting.java b/tests/FixVibrateSetting/src/com/android/fixvibratesetting/FixVibrateSetting.java index 947ea78..2e51570 100644 --- a/tests/FixVibrateSetting/src/com/android/fixvibratesetting/FixVibrateSetting.java +++ b/tests/FixVibrateSetting/src/com/android/fixvibratesetting/FixVibrateSetting.java @@ -109,14 +109,20 @@ public class FixVibrateSetting extends Activity implements View.OnClickListener } private void test() { - Notification n = new Notification(R.drawable.stat_sys_warning, "Test notification", - System.currentTimeMillis()); Intent intent = new Intent(this, FixVibrateSetting.class); PendingIntent pending = PendingIntent.getActivity(this, 0, intent, 0); - n.setLatestEventInfo(this, "Test notification", "Test notification", pending); - n.vibrate = new long[] { 0, 700, 500, 1000 }; - n.flags |= Notification.FLAG_AUTO_CANCEL; + Notification n = new Notification.Builder(this) + .setSmallIcon(R.drawable.stat_sys_warning) + .setTicker("Test notification") + .setWhen(System.currentTimeMillis()) + .setContentTitle("Test notification") + .setContentText("Test notification") + .setContentIntent(pending) + .setVibrate(new long[] { 0, 700, 500, 1000 }) + .setAutoCancel(true) + .build(); + mNotificationManager.notify(1, n); } } diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/SchedulerService.java b/tests/FrameworkPerf/src/com/android/frameworkperf/SchedulerService.java index 7691e64..fc3f390 100644 --- a/tests/FrameworkPerf/src/com/android/frameworkperf/SchedulerService.java +++ b/tests/FrameworkPerf/src/com/android/frameworkperf/SchedulerService.java @@ -26,15 +26,18 @@ public class SchedulerService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { - Notification status = new Notification(R.drawable.stat_happy, null, - System.currentTimeMillis()); - status.flags |= Notification.FLAG_ONGOING_EVENT; - status.setLatestEventInfo(this, "Scheduler Test running", - "Scheduler Test running", PendingIntent.getActivity(this, 0, - new Intent(this, FrameworkPerfActivity.class) - .setAction(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_LAUNCHER) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0)); + Notification status = new Notification.Builder(this) + .setSmallIcon(R.drawable.stat_happy) + .setWhen(System.currentTimeMillis()) + .setContentTitle("Scheduler Test running") + .setContentText("Scheduler Test running") + .setContentIntent(PendingIntent.getActivity(this, 0, + new Intent(this, FrameworkPerfActivity.class) + .setAction(Intent.ACTION_MAIN) + .addCategory(Intent.CATEGORY_LAUNCHER) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0)) + .setOngoing(true) + .build(); startForeground(1, status); return START_STICKY; } diff --git a/tests/HierarchyViewerTest/.gitignore b/tests/HierarchyViewerTest/.gitignore new file mode 100644 index 0000000..75eec98 --- /dev/null +++ b/tests/HierarchyViewerTest/.gitignore @@ -0,0 +1,6 @@ +.gradle +.idea +*.iml +gradle* +build +local.properties diff --git a/tests/HierarchyViewerTest/Android.mk b/tests/HierarchyViewerTest/Android.mk new file mode 100644 index 0000000..07b90f0 --- /dev/null +++ b/tests/HierarchyViewerTest/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := HierarchyViewerTest + +LOCAL_JAVA_LIBRARIES := android.test.runner + +include $(BUILD_PACKAGE) diff --git a/tests/HierarchyViewerTest/AndroidManifest.xml b/tests/HierarchyViewerTest/AndroidManifest.xml new file mode 100644 index 0000000..65f2fd3 --- /dev/null +++ b/tests/HierarchyViewerTest/AndroidManifest.xml @@ -0,0 +1,36 @@ +<!-- + ~ Copyright (C) 2015 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 + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.test.hierarchyviewer"> + + <application> + <uses-library android:name="android.test.runner" /> + + <activity + android:name=".MainActivity" + android:label="HvTest" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> + + <instrumentation + android:name="android.test.InstrumentationTestRunner" + android:targetPackage="com.android.test.hierarchyviewer" /> +</manifest> diff --git a/tests/HierarchyViewerTest/build.gradle b/tests/HierarchyViewerTest/build.gradle new file mode 100644 index 0000000..e8cdfa2 --- /dev/null +++ b/tests/HierarchyViewerTest/build.gradle @@ -0,0 +1,31 @@ +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.1.0+' + + } +} + +apply plugin: 'com.android.application' + +android { + compileSdkVersion 21 + buildToolsVersion "22.0.0" + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = ['src'] + res.srcDirs = ['res'] + } + } +} diff --git a/tests/HierarchyViewerTest/res/layout/activity_main.xml b/tests/HierarchyViewerTest/res/layout/activity_main.xml new file mode 100644 index 0000000..410a776 --- /dev/null +++ b/tests/HierarchyViewerTest/res/layout/activity_main.xml @@ -0,0 +1,12 @@ +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" + android:layout_height="match_parent"> + + <TextView + android:id="@+id/textView" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:scaleX="10" + android:text="@string/test" /> + +</RelativeLayout> diff --git a/tests/HierarchyViewerTest/res/menu/menu_main.xml b/tests/HierarchyViewerTest/res/menu/menu_main.xml new file mode 100644 index 0000000..9b78a1e --- /dev/null +++ b/tests/HierarchyViewerTest/res/menu/menu_main.xml @@ -0,0 +1,5 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> + <item android:id="@+id/action_settings" android:title="Settings" + android:orderInCategory="100" android:showAsAction="never" /> +</menu> diff --git a/tests/HierarchyViewerTest/res/values/strings.xml b/tests/HierarchyViewerTest/res/values/strings.xml new file mode 100644 index 0000000..800ee1c --- /dev/null +++ b/tests/HierarchyViewerTest/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="test">Hello World</string> +</resources>
\ No newline at end of file diff --git a/tests/HierarchyViewerTest/run_tests.sh b/tests/HierarchyViewerTest/run_tests.sh new file mode 100644 index 0000000..094bb4c --- /dev/null +++ b/tests/HierarchyViewerTest/run_tests.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +# Runs the tests in this apk +adb install $OUT/data/app/HierarchyViewerTest/HierarchyViewerTest.apk +adb shell am instrument -w com.android.test.hierarchyviewer/android.test.InstrumentationTestRunner diff --git a/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/Decoder.java b/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/Decoder.java new file mode 100644 index 0000000..c6f1470 --- /dev/null +++ b/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/Decoder.java @@ -0,0 +1,101 @@ +package com.android.test.hierarchyviewer; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; + +public class Decoder { + // Prefixes for simple primitives. These match the JNI definitions. + public static final byte SIG_BOOLEAN = 'Z'; + public static final byte SIG_BYTE = 'B'; + public static final byte SIG_SHORT = 'S'; + public static final byte SIG_INT = 'I'; + public static final byte SIG_LONG = 'J'; + public static final byte SIG_FLOAT = 'F'; + public static final byte SIG_DOUBLE = 'D'; + + // Prefixes for some commonly used objects + public static final byte SIG_STRING = 'R'; + + public static final byte SIG_MAP = 'M'; // a map with an short key + public static final short SIG_END_MAP = 0; + + private final ByteBuffer mBuf; + + public Decoder(byte[] buf) { + this(ByteBuffer.wrap(buf)); + } + + public Decoder(ByteBuffer buf) { + mBuf = buf; + } + + public boolean hasRemaining() { + return mBuf.hasRemaining(); + } + + public Object readObject() { + byte sig = mBuf.get(); + + switch (sig) { + case SIG_BOOLEAN: + return mBuf.get() == 0 ? Boolean.FALSE : Boolean.TRUE; + case SIG_BYTE: + return mBuf.get(); + case SIG_SHORT: + return mBuf.getShort(); + case SIG_INT: + return mBuf.getInt(); + case SIG_LONG: + return mBuf.getLong(); + case SIG_FLOAT: + return mBuf.getFloat(); + case SIG_DOUBLE: + return mBuf.getDouble(); + case SIG_STRING: + return readString(); + case SIG_MAP: + return readMap(); + default: + throw new DecoderException(sig, mBuf.position() - 1); + } + } + + private String readString() { + short len = mBuf.getShort(); + byte[] b = new byte[len]; + mBuf.get(b, 0, len); + return new String(b, Charset.forName("utf-8")); + } + + private Map<Short, Object> readMap() { + Map<Short, Object> m = new HashMap<Short, Object>(); + + while (true) { + Object o = readObject(); + if (!(o instanceof Short)) { + throw new DecoderException("Expected short key, got " + o.getClass()); + } + + Short key = (Short)o; + if (key == SIG_END_MAP) { + break; + } + + m.put(key, readObject()); + } + + return m; + } + + public static class DecoderException extends RuntimeException { + public DecoderException(byte seen, int pos) { + super(String.format("Unexpected byte %c seen at position %d", (char)seen, pos)); + } + + public DecoderException(String msg) { + super(msg); + } + } +} diff --git a/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/MainActivity.java b/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/MainActivity.java new file mode 100644 index 0000000..3a67273 --- /dev/null +++ b/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/MainActivity.java @@ -0,0 +1,44 @@ +package com.android.test.hierarchyviewer; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; + + +public class MainActivity extends Activity { + private static final String TAG = "Main"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + View textView = findViewById(R.id.textView); + Log.d(TAG, "x, y = " + textView.getX() + ", " + textView.getY()); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } +} diff --git a/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/MainActivityTest.java b/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/MainActivityTest.java new file mode 100644 index 0000000..ea3710d --- /dev/null +++ b/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/MainActivityTest.java @@ -0,0 +1,81 @@ +package com.android.test.hierarchyviewer; + +import android.test.ActivityInstrumentationTestCase2; +import android.view.View; + +import java.io.ByteArrayOutputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; + +public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { + private MainActivity mActivity; + private View mTextView; + + + public MainActivityTest() { + super(MainActivity.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + mActivity = getActivity(); + mTextView = mActivity.findViewById(R.id.textView); + } + + private byte[] encode(View view) throws ClassNotFoundException, NoSuchMethodException, + IllegalAccessException, InstantiationException, InvocationTargetException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(1024 * 1024); + + Object encoder = createEncoder(baos); + invokeMethod(View.class, view, "encode", encoder); + invokeMethod(encoder.getClass(), encoder, "endStream"); + + return baos.toByteArray(); + } + + private Object invokeMethod(Class targetClass, Object target, String methodName, Object... params) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class[] paramClasses = new Class[params.length]; + for (int i = 0; i < params.length; i++) { + paramClasses[i] = params[i].getClass(); + } + Method method = targetClass.getDeclaredMethod(methodName, paramClasses); + method.setAccessible(true); + return method.invoke(target, params); + } + + private Object createEncoder(ByteArrayOutputStream baos) throws ClassNotFoundException, + NoSuchMethodException, IllegalAccessException, InvocationTargetException, + InstantiationException { + Class clazz = Class.forName("android.view.ViewHierarchyEncoder"); + Constructor constructor = clazz.getConstructor(ByteArrayOutputStream.class); + return constructor.newInstance(baos); + } + + public void testTextView() throws Exception { + byte[] data = encode(mTextView); + assertNotNull(data); + assertTrue(data.length > 0); + + ViewDumpParser parser = new ViewDumpParser(); + parser.parse(data); + + List<Map<Short, Object>> views = parser.getViews(); + Map<String, Short> propertyNameTable = parser.getIds(); + + assertEquals(1, views.size()); + assertNotNull(propertyNameTable); + + Map<Short, Object> textViewProperties = views.get(0); + assertEquals("android.widget.TextView", + textViewProperties.get(propertyNameTable.get("meta:__name__"))); + + assertEquals(mActivity.getString(R.string.test), + textViewProperties.get(propertyNameTable.get("text:text"))); + } +} diff --git a/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/ViewDumpParser.java b/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/ViewDumpParser.java new file mode 100644 index 0000000..0111bc6 --- /dev/null +++ b/tests/HierarchyViewerTest/src/com/android/test/hierarchyviewer/ViewDumpParser.java @@ -0,0 +1,73 @@ +package com.android.test.hierarchyviewer; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +public class ViewDumpParser { + private Map<String, Short> mIds; + private List<Map<Short,Object>> mViews; + + public void parse(byte[] data) { + Decoder d = new Decoder(ByteBuffer.wrap(data)); + + mViews = new ArrayList<>(100); + while (d.hasRemaining()) { + Object o = d.readObject(); + if (o instanceof Map) { + //noinspection unchecked + mViews.add((Map<Short, Object>) o); + } + } + + if (mViews.isEmpty()) { + return; + } + + // the last one is the property map + Map<Short,Object> idMap = mViews.remove(mViews.size() - 1); + mIds = reverse(idMap); + } + + public String getFirstView() { + if (mViews.isEmpty()) { + return null; + } + + Map<Short, Object> props = mViews.get(0); + Object name = getProperty(props, "__name__"); + Object hash = getProperty(props, "__hash__"); + + if (name instanceof String && hash instanceof Integer) { + return String.format(Locale.US, "%s@%x", name, hash); + } else { + return null; + } + } + + private Object getProperty(Map<Short, Object> props, String key) { + return props.get(mIds.get(key)); + } + + private static Map<String, Short> reverse(Map<Short, Object> m) { + Map<String, Short> r = new HashMap<String, Short>(m.size()); + + for (Map.Entry<Short, Object> e : m.entrySet()) { + r.put((String)e.getValue(), e.getKey()); + } + + return r; + } + + public List<Map<Short, Object>> getViews() { + return mViews; + } + + public Map<String, Short> getIds() { + return mIds; + } + +} diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 8531944..10cf5c1 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -24,11 +24,11 @@ <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> - <uses-sdk android:minSdkVersion="11" /> - + <uses-sdk android:minSdkVersion="21" /> + <application android:label="HwUi" - android:hardwareAccelerated="true"> + android:theme="@android:style/Theme.Material.Light"> <activity android:name="HwTests" @@ -42,8 +42,7 @@ <activity android:name="PathOpsActivity" - android:label="Path/Ops" - android:theme="@android:style/Theme.Holo.Light"> + android:label="Path/Ops"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="com.android.test.hwui.TEST" /> @@ -52,8 +51,7 @@ <activity android:name="AssetsAtlasActivity" - android:label="Atlas/Framework" - android:theme="@android:style/Theme.Holo.Light"> + android:label="Atlas/Framework"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="com.android.test.hwui.TEST" /> @@ -62,8 +60,7 @@ <activity android:name="ScaledTextActivity" - android:label="Text/Scaled" - android:theme="@android:style/Theme.Holo.Light"> + android:label="Text/Scaled"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="com.android.test.hwui.TEST" /> @@ -72,8 +69,7 @@ <activity android:name="Rotate3dTextActivity" - android:label="Text/3D Rotation" - android:theme="@android:style/Theme.Holo.Light"> + android:label="Text/3D Rotation"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="com.android.test.hwui.TEST" /> diff --git a/tests/HwAccelerationTest/res/layout/projection_clipping.xml b/tests/HwAccelerationTest/res/layout/projection_clipping.xml index 7177fc8f..1f2b939 100644 --- a/tests/HwAccelerationTest/res/layout/projection_clipping.xml +++ b/tests/HwAccelerationTest/res/layout/projection_clipping.xml @@ -14,13 +14,13 @@ android:id="@+id/clickable1" android:layout_width="100dp" android:layout_height="100dp" - android:background="?android:attr/selectableItemBackground"/> + android:background="?android:attr/selectableItemBackgroundBorderless"/> <View android:id="@+id/clickable2" android:translationX="50dp" android:translationY="10dp" android:layout_width="150dp" android:layout_height="100dp" - android:background="?android:attr/selectableItemBackground"/> + android:background="?android:attr/selectableItemBackgroundBorderless"/> </FrameLayout> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java index afd6a8d..5bc8934 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java @@ -24,7 +24,7 @@ import android.graphics.Paint; import android.graphics.Paint.Style; import android.os.Bundle; import android.os.Trace; -import android.view.HardwareCanvas; +import android.view.DisplayListCanvas; import android.view.RenderNodeAnimator; import android.view.View; import android.widget.LinearLayout; @@ -88,8 +88,8 @@ public class CirclePropActivity extends Activity { super.onDraw(canvas); if (canvas.isHardwareAccelerated()) { - HardwareCanvas hwcanvas = (HardwareCanvas) canvas; - hwcanvas.drawCircle(mX, mY, mRadius, mPaint); + DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas; + displayListCanvas.drawCircle(mX, mY, mRadius, mPaint); } } diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java index 5ba3ad9..be5d7f9 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java @@ -46,9 +46,9 @@ public class ProjectionActivity extends Activity { } private void setProject(boolean value) { - RenderNode displayList = getDisplayList(); - if (displayList != null) { - displayList.setProjectBackwards(value); + RenderNode renderNode = updateDisplayListIfDirty(); + if (renderNode != null) { + renderNode.setProjectBackwards(value); } // NOTE: we can't invalidate ProjectedView for the redraw because: // 1) the view won't preserve displayList properties that it doesn't know about diff --git a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java index b9a2a7e..dfbbd7e 100644 --- a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java +++ b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java @@ -51,9 +51,9 @@ public class MainActivity extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Resources res = getResources(); - defaultColor = res.getColor(R.color.none_received); - startJobColor = res.getColor(R.color.start_received); - stopJobColor = res.getColor(R.color.stop_received); + defaultColor = getColor(R.color.none_received); + startJobColor = getColor(R.color.start_received); + stopJobColor = getColor(R.color.stop_received); // Set up UI. mShowStartView = (TextView) findViewById(R.id.onstart_textview); diff --git a/tests/Assistant/Android.mk b/tests/LegacyAssistant/Android.mk index bf8cc29..0ad48d1 100644 --- a/tests/Assistant/Android.mk +++ b/tests/LegacyAssistant/Android.mk @@ -3,7 +3,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := $(call all-subdir-java-files) -LOCAL_PACKAGE_NAME := Assistant +LOCAL_PACKAGE_NAME := LegacyAssistant LOCAL_MODULE_TAGS := tests LOCAL_CERTIFICATE := platform diff --git a/tests/Assistant/AndroidManifest.xml b/tests/LegacyAssistant/AndroidManifest.xml index b5d4d51..7ae5103 100644 --- a/tests/Assistant/AndroidManifest.xml +++ b/tests/LegacyAssistant/AndroidManifest.xml @@ -15,7 +15,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.test.assistant"> + package="com.google.android.test.legacyassistant"> <application android:label="@string/activity_title"> diff --git a/tests/Assistant/res/drawable-hdpi/ic_action_assist_activated.png b/tests/LegacyAssistant/res/drawable-hdpi/ic_action_assist_activated.png Binary files differindex cea8ac4..cea8ac4 100644 --- a/tests/Assistant/res/drawable-hdpi/ic_action_assist_activated.png +++ b/tests/LegacyAssistant/res/drawable-hdpi/ic_action_assist_activated.png diff --git a/tests/Assistant/res/drawable-hdpi/ic_action_assist_normal.png b/tests/LegacyAssistant/res/drawable-hdpi/ic_action_assist_normal.png Binary files differindex bb7702d..bb7702d 100644 --- a/tests/Assistant/res/drawable-hdpi/ic_action_assist_normal.png +++ b/tests/LegacyAssistant/res/drawable-hdpi/ic_action_assist_normal.png diff --git a/tests/Assistant/res/drawable-mdpi/ic_action_assist_activated.png b/tests/LegacyAssistant/res/drawable-mdpi/ic_action_assist_activated.png Binary files differindex 5841d82..5841d82 100644 --- a/tests/Assistant/res/drawable-mdpi/ic_action_assist_activated.png +++ b/tests/LegacyAssistant/res/drawable-mdpi/ic_action_assist_activated.png diff --git a/tests/Assistant/res/drawable-mdpi/ic_action_assist_normal.png b/tests/LegacyAssistant/res/drawable-mdpi/ic_action_assist_normal.png Binary files differindex 3851f03..3851f03 100644 --- a/tests/Assistant/res/drawable-mdpi/ic_action_assist_normal.png +++ b/tests/LegacyAssistant/res/drawable-mdpi/ic_action_assist_normal.png diff --git a/tests/Assistant/res/drawable-xhdpi/ic_action_assist_activated.png b/tests/LegacyAssistant/res/drawable-xhdpi/ic_action_assist_activated.png Binary files differindex 778db19..778db19 100644 --- a/tests/Assistant/res/drawable-xhdpi/ic_action_assist_activated.png +++ b/tests/LegacyAssistant/res/drawable-xhdpi/ic_action_assist_activated.png diff --git a/tests/Assistant/res/drawable-xhdpi/ic_action_assist_normal.png b/tests/LegacyAssistant/res/drawable-xhdpi/ic_action_assist_normal.png Binary files differindex ad49125..ad49125 100644 --- a/tests/Assistant/res/drawable-xhdpi/ic_action_assist_normal.png +++ b/tests/LegacyAssistant/res/drawable-xhdpi/ic_action_assist_normal.png diff --git a/tests/Assistant/res/drawable/ic_action_assist.xml b/tests/LegacyAssistant/res/drawable/ic_action_assist.xml index 05c4bf5..05c4bf5 100644 --- a/tests/Assistant/res/drawable/ic_action_assist.xml +++ b/tests/LegacyAssistant/res/drawable/ic_action_assist.xml diff --git a/tests/Assistant/res/layout/assist_intent_activity.xml b/tests/LegacyAssistant/res/layout/assist_intent_activity.xml index 49785bc..49785bc 100644 --- a/tests/Assistant/res/layout/assist_intent_activity.xml +++ b/tests/LegacyAssistant/res/layout/assist_intent_activity.xml diff --git a/tests/Assistant/res/values/strings.xml b/tests/LegacyAssistant/res/values/strings.xml index a59c1ef..a59c1ef 100644 --- a/tests/Assistant/res/values/strings.xml +++ b/tests/LegacyAssistant/res/values/strings.xml diff --git a/tests/Assistant/src/com/google/android/test/assistant/AssistActivity.java b/tests/LegacyAssistant/src/com/google/android/test/legacyassistant/AssistActivity.java index 51894a1..b3dbb15 100644 --- a/tests/Assistant/src/com/google/android/test/assistant/AssistActivity.java +++ b/tests/LegacyAssistant/src/com/google/android/test/legacyassistant/AssistActivity.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.google.android.test.assistant; +package com.google.android.test.legacyassistant; import android.app.Activity; import android.os.Bundle; -import com.google.android.test.assistant.R; +import com.google.android.test.legacyassistant.R; public class AssistActivity extends Activity { diff --git a/tests/LockTaskTests/Android.mk b/tests/LockTaskTests/Android.mk new file mode 100644 index 0000000..ed58643 --- /dev/null +++ b/tests/LockTaskTests/Android.mk @@ -0,0 +1,15 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_PATH := $(PRODUCT_OUT)/system/priv-app + +LOCAL_PACKAGE_NAME := LockTaskTests +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-Iaidl-files-under, src) $(call all-java-files-under, src) + +include $(BUILD_PACKAGE) + +# Use the following include to make our test apk. +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/LockTaskTests/AndroidManifest.xml b/tests/LockTaskTests/AndroidManifest.xml new file mode 100644 index 0000000..e349c92 --- /dev/null +++ b/tests/LockTaskTests/AndroidManifest.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.android.example.locktasktests" + android:versionCode="1" + android:versionName="1.0" > + + <uses-sdk + android:minSdkVersion="22" + android:targetSdkVersion="22" /> + <uses-permission android:name="android.permission.INTERNET"/> + + <application + android:icon="@drawable/ic_launcher" + android:label="@string/app_name" + android:theme="@style/AppTheme" + android:allowBackup="true" > + <activity + android:name="com.google.android.example.locktasktests.MainActivity" + android:label="@string/app_name" + android:screenOrientation="portrait" + android:theme="@style/AppTheme" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity + android:name="com.google.android.example.locktasktests.LockDefaultActivity" + android:label="@string/title_activity_default" + android:taskAffinity="" + android:documentLaunchMode="always" + android:lockTaskMode="normal" > + </activity> + <activity + android:name="com.google.android.example.locktasktests.LockTaskNeverActivity" + android:label="@string/title_activity_never" + android:taskAffinity="" + android:documentLaunchMode="always" + android:lockTaskMode="never" > + </activity> + <activity + android:name="com.google.android.example.locktasktests.LockWhitelistedActivity" + android:label="@string/title_activity_whitelist" + android:taskAffinity="" + android:documentLaunchMode="always" + android:lockTaskMode="if_whitelisted" > + </activity> + <activity + android:name="com.google.android.example.locktasktests.LockAtLaunchActivity" + android:label="@string/title_activity_always" + android:taskAffinity="" + android:documentLaunchMode="always" + android:lockTaskMode="always" > + </activity> + </application> + +</manifest> diff --git a/tests/LockTaskTests/res/drawable-hdpi/ic_launcher.png b/tests/LockTaskTests/res/drawable-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..288b665 --- /dev/null +++ b/tests/LockTaskTests/res/drawable-hdpi/ic_launcher.png diff --git a/tests/LockTaskTests/res/drawable-mdpi/ic_launcher.png b/tests/LockTaskTests/res/drawable-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..6ae570b --- /dev/null +++ b/tests/LockTaskTests/res/drawable-mdpi/ic_launcher.png diff --git a/tests/LockTaskTests/res/drawable-xhdpi/ic_launcher.png b/tests/LockTaskTests/res/drawable-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..d4fb7cd --- /dev/null +++ b/tests/LockTaskTests/res/drawable-xhdpi/ic_launcher.png diff --git a/tests/LockTaskTests/res/drawable-xxhdpi/ic_launcher.png b/tests/LockTaskTests/res/drawable-xxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..85a6081 --- /dev/null +++ b/tests/LockTaskTests/res/drawable-xxhdpi/ic_launcher.png diff --git a/tests/LockTaskTests/res/layout/activity_launch.xml b/tests/LockTaskTests/res/layout/activity_launch.xml new file mode 100644 index 0000000..b619743 --- /dev/null +++ b/tests/LockTaskTests/res/layout/activity_launch.xml @@ -0,0 +1,32 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/root_launch" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:paddingBottom="@dimen/activity_vertical_margin" + android:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" + tools:context="com.google.android.example.locktasktests.LaunchActivity" > + + <Button + android:id="@+id/button_try_lock" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:onClick="onTryLock" + android:text="@string/try_lock" /> + <Button + android:id="@+id/button_try_unlock" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:onClick="onTryUnlock" + android:text="@string/try_unlock" /> + <Button + android:id="@+id/button_launch_main" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:onClick="onLaunchMain" + android:text="@string/launch_main" /> + +</LinearLayout> diff --git a/tests/LockTaskTests/res/layout/activity_main.xml b/tests/LockTaskTests/res/layout/activity_main.xml new file mode 100644 index 0000000..dbdc9fa --- /dev/null +++ b/tests/LockTaskTests/res/layout/activity_main.xml @@ -0,0 +1,47 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/root_launch" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:paddingBottom="@dimen/activity_vertical_margin" + android:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" + tools:context="com.google.android.example.locktasktests.MainActivity" > + <Button + android:id="@+id/button_default" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:onClick="onButtonPressed" + android:text="@string/launch_default" /> + <Button + android:id="@+id/button_never" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:onClick="onButtonPressed" + android:text="@string/launch_never" /> + <Button + android:id="@+id/button_whitelist" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:onClick="onButtonPressed" + android:text="@string/launch_whitelist" /> + <Button + android:id="@+id/button_always" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:onClick="onButtonPressed" + android:text="@string/launch_always" /> + <Button + android:id="@+id/toast_pinned" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:onClick="onToast" + android:text="@string/toast_pinned" /> +</LinearLayout> diff --git a/tests/LockTaskTests/res/values-v11/styles.xml b/tests/LockTaskTests/res/values-v11/styles.xml new file mode 100644 index 0000000..3c02242 --- /dev/null +++ b/tests/LockTaskTests/res/values-v11/styles.xml @@ -0,0 +1,11 @@ +<resources> + + <!-- + Base application theme for API 11+. This theme completely replaces + AppBaseTheme from res/values/styles.xml on API 11+ devices. + --> + <style name="AppBaseTheme" parent="android:Theme.Holo.Light"> + <!-- API 11 theme customizations can go here. --> + </style> + +</resources> diff --git a/tests/LockTaskTests/res/values-v14/styles.xml b/tests/LockTaskTests/res/values-v14/styles.xml new file mode 100644 index 0000000..a91fd03 --- /dev/null +++ b/tests/LockTaskTests/res/values-v14/styles.xml @@ -0,0 +1,12 @@ +<resources> + + <!-- + Base application theme for API 14+. This theme completely replaces + AppBaseTheme from BOTH res/values/styles.xml and + res/values-v11/styles.xml on API 14+ devices. + --> + <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar"> + <!-- API 14 theme customizations can go here. --> + </style> + +</resources> diff --git a/tests/LockTaskTests/res/values-w820dp/dimens.xml b/tests/LockTaskTests/res/values-w820dp/dimens.xml new file mode 100644 index 0000000..f3e7020 --- /dev/null +++ b/tests/LockTaskTests/res/values-w820dp/dimens.xml @@ -0,0 +1,10 @@ +<resources> + + <!-- + Example customization of dimensions originally defined in res/values/dimens.xml + (such as screen margins) for screens with more than 820dp of available width. This + would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). + --> + <dimen name="activity_horizontal_margin">64dp</dimen> + +</resources> diff --git a/tests/LockTaskTests/res/values/dimens.xml b/tests/LockTaskTests/res/values/dimens.xml new file mode 100644 index 0000000..55c1e59 --- /dev/null +++ b/tests/LockTaskTests/res/values/dimens.xml @@ -0,0 +1,7 @@ +<resources> + + <!-- Default screen margins, per the Android Design guidelines. --> + <dimen name="activity_horizontal_margin">16dp</dimen> + <dimen name="activity_vertical_margin">16dp</dimen> + +</resources> diff --git a/tests/LockTaskTests/res/values/strings.xml b/tests/LockTaskTests/res/values/strings.xml new file mode 100644 index 0000000..3bcae80 --- /dev/null +++ b/tests/LockTaskTests/res/values/strings.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string name="app_name">Lock Task Tests</string> + <string name="title_activity_default">LockDefaultActivity</string> + <string name="title_activity_never">LockTaskNeverActivity</string> + <string name="title_activity_whitelist">LockWhitelistedActivity</string> + <string name="title_activity_always">LockAtLaunchActivity</string> + <string name="launch_default">android:lockTaskMode=\n + \"default\"\n + Pinnable from Overview.</string> + <string name="launch_never">android:lockTaskMode=\n + \"never\"\n + Not Lockable or Pinnable.</string> + <string name="launch_whitelist">android:lockTaskMode=\n + \"if_whitelisted\"\n + Lockable if whitelisted, Pinnable.\n + Use SampleDeviceOwner app to set whitelist.</string> + <string name="launch_always">android:lockTaskMode=\n + \"always\"\n + Launches into lock mode.</string> + <string name="launch_main">launch MainActivity (as activity)"</string> + <string name="try_lock">Call startLockMode()</string> + <string name="try_unlock">Call stopLockMode()</string> + + <string name="toast_pinned">Show pinned toast message</string> +</resources> diff --git a/tests/LockTaskTests/res/values/styles.xml b/tests/LockTaskTests/res/values/styles.xml new file mode 100644 index 0000000..6ce89c7 --- /dev/null +++ b/tests/LockTaskTests/res/values/styles.xml @@ -0,0 +1,20 @@ +<resources> + + <!-- + Base application theme, dependent on API level. This theme is replaced + by AppBaseTheme from res/values-vXX/styles.xml on newer devices. + --> + <style name="AppBaseTheme" parent="android:Theme.Light"> + <!-- + Theme customizations available in newer API levels can go in + res/values-vXX/styles.xml, while customizations related to + backward-compatibility can go here. + --> + </style> + + <!-- Application theme. --> + <style name="AppTheme" parent="AppBaseTheme"> + <!-- All customizations that are NOT specific to a particular API-level can go here. --> + </style> + +</resources> diff --git a/tests/LockTaskTests/src/com/google/android/example/locktasktests/LaunchActivity.java b/tests/LockTaskTests/src/com/google/android/example/locktasktests/LaunchActivity.java new file mode 100644 index 0000000..ab60d485 --- /dev/null +++ b/tests/LockTaskTests/src/com/google/android/example/locktasktests/LaunchActivity.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2015 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.google.android.example.locktasktests; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.view.View; +import android.widget.EditText; + +public class LaunchActivity extends Activity { + + Runnable mBackgroundPolling; + boolean mRunning; + Handler mHandler; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_launch); + mBackgroundPolling = new Runnable() { + @Override + public void run() { + if (!mRunning) { + return; + } + ActivityManager activityManager = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + final int color = activityManager.getLockTaskModeState() != + ActivityManager.LOCK_TASK_MODE_NONE ? 0xFFFFC0C0 : 0xFFFFFFFF; + findViewById(R.id.root_launch).setBackgroundColor(color); + mHandler.postDelayed(this, 1000); + } + }; + mHandler = new Handler(Looper.getMainLooper()); + } + + @Override + public void onResume() { + super.onResume(); + mRunning = true; + mBackgroundPolling.run(); + } + + @Override + public void onPause() { + super.onPause(); + mRunning = false; + } + + public void onTryLock(View view) { + startLockTask(); + } + + public void onTryUnlock(View view) { + stopLockTask(); + } + + public void onLaunchMain(View view) { + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + } +} diff --git a/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockAtLaunchActivity.java b/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockAtLaunchActivity.java new file mode 100644 index 0000000..4390c94 --- /dev/null +++ b/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockAtLaunchActivity.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2015 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.google.android.example.locktasktests; + +public class LockAtLaunchActivity extends LaunchActivity { +} diff --git a/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockDefaultActivity.java b/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockDefaultActivity.java new file mode 100644 index 0000000..7e57ab7 --- /dev/null +++ b/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockDefaultActivity.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2015 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.google.android.example.locktasktests; + +public class LockDefaultActivity extends LaunchActivity { +} diff --git a/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockTaskNeverActivity.java b/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockTaskNeverActivity.java new file mode 100644 index 0000000..69c2cbc --- /dev/null +++ b/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockTaskNeverActivity.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2015 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.google.android.example.locktasktests; + +public class LockTaskNeverActivity extends LaunchActivity { +} diff --git a/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockWhitelistedActivity.java b/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockWhitelistedActivity.java new file mode 100644 index 0000000..387baa2 --- /dev/null +++ b/tests/LockTaskTests/src/com/google/android/example/locktasktests/LockWhitelistedActivity.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2015 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.google.android.example.locktasktests; + +public class LockWhitelistedActivity extends LaunchActivity { +} diff --git a/tests/LockTaskTests/src/com/google/android/example/locktasktests/MainActivity.java b/tests/LockTaskTests/src/com/google/android/example/locktasktests/MainActivity.java new file mode 100644 index 0000000..3e4f8ee --- /dev/null +++ b/tests/LockTaskTests/src/com/google/android/example/locktasktests/MainActivity.java @@ -0,0 +1,79 @@ + +package com.google.android.example.locktasktests; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.view.View; + +public class MainActivity extends Activity { + + private final static String TAG = "LockTaskTests"; + Runnable mBackgroundPolling; + boolean mRunning; + Handler mHandler; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + mBackgroundPolling = new Runnable() { + // Poll lock task state and set background pink if locked, otherwise white. + @Override + public void run() { + if (!mRunning) { + return; + } + ActivityManager activityManager = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + final int color = activityManager.getLockTaskModeState() != + ActivityManager.LOCK_TASK_MODE_NONE ? 0xFFFFC0C0 : 0xFFFFFFFF; + findViewById(R.id.root_launch).setBackgroundColor(color); + mHandler.postDelayed(this, 500); + } + }; + mHandler = new Handler(Looper.getMainLooper()); + } + + @Override + public void onResume() { + super.onResume(); + mRunning = true; + mBackgroundPolling.run(); + } + + @Override + public void onPause() { + super.onPause(); + mRunning = false; + } + + public void onButtonPressed(View v) { + Class activity = null; + switch (v.getId()) { + case R.id.button_default: + activity = LockDefaultActivity.class; + break; + case R.id.button_never: + activity = LockTaskNeverActivity.class; + break; + case R.id.button_whitelist: + activity = LockWhitelistedActivity.class; + break; + case R.id.button_always: + activity = LockAtLaunchActivity.class; + break; + } + Intent intent = new Intent(this, activity); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } + + public void onToast(View v) { + showLockTaskEscapeMessage(); + } +} diff --git a/tests/MemoryUsage/AndroidManifest.xml b/tests/MemoryUsage/AndroidManifest.xml index 3932e5b..cd559c5 100644 --- a/tests/MemoryUsage/AndroidManifest.xml +++ b/tests/MemoryUsage/AndroidManifest.xml @@ -6,7 +6,9 @@ android:name="com.android.tests.memoryusage.MemoryUsageInstrumentation" android:targetPackage="com.android.tests.memoryusage" /> + <uses-permission android:name="android.permission.REAL_GET_TASKS" /> + <application android:label="Memory Usage Test"> <uses-library android:name="android.test.runner" /> </application> -</manifest>
\ No newline at end of file +</manifest> diff --git a/tests/OneMedia/Android.mk b/tests/OneMedia/Android.mk index 4d39728..9fc6403 100644 --- a/tests/OneMedia/Android.mk +++ b/tests/OneMedia/Android.mk @@ -9,6 +9,8 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files) \ LOCAL_PACKAGE_NAME := OneMedia LOCAL_CERTIFICATE := platform +LOCAL_JAVA_LIBRARIES += org.apache.http.legacy + LOCAL_PROGUARD_ENABLED := disabled include $(BUILD_PACKAGE) diff --git a/tests/OneMedia/AndroidManifest.xml b/tests/OneMedia/AndroidManifest.xml index beafeb4..c6824ec 100644 --- a/tests/OneMedia/AndroidManifest.xml +++ b/tests/OneMedia/AndroidManifest.xml @@ -13,6 +13,8 @@ android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > + + <uses-library android:name="org.apache.http.legacy" android:required="false" /> <activity android:name="com.android.onemedia.OnePlayerActivity" android:label="@string/app_name" > diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs index 42b1cf1..0c177ef 100644 --- a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs +++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs @@ -116,7 +116,6 @@ static void renderAllMeshes() { rs_allocation allMeshes = rsGetAllocation(gMeshes); int size = rsAllocationGetDimX(allMeshes); gLookAt = 0.0f; - float minX, minY, minZ, maxX, maxY, maxZ; for (int i = 0; i < size; i++) { MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); rsgDrawMesh(info->mMesh); @@ -124,7 +123,6 @@ static void renderAllMeshes() { } static void drawDescription() { - uint width = rsgGetWidth(); uint height = rsgGetHeight(); int left = 0, right = 0, top = 0, bottom = 0; @@ -196,7 +194,6 @@ int root(void) { uint32_t w = rsAllocationGetDimX(gOffscreen); uint32_t h = rsAllocationGetDimY(gOffscreen); - uint32_t numElements = w*h; rsgAllocationSyncAll(gOffscreen, RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET); diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs index 05ef3ac..13a3c85 100644 --- a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs +++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs @@ -115,7 +115,6 @@ static void renderAllMeshes() { rs_allocation allMeshes = rsGetAllocation(gMeshes); int size = rsAllocationGetDimX(allMeshes); gLookAt = 0.0f; - float minX, minY, minZ, maxX, maxY, maxZ; for (int i = 0; i < size; i++) { MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); rsgDrawMesh(info->mMesh); @@ -123,7 +122,6 @@ static void renderAllMeshes() { } static void drawDescription() { - uint width = rsgGetWidth(); uint height = rsgGetHeight(); int left = 0, right = 0, top = 0, bottom = 0; diff --git a/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs index de2a0a7..d3dd5b9 100644 --- a/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs +++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs @@ -123,7 +123,6 @@ static void renderAllMeshes() { rs_allocation allMeshes = rsGetAllocation(gMeshes); int size = rsAllocationGetDimX(allMeshes); gLookAt = 0.0f; - float minX, minY, minZ, maxX, maxY, maxZ; for (int i = 0; i < size; i++) { MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); rsgDrawMesh(info->mMesh); @@ -131,7 +130,6 @@ static void renderAllMeshes() { } void drawDescription() { - uint width = rsgGetWidth(); uint height = rsgGetHeight(); int left = 0, right = 0, top = 0, bottom = 0; @@ -163,7 +161,7 @@ int root(void) { rsMatrixMultiply(&matrix, &gPostureMatrix); rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f); rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f); - + rsgProgramVertexLoadModelMatrix(&matrix); renderAllMeshes(); diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs index 27e5b11..43cf4e0 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs @@ -85,7 +85,7 @@ static void runSubTest(int index) { TestData testData; fillSurfaceParams(&testData); - rs_allocation null_alloc; + rs_allocation null_alloc = {0}; rsForEach(gTestScripts[index].testScript, gTestScripts[index].testData, null_alloc, @@ -125,7 +125,6 @@ static bool checkInit() { static int benchMode = 0; static bool benchmarkSingleTest = false; -static int benchSubMode = 0; static int runningLoops = 0; static bool sendMsgFlag = false; @@ -209,7 +208,6 @@ static void benchmark() { drawOffscreenResult(0, 0, quadW, quadH); int left = 0, right = 0, top = 0, bottom = 0; - uint width = rsgGetWidth(); uint height = rsgGetHeight(); rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f); rsgBindFont(gFontSerif); diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs index 7f10019..0f50828 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs @@ -52,7 +52,6 @@ static void displayFontSamples(int fillNum) { fonts[3] = gFontSerif; fonts[4] = gFontSans; - uint width = gRenderSurfaceW; uint height = gRenderSurfaceH; int left = 0, right = 0, top = 0, bottom = 0; rsgMeasureText(sampleText, &left, &right, &top, &bottom); diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs index 5089092..e87db39 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs @@ -143,7 +143,6 @@ static void createParticle(Particle_t *part, int idx, float scale) { float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f); float id = d / gGalaxyRadius; float z = randomGauss() * 0.4f * (1.0f - id); - float p = -d * ELLIPSE_TWIST; if (d < gGalaxyRadius * 0.33f) { part->color.x = (uchar) (220 + id * 35); @@ -305,7 +304,6 @@ static void drawMeshInPage(float xStart, float yStart, int wResolution, int hRes int left = 0, right = 0, top = 0, bottom = 0; rsgMeasureText(gSampleTextList100[0].item, &left, &right, &top, &bottom); float textHeight = (float)(top - bottom); - float textWidth = (float)(right - left); rs_matrix4x4 matrix; rsMatrixLoadScale(&matrix, size, size, 1.0); diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh index 575794b..00793c0 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh @@ -19,7 +19,7 @@ #include "scenegraph_objects.rsh" //#define DEBUG_PARAMS -static void debugParam(SgShaderParam *p, SgShaderParamData *pData) { +static inline void debugParam(SgShaderParam *p, SgShaderParamData *pData) { rsDebug("____________ Param ____________", p); printName(pData->paramName); rsDebug("bufferOffset", p->bufferOffset); @@ -44,8 +44,7 @@ static void debugParam(SgShaderParam *p, SgShaderParamData *pData) { } } - -static void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) { +static inline void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) { #ifdef DEBUG_PARAMS rsDebug("Writing value ", *input); rsDebug("Writing vec size ", vecSize); @@ -67,7 +66,7 @@ static void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) { } } -static bool processParam(SgShaderParam *p, SgShaderParamData *pData, +static inline bool processParam(SgShaderParam *p, SgShaderParamData *pData, uint8_t *constantBuffer, const SgCamera *currentCam, SgFragmentShader *shader) { @@ -155,7 +154,7 @@ static bool processParam(SgShaderParam *p, SgShaderParamData *pData, return true; } -static void processAllParams(rs_allocation shaderConst, +static inline void processAllParams(rs_allocation shaderConst, rs_allocation allParams, const SgCamera *camera) { if (rsIsObject(shaderConst)) { @@ -177,7 +176,7 @@ static void processAllParams(rs_allocation shaderConst, } } -static void processTextureParams(SgFragmentShader *shader) { +static inline void processTextureParams(SgFragmentShader *shader) { int numParams = 0; if (rsIsObject(shader->shaderTextureParams)) { numParams = rsAllocationGetDimX(shader->shaderTextureParams); diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs index 8a73dbd..205b2cb 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs @@ -78,7 +78,7 @@ static void draw(SgRenderable *obj) { if (rsIsObject(renderState->pr)) { rsgBindProgramRaster(renderState->pr); } else { - rs_program_raster pr; + rs_program_raster pr = {0}; rsgBindProgramRaster(pr); } diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh index bdca3ab..90ae212 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh @@ -208,7 +208,7 @@ typedef struct Texture_s { rs_allocation texture; } SgTexture; -static void printName(rs_allocation name) { +static inline void printName(rs_allocation name) { if (!rsIsObject(name)) { rsDebug("no name", 0); return; @@ -217,7 +217,7 @@ static void printName(rs_allocation name) { rsDebug((const char*)rsGetElementAt(name, 0), 0); } -static void printCameraInfo(const SgCamera *cam) { +static inline void printCameraInfo(const SgCamera *cam) { rsDebug("***** Camera information. ptr:", cam); printName(cam->name); const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0); @@ -233,7 +233,7 @@ static void printCameraInfo(const SgCamera *cam) { rsDebug("View: ", &cam->view); } -static void printLightInfo(const SgLight *light) { +static inline void printLightInfo(const SgLight *light) { rsDebug("***** Light information. ptr:", light); printName(light->name); const SgTransform *lTransform = (const SgTransform *)rsGetElementAt(light->transformMatrix, 0); @@ -246,7 +246,7 @@ static void printLightInfo(const SgLight *light) { rsDebug("Type: ", light->type); } -static void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *pnt, float3 *vec) { +static inline void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *pnt, float3 *vec) { rsDebug("=================================", screenX); rsDebug("Point X", screenX); rsDebug("Point Y", screenY); @@ -290,7 +290,7 @@ static void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 * *pnt = cam->position.xyz; } -static bool intersect(const SgRenderable *obj, float3 pnt, float3 vec) { +static inline bool intersect(const SgRenderable *obj, float3 pnt, float3 vec) { // Solving for t^2 + Bt + C = 0 float3 originMinusCenter = pnt - obj->worldBoundingSphere.xyz; float B = dot(originMinusCenter, vec) * 2.0f; diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs index 941b5a8..1d0b5be 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs @@ -26,6 +26,7 @@ typedef struct { } ParentData; //#define DEBUG_TRANSFORMS +/* Unused function: static void debugTransform(SgTransform *data, const ParentData *parent) { rsDebug("****** <Transform> ******", (int)data); printName(data->name); @@ -53,6 +54,7 @@ static void debugTransform(SgTransform *data, const ParentData *parent) { rsDebug("timestamp", data->timestamp); rsDebug("****** </Transform> ******", (int)data); } +*/ static void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) { rs_matrix4x4 temp; @@ -119,7 +121,7 @@ void root(const rs_allocation *v_in, rs_allocation *v_out, const void *usrData) } if (rsIsObject(data->children)) { - rs_allocation nullAlloc; + rs_allocation nullAlloc = {0}; rsForEach(gTransformScript, data->children, nullAlloc, &toChild, sizeof(toChild)); } diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs index 997a1a7..d94da52 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs @@ -41,9 +41,7 @@ void init() { gRotate = 0.0f; } -static int pos = 50; static float gRotateY = 120.0f; -static float3 gLookAt = 0; static float gZoom = 50.0f; static void displayLoading() { if (rsIsObject(gRobotTex) && rsIsObject(gRobotMesh)) { diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs index ae32e3a..735f6b9 100644 --- a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs +++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs @@ -131,7 +131,6 @@ static void renderAllMeshes() { rs_allocation allMeshes = rsGetAllocation(gMeshes); int size = rsAllocationGetDimX(allMeshes); gLookAt = 0.0f; - float minX, minY, minZ, maxX, maxY, maxZ; for (int i = 0; i < size; i++) { MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); rsgDrawMesh(info->mMesh); diff --git a/tests/Split/res/values-b+fr+Latn+CA/strings.xml b/tests/Split/res/values-b+fr+Latn+CA/strings.xml new file mode 100644 index 0000000..108a135 --- /dev/null +++ b/tests/Split/res/values-b+fr+Latn+CA/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="test">Bonsoir!</string> +</resources> diff --git a/tests/Split/res/values-fr-rCA/strings.xml b/tests/Split/res/values-fr-rCA/strings.xml new file mode 100644 index 0000000..0837a68 --- /dev/null +++ b/tests/Split/res/values-fr-rCA/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="test">Bonjour</string> +</resources> diff --git a/tests/StatusBar/res/drawable-hdpi/stat_sys_warning.png b/tests/StatusBar/res/drawable-hdpi/stat_sys_warning.png Binary files differnew file mode 100644 index 0000000..dbaf944 --- /dev/null +++ b/tests/StatusBar/res/drawable-hdpi/stat_sys_warning.png diff --git a/tests/StatusBar/res/drawable-mdpi/stat_sys_warning.png b/tests/StatusBar/res/drawable-mdpi/stat_sys_warning.png Binary files differnew file mode 100644 index 0000000..168f8f6 --- /dev/null +++ b/tests/StatusBar/res/drawable-mdpi/stat_sys_warning.png diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java index ba160b1..67b9d77 100644 --- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java +++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java @@ -25,7 +25,6 @@ import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; -import android.os.Environment; import android.os.Vibrator; import android.os.Handler; import android.os.UserHandle; @@ -85,7 +84,7 @@ public class NotificationTestList extends TestActivity } private Test[] mTests = new Test[] { - new Test("Off and sound") { + new Test("Off") { public void run() { PowerManager pm = (PowerManager)NotificationTestList.this.getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wl = @@ -94,9 +93,12 @@ public class NotificationTestList extends TestActivity pm.goToSleep(SystemClock.uptimeMillis()); - Notification n = new Notification(); - n.sound = Uri.parse("file://" + Environment.getExternalStorageDirectory() + - "/virtual-void.mp3"); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.stat_sys_phone) + .setContentTitle(name) + .setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + + getPackageName() + "/raw/ringer")) + .build(); Log.d(TAG, "n.sound=" + n.sound); mNM.notify(1, n); @@ -114,122 +116,120 @@ public class NotificationTestList extends TestActivity } }, - new Test("Button") { + new Test("Custom Button") { public void run() { - Notification n = new Notification(R.drawable.icon1, null, - mActivityCreateTime); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setWhen(mActivityCreateTime) + .setContentTitle(name) + .setOngoing(true) + .build(); n.contentView = new RemoteViews(getPackageName(), R.layout.button_notification); - n.flags |= Notification.FLAG_ONGOING_EVENT; - n.contentIntent = makeIntent(); n.contentView.setOnClickPendingIntent(R.id.button, makeIntent2()); mNM.notify(1, n); } }, - new Test("custom intent on text view") { + new Test("Action Button") { public void run() { - Notification n = new Notification(R.drawable.icon1, null, - mActivityCreateTime); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #1", - "This is a notification!!!", null); - n.contentView.setOnClickPendingIntent(com.android.internal.R.id.text, - makeIntent2()); - mNM.notify(1, n); - } - }, + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setWhen(mActivityCreateTime) + .setContentTitle(name) + .setOngoing(true) + .addAction(R.drawable.ic_statusbar_chat, "Button", makeIntent2()) + .build(); - new Test("Ticker 1 line") { - public void run() { - Notification n = new Notification(R.drawable.icon1, "tick tick tick", - mActivityCreateTime); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #1", - "This is a notification!!!", makeIntent()); mNM.notify(1, n); } }, - new Test("No view") { + new Test("with intent") { public void run() { - Notification n = new Notification(R.drawable.icon1, "No view", - System.currentTimeMillis()); - mNM.notify(1, n); - } - }, + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setWhen(mActivityCreateTime) + .setContentTitle("Persistent #1") + .setContentText("This is a notification!!!") + .setContentIntent(makeIntent2()) + .setOngoing(true) + .build(); - new Test("No intent") { - public void run() { - Notification n = new Notification(R.drawable.icon1, "No intent", - System.currentTimeMillis()); - n.setLatestEventInfo(NotificationTestList.this, "No intent", - "No intent", null); mNM.notify(1, n); } }, - new Test("Layout") { + new Test("Whens") { public void run() { - Notification n; + Notification.Builder n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setContentTitle(name) + .setOngoing(true); - n = new Notification(NotificationTestList.this, - R.drawable.ic_statusbar_missedcall, - null, System.currentTimeMillis()-(1000*60*60*24), - "(453) 123-2328", - "", null); - n.flags |= Notification.FLAG_ONGOING_EVENT; + mNM.notify(1, n.setContentTitle("(453) 123-2328") + .setWhen(System.currentTimeMillis()-(1000*60*60*24)) + .build()); - mNM.notify(1, n); - - mNM.notify(2, new Notification(NotificationTestList.this, - R.drawable.ic_statusbar_email, - null, System.currentTimeMillis(), - "Mark Willem, Me (2)", - "Re: Didn't you get the memo?", null)); + mNM.notify(1, n.setContentTitle("Mark Willem, Me (2)") + .setWhen(System.currentTimeMillis()) + .build()); - mNM.notify(3, new Notification(NotificationTestList.this, - R.drawable.ic_statusbar_chat, - null, System.currentTimeMillis()+(1000*60*60*24), - "Sophia Winterlanden", - "Lorem ipsum dolor sit amet.", null)); + mNM.notify(1, n.setContentTitle("Sophia Winterlanden") + .setWhen(System.currentTimeMillis() + (1000 * 60 * 60 * 24)) + .build()); } }, new Test("Bad Icon #1 (when=create)") { public void run() { - Notification n = new Notification(R.layout.chrono_notification /* not an icon */, - null, mActivityCreateTime); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #1", - "This is the same notification!!!", makeIntent()); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.layout.chrono_notification /* not an icon */) + .setWhen(mActivityCreateTime) + .setContentTitle("Persistent #1") + .setContentText("This is the same notification!!") + .setContentIntent(makeIntent()) + .build(); mNM.notify(1, n); } }, new Test("Bad Icon #1 (when=now)") { public void run() { - Notification n = new Notification(R.layout.chrono_notification /* not an icon */, - null, System.currentTimeMillis()); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #1", - "This is the same notification!!!", makeIntent()); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.layout.chrono_notification /* not an icon */) + .setWhen(System.currentTimeMillis()) + .setContentTitle("Persistent #1") + .setContentText("This is the same notification!!") + .setContentIntent(makeIntent()) + .build(); mNM.notify(1, n); } }, new Test("Null Icon #1 (when=now)") { public void run() { - Notification n = new Notification(0, null, System.currentTimeMillis()); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #1", - "This is the same notification!!!", makeIntent()); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(0) + .setWhen(System.currentTimeMillis()) + .setContentTitle("Persistent #1") + .setContentText("This is the same notification!!") + .setContentIntent(makeIntent()) + .build(); mNM.notify(1, n); } }, new Test("Bad resource #1 (when=create)") { public void run() { - Notification n = new Notification(R.drawable.icon2, - null, mActivityCreateTime); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #1", - "This is the same notification!!!", makeIntent()); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon2) + .setWhen(mActivityCreateTime) + .setContentTitle("Persistent #1") + .setContentText("This is the same notification!!") + .setContentIntent(makeIntent()) + .build(); n.contentView.setInt(1 /*bogus*/, "bogus method", 666); mNM.notify(1, n); } @@ -237,29 +237,18 @@ public class NotificationTestList extends TestActivity new Test("Bad resource #1 (when=now)") { public void run() { - Notification n = new Notification(R.drawable.icon2, - null, System.currentTimeMillis()); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #1", - "This is the same notification!!!", makeIntent()); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon2) + .setWhen(System.currentTimeMillis()) + .setContentTitle("Persistent #1") + .setContentText("This is the same notification!!") + .setContentIntent(makeIntent()) + .build(); n.contentView.setInt(1 /*bogus*/, "bogus method", 666); mNM.notify(1, n); } }, - - new Test("Bad resource #3") { - public void run() - { - Notification n = new Notification(NotificationTestList.this, - R.drawable.ic_statusbar_missedcall, - null, System.currentTimeMillis()-(1000*60*60*24), - "(453) 123-2328", - "", null); - n.contentView.setInt(1 /*bogus*/, "bogus method", 666); - mNM.notify(3, n); - } - }, - new Test("Times") { public void run() { @@ -278,22 +267,25 @@ public class NotificationTestList extends TestActivity new Runnable() { public void run() { Log.d(TAG, "Stress - Ongoing/Latest 0"); - Notification n = new Notification(NotificationTestList.this, - R.drawable.icon3, - null, System.currentTimeMillis(), "Stress - Ongoing", - "Notify me!!!", null); - n.flags |= Notification.FLAG_ONGOING_EVENT; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon3) + .setWhen(System.currentTimeMillis()) + .setContentTitle("Stress - Ongoing") + .setContentText("Notify me!!!") + .setOngoing(true) + .build(); mNM.notify(1, n); } }, new Runnable() { public void run() { Log.d(TAG, "Stress - Ongoing/Latest 1"); - Notification n = new Notification(NotificationTestList.this, - R.drawable.icon4, - null, System.currentTimeMillis(), "Stress - Latest", - "Notify me!!!", null); - //n.flags |= Notification.FLAG_ONGOING_EVENT; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon4) + .setWhen(System.currentTimeMillis()) + .setContentTitle("Stress - Latest") + .setContentText("Notify me!!!") + .build(); mNM.notify(1, n); } } @@ -302,12 +294,15 @@ public class NotificationTestList extends TestActivity new Test("Long") { public void run() { - Notification n = new Notification(); - n.defaults |= Notification.DEFAULT_SOUND ; - n.vibrate = new long[] { - 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, - 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, - 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400 }; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setContentTitle(name) + .setDefaults(Notification.DEFAULT_SOUND) + .setVibrate(new long[] { + 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, + 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, + 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400 }) + .build(); mNM.notify(1, n); } }, @@ -320,21 +315,19 @@ public class NotificationTestList extends TestActivity Thread t = new Thread() { public void run() { int x = 0; + final Notification.Builder n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setContentTitle(name) + .setOngoing(true); + while (!mProgressDone) { - Notification n = new Notification(R.drawable.icon1, null, - PROGRESS_UPDATES_WHEN + n.setWhen(PROGRESS_UPDATES_WHEN ? System.currentTimeMillis() : mActivityCreateTime); - RemoteViews v = new RemoteViews(getPackageName(), - R.layout.progress_notification); - - v.setProgressBar(R.id.progress_bar, 100, x, false); - v.setTextViewText(R.id.status_text, "Progress: " + x + "%"); - - n.contentView = v; - n.flags |= Notification.FLAG_ONGOING_EVENT; - - mNM.notify(500, n); + n.setProgress(100, x, false); + n.setContentText("Progress: " + x + "%"); + + mNM.notify(500, n.build()); x = (x + 7) % 100; try { @@ -359,11 +352,12 @@ public class NotificationTestList extends TestActivity new Test("Blue Lights") { public void run() { - Notification n = new Notification(); - n.flags |= Notification.FLAG_SHOW_LIGHTS; - n.ledARGB = 0xff0000ff; - n.ledOnMS = 1; - n.ledOffMS = 0; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon2) + .setContentTitle(name) + .setLights(0xff0000ff, 1, 0) + .setDefaults(Notification.DEFAULT_LIGHTS) + .build(); mNM.notify(1, n); } }, @@ -371,11 +365,12 @@ public class NotificationTestList extends TestActivity new Test("Red Lights") { public void run() { - Notification n = new Notification(); - n.flags |= Notification.FLAG_SHOW_LIGHTS; - n.ledARGB = 0xffff0000; - n.ledOnMS = 1; - n.ledOffMS = 0; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon2) + .setContentTitle(name) + .setLights(0xffff0000, 1, 0) + .setDefaults(Notification.DEFAULT_LIGHTS) + .build(); mNM.notify(1, n); } }, @@ -383,11 +378,12 @@ public class NotificationTestList extends TestActivity new Test("Yellow Lights") { public void run() { - Notification n = new Notification(); - n.flags |= Notification.FLAG_SHOW_LIGHTS; - n.ledARGB = 0xffffff00; - n.ledOnMS = 1; - n.ledOffMS = 0; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon2) + .setContentTitle(name) + .setLights(0xffffff00, 1, 0) + .setDefaults(Notification.DEFAULT_LIGHTS) + .build(); mNM.notify(1, n); } }, @@ -395,11 +391,12 @@ public class NotificationTestList extends TestActivity new Test("Lights off") { public void run() { - Notification n = new Notification(); - n.flags |= Notification.FLAG_SHOW_LIGHTS; - n.ledARGB = 0x00000000; - n.ledOnMS = 0; - n.ledOffMS = 0; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon2) + .setContentTitle(name) + .setLights(0x00000000, 0, 0) + .setDefaults(Notification.DEFAULT_LIGHTS) + .build(); mNM.notify(1, n); } }, @@ -407,11 +404,12 @@ public class NotificationTestList extends TestActivity new Test("Blue Blinking Slow") { public void run() { - Notification n = new Notification(); - n.flags |= Notification.FLAG_SHOW_LIGHTS; - n.ledARGB = 0xff0000ff; - n.ledOnMS = 1300; - n.ledOffMS = 1300; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon2) + .setContentTitle(name) + .setLights(0xff0000ff, 1300, 1300) + .setDefaults(Notification.DEFAULT_LIGHTS) + .build(); mNM.notify(1, n); } }, @@ -419,11 +417,12 @@ public class NotificationTestList extends TestActivity new Test("Blue Blinking Fast") { public void run() { - Notification n = new Notification(); - n.flags |= Notification.FLAG_SHOW_LIGHTS; - n.ledARGB = 0xff0000ff; - n.ledOnMS = 300; - n.ledOffMS = 300; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon2) + .setContentTitle(name) + .setLights(0xff0000ff, 300, 300) + .setDefaults(Notification.DEFAULT_LIGHTS) + .build(); mNM.notify(1, n); } }, @@ -431,8 +430,11 @@ public class NotificationTestList extends TestActivity new Test("Default All") { public void run() { - Notification n = new Notification(); - n.defaults |= Notification.DEFAULT_ALL; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon2) + .setContentTitle(name) + .setDefaults(Notification.DEFAULT_ALL) + .build(); mNM.notify(1, n); } }, @@ -440,20 +442,12 @@ public class NotificationTestList extends TestActivity new Test("Default All, once") { public void run() { - Notification n = new Notification(); - n.defaults |= Notification.DEFAULT_ALL; - n.flags |= Notification.FLAG_ONLY_ALERT_ONCE ; - mNM.notify(1, n); - } - }, - - new Test("Content Sound") { - public void run() - { - Notification n = new Notification(); - n.sound = Uri.parse( - "content://media/internal/audio/media/7"); - + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon2) + .setContentTitle(name) + .setOnlyAlertOnce(true) + .setDefaults(Notification.DEFAULT_ALL) + .build(); mNM.notify(1, n); } }, @@ -461,10 +455,12 @@ public class NotificationTestList extends TestActivity new Test("Resource Sound") { public void run() { - Notification n = new Notification(); - n.sound = Uri.parse( - ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + - getPackageName() + "/raw/ringer"); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.stat_sys_phone) + .setContentTitle(name) + .setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + + getPackageName() + "/raw/ringer")) + .build(); Log.d(TAG, "n.sound=" + n.sound); mNM.notify(1, n); @@ -474,9 +470,13 @@ public class NotificationTestList extends TestActivity new Test("Sound and Cancel") { public void run() { - Notification n = new Notification(); - n.sound = Uri.parse( - "content://media/internal/audio/media/7"); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.stat_sys_phone) + .setContentTitle(name) + .setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + + getPackageName() + "/raw/ringer")) + .build(); + Log.d(TAG, "n.sound=" + n.sound); mNM.notify(1, n); SystemClock.sleep(200); @@ -487,8 +487,11 @@ public class NotificationTestList extends TestActivity new Test("Vibrate") { public void run() { - Notification n = new Notification(); - n.vibrate = new long[] { 0, 700, 500, 1000 }; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.stat_sys_phone) + .setContentTitle(name) + .setVibrate(new long[]{0, 700, 500, 1000}) + .build(); mNM.notify(1, n); } @@ -497,8 +500,11 @@ public class NotificationTestList extends TestActivity new Test("Vibrate and cancel") { public void run() { - Notification n = new Notification(); - n.vibrate = new long[] { 0, 700, 500, 1000 }; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.stat_sys_phone) + .setContentTitle(name) + .setVibrate(new long[]{0, 700, 500, 1000}) + .build(); mNM.notify(1, n); SystemClock.sleep(500); @@ -566,10 +572,13 @@ public class NotificationTestList extends TestActivity new Test("Persistent #1") { public void run() { - Notification n = new Notification(R.drawable.icon1, "tick tick tick", - mActivityCreateTime); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #1", - "This is a notification!!!", makeIntent()); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setWhen(mActivityCreateTime) + .setContentTitle(name) + .setContentText("This is a notification!!!") + .setContentIntent(makeIntent()) + .build(); mNM.notify(1, n); } }, @@ -578,18 +587,19 @@ public class NotificationTestList extends TestActivity public void run() { mHandler.postDelayed(new Runnable() { public void run() { - Notification n = new Notification(R.drawable.icon1, - " " + String message = " " + "tick tock tick tock\n\nSometimes notifications can " + "be really long and wrap to more than one line.\n" + "Sometimes." + "Ohandwhathappensifwehaveonereallylongstringarewesure" - + "thatwesegmentitcorrectly?\n", - System.currentTimeMillis()); - n.setLatestEventInfo(NotificationTestList.this, - "Still Persistent #1", - "This is still a notification!!!", - makeIntent()); + + "thatwesegmentitcorrectly?\n"; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setContentTitle(name) + .setContentText("This is still a notification!!!") + .setContentIntent(makeIntent()) + .setStyle(new Notification.BigTextStyle().bigText(message)) + .build(); mNM.notify(1, n); } }, 3000); @@ -598,54 +608,67 @@ public class NotificationTestList extends TestActivity new Test("Persistent #2") { public void run() { - Notification n = new Notification(R.drawable.icon2, "tock tock tock", - System.currentTimeMillis()); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #2", - "Notify me!!!", makeIntent()); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setWhen(mActivityCreateTime) + .setContentTitle(name) + .setContentText("This is a notification!!!") + .setContentIntent(makeIntent()) + .build(); mNM.notify(2, n); } }, new Test("Persistent #3") { public void run() { - Notification n = new Notification(R.drawable.icon2, "tock tock tock\nmooooo", - System.currentTimeMillis()); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #3", - "Notify me!!!", makeIntent()); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setWhen(mActivityCreateTime) + .setContentTitle(name) + .setContentText("This is a notification!!!") + .setContentIntent(makeIntent()) + .build(); mNM.notify(3, n); } }, new Test("Persistent #2 Vibrate") { public void run() { - Notification n = new Notification(R.drawable.icon2, "tock tock tock", - System.currentTimeMillis()); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #2", - "Notify me!!!", makeIntent()); - n.defaults = Notification.DEFAULT_VIBRATE; + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setWhen(mActivityCreateTime) + .setContentTitle(name) + .setContentText("This is a notification!!!") + .setContentIntent(makeIntent()) + .setDefaults(Notification.DEFAULT_VIBRATE) + .build(); mNM.notify(2, n); } }, new Test("Persistent #1 - different icon") { public void run() { - Notification n = new Notification(R.drawable.icon2, null, - mActivityCreateTime); - n.setLatestEventInfo(NotificationTestList.this, "Persistent #1", - "This is the same notification!!!", makeIntent()); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon2) + .setWhen(mActivityCreateTime) + .setContentTitle(name) + .setContentText("This is a notification!!!") + .setContentIntent(makeIntent()) + .build(); mNM.notify(1, n); } }, new Test("Chronometer Start") { public void run() { - Notification n = new Notification(R.drawable.icon2, "me me me me", - System.currentTimeMillis()); - n.contentView = new RemoteViews(getPackageName(), R.layout.chrono_notification); - mChronometerBase = SystemClock.elapsedRealtime(); - n.contentView.setChronometer(R.id.time, mChronometerBase, "Yay! (%s)", true); - n.flags |= Notification.FLAG_ONGOING_EVENT; - n.contentIntent = makeIntent(); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setWhen(System.currentTimeMillis()) + .setContentTitle(name) + .setContentIntent(makeIntent()) + .setOngoing(true) + .setUsesChronometer(true) + .build(); mNM.notify(2, n); } }, @@ -655,12 +678,12 @@ public class NotificationTestList extends TestActivity mHandler.postDelayed(new Runnable() { public void run() { Log.d(TAG, "Chronometer Stop"); - Notification n = new Notification(); - n.icon = R.drawable.icon1; - n.contentView = new RemoteViews(getPackageName(), - R.layout.chrono_notification); - n.contentView.setChronometer(R.id.time, mChronometerBase, null, false); - n.contentIntent = makeIntent(); + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.icon1) + .setWhen(System.currentTimeMillis()) + .setContentTitle(name) + .setContentIntent(makeIntent()) + .build(); mNM.notify(2, n); } }, 3000); @@ -669,29 +692,29 @@ public class NotificationTestList extends TestActivity new Test("Sequential Persistent") { public void run() { - mNM.notify(1, notificationWithNumbers(1)); - mNM.notify(2, notificationWithNumbers(2)); + mNM.notify(1, notificationWithNumbers(name, 1)); + mNM.notify(2, notificationWithNumbers(name, 2)); } }, new Test("Replace Persistent") { public void run() { - mNM.notify(1, notificationWithNumbers(1)); - mNM.notify(1, notificationWithNumbers(1)); + mNM.notify(1, notificationWithNumbers(name, 1)); + mNM.notify(1, notificationWithNumbers(name, 1)); } }, new Test("Run and Cancel (n=1)") { public void run() { - mNM.notify(1, notificationWithNumbers(1)); + mNM.notify(1, notificationWithNumbers(name, 1)); mNM.cancel(1); } }, new Test("Run an Cancel (n=2)") { public void run() { - mNM.notify(1, notificationWithNumbers(1)); - mNM.notify(2, notificationWithNumbers(2)); + mNM.notify(1, notificationWithNumbers(name, 1)); + mNM.notify(2, notificationWithNumbers(name, 2)); mNM.cancel(2); } }, @@ -701,8 +724,8 @@ public class NotificationTestList extends TestActivity public void run() { for (int i = 0; i < 10; i++) { Log.d(TAG, "Add two notifications"); - mNM.notify(1, notificationWithNumbers(1)); - mNM.notify(2, notificationWithNumbers(2)); + mNM.notify(1, notificationWithNumbers(name, 1)); + mNM.notify(2, notificationWithNumbers(name, 2)); Log.d(TAG, "Cancel two notifications"); mNM.cancel(1); mNM.cancel(2); @@ -712,29 +735,14 @@ public class NotificationTestList extends TestActivity new Test("Ten Notifications") { public void run() { - for (int i = 0; i < 2; i++) { - Notification n = new Notification( - kNumberedIconResIDs[i], - null, System.currentTimeMillis()); - n.number = i; - n.setLatestEventInfo( - NotificationTestList.this, - "Persistent #" + i, - "Notify me!!!" + i, - null); - n.flags |= Notification.FLAG_ONGOING_EVENT; - mNM.notify((i+1)*10, n); - } - for (int i = 2; i < 10; i++) { - Notification n = new Notification( - kNumberedIconResIDs[i], - null, System.currentTimeMillis()); - n.number = i; - n.setLatestEventInfo( - NotificationTestList.this, - "Persistent #" + i, - "Notify me!!!" + i, - null); + for (int i = 0; i < 10; i++) { + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(kNumberedIconResIDs[i]) + .setContentTitle("Persistent #" + i) + .setContentText("Notify me!!!" + i) + .setOngoing(i < 2) + .setNumber(i) + .build(); mNM.notify((i+1)*10, n); } } @@ -757,25 +765,25 @@ public class NotificationTestList extends TestActivity new Test("Persistent with numbers 1") { public void run() { - mNM.notify(1, notificationWithNumbers(1)); + mNM.notify(1, notificationWithNumbers(name, 1)); } }, new Test("Persistent with numbers 22") { public void run() { - mNM.notify(1, notificationWithNumbers(22)); + mNM.notify(1, notificationWithNumbers(name, 22)); } }, new Test("Persistent with numbers 333") { public void run() { - mNM.notify(1, notificationWithNumbers(333)); + mNM.notify(1, notificationWithNumbers(name, 333)); } }, new Test("Persistent with numbers 4444") { public void run() { - mNM.notify(1, notificationWithNumbers(4444)); + mNM.notify(1, notificationWithNumbers(name, 4444)); } }, @@ -786,7 +794,7 @@ public class NotificationTestList extends TestActivity .setContentTitle("High priority") .setContentText("This should appear before all others") .setPriority(Notification.PRIORITY_HIGH) - .getNotification(); + .build(); int[] idOut = new int[1]; try { @@ -812,7 +820,7 @@ public class NotificationTestList extends TestActivity .setContentTitle("MAX priority") .setContentText("This might appear as an intruder alert") .setPriority(Notification.PRIORITY_MAX) - .getNotification(); + .build(); int[] idOut = new int[1]; try { @@ -838,7 +846,7 @@ public class NotificationTestList extends TestActivity .setContentTitle("MIN priority") .setContentText("You should not see this") .setPriority(Notification.PRIORITY_MIN) - .getNotification(); + .build(); int[] idOut = new int[1]; try { @@ -875,16 +883,15 @@ public class NotificationTestList extends TestActivity }; - private Notification notificationWithNumbers(int num) { - Notification n = new Notification(this, - (num >= 0 && num < kNumberedIconResIDs.length) - ? kNumberedIconResIDs[num] - : kUnnumberedIconResID, - null, - System.currentTimeMillis(), - "Notification", "Number=" + num, - null); - n.number = num; + private Notification notificationWithNumbers(String name, int num) { + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon((num >= 0 && num < kNumberedIconResIDs.length) + ? kNumberedIconResIDs[num] + : kUnnumberedIconResID) + .setContentTitle(name) + .setContentText("Number=" + num) + .setNumber(num) + .build(); return n; } @@ -932,9 +939,12 @@ public class NotificationTestList extends TestActivity } void timeNotification(int n, String label, long time) { - mNM.notify(n, new Notification(NotificationTestList.this, - R.drawable.ic_statusbar_missedcall, null, - time, label, "" + new java.util.Date(time), null)); + mNM.notify(n, new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.ic_statusbar_missedcall) + .setWhen(time) + .setContentTitle(label) + .setContentText(new java.util.Date(time).toString()) + .build()); } diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java index 50f98b8..cd04c2e 100644 --- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java +++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java @@ -153,25 +153,24 @@ public class StatusBarTest extends TestActivity }, new Test("Priority notification") { public void run() { - Notification not = new Notification(); - not.icon = R.drawable.stat_sys_phone; - not.when = System.currentTimeMillis()-(1000*60*60*24); - not.setLatestEventInfo(StatusBarTest.this, - "Incoming call", - "from: Imperious Leader", - null - ); - not.flags |= Notification.FLAG_HIGH_PRIORITY; Intent fullScreenIntent = new Intent(StatusBarTest.this, TestAlertActivity.class); int id = (int)System.currentTimeMillis(); // XXX HAX fullScreenIntent.putExtra("id", id); - not.fullScreenIntent = PendingIntent.getActivity( + PendingIntent pi = PendingIntent.getActivity( StatusBarTest.this, 0, fullScreenIntent, PendingIntent.FLAG_CANCEL_CURRENT); - // if you tap on it you should get the original alert box - not.contentIntent = not.fullScreenIntent; + Notification not = new Notification.Builder(StatusBarTest.this) + .setSmallIcon(R.drawable.stat_sys_phone) + .setWhen(System.currentTimeMillis() - (1000 * 60 * 60 * 24)) + .setContentTitle("Incoming call") + .setContentText("from: Imperious Leader") + .setContentIntent(pi) + .setFullScreenIntent(pi, true) + .setPriority(Notification.PRIORITY_HIGH) + .build(); + mNotificationManager.notify(id, not); } }, diff --git a/tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java b/tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java index 20648a4..06fbcdc 100644 --- a/tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java +++ b/tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java @@ -19,8 +19,10 @@ package com.android.speech.tts; import android.speech.tts.SynthesisCallback; import android.speech.tts.SynthesisRequest; import android.speech.tts.TextToSpeechService; +import android.util.Log; import java.util.ArrayList; +import java.util.logging.Logger; public class MockableTextToSpeechService extends TextToSpeechService { diff --git a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java index 78d4f96..faf6827 100644 --- a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java +++ b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java @@ -43,11 +43,18 @@ public class TextToSpeechTests extends InstrumentationTestCase { IDelegate passThrough = LittleMock.mock(IDelegate.class); MockableTextToSpeechService.setMocker(passThrough); + // For the default voice selection + LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(passThrough) + .onIsLanguageAvailable( + LittleMock.anyString(), LittleMock.anyString(), LittleMock.anyString()); + LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(passThrough) + .onLoadLanguage( + LittleMock.anyString(), LittleMock.anyString(), LittleMock.anyString()); + blockingInitAndVerify(MOCK_ENGINE, TextToSpeech.SUCCESS); assertEquals(MOCK_ENGINE, mTts.getCurrentEngine()); } - @Override public void tearDown() { if (mTts != null) { @@ -77,7 +84,7 @@ public class TextToSpeechTests extends InstrumentationTestCase { assertEquals(TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE, mTts.setLanguage(new Locale("eng", "USA", "variant"))); LittleMock.verify(delegate, LittleMock.anyTimes()).onIsLanguageAvailable( "eng", "USA", "variant"); - LittleMock.verify(delegate, LittleMock.times(1)).onLoadLanguage( + LittleMock.verify(delegate, LittleMock.anyTimes()).onLoadLanguage( "eng", "USA", "variant"); } @@ -147,26 +154,34 @@ public class TextToSpeechTests extends InstrumentationTestCase { public void testDefaultLanguage_setsVoiceName() throws Exception { IDelegate delegate = LittleMock.mock(IDelegate.class); MockableTextToSpeechService.setMocker(delegate); + Locale defaultLocale = Locale.getDefault(); // --------------------------------------------------------- // Test that default language also sets the default voice // name - LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onIsLanguageAvailable( - LittleMock.anyString(), LittleMock.anyString(), LittleMock.anyString()); - LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onLoadLanguage( - LittleMock.anyString(), LittleMock.anyString(), LittleMock.anyString()); + LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE). + when(delegate).onIsLanguageAvailable( + defaultLocale.getISO3Language(), + defaultLocale.getISO3Country().toUpperCase(), + defaultLocale.getVariant()); + LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE). + when(delegate).onLoadLanguage( + defaultLocale.getISO3Language(), + defaultLocale.getISO3Country(), + defaultLocale.getVariant()); + blockingCallSpeak("foo bar", delegate); ArgumentCaptor<SynthesisRequest> req = LittleMock.createCaptor(); LittleMock.verify(delegate, LittleMock.times(1)).onSynthesizeText(req.capture(), LittleMock.<SynthesisCallback>anyObject()); - Locale defaultLocale = Locale.getDefault(); assertEquals(defaultLocale.getISO3Language(), req.getValue().getLanguage()); assertEquals(defaultLocale.getISO3Country(), req.getValue().getCountry()); assertEquals("", req.getValue().getVariant()); assertEquals(defaultLocale.toLanguageTag(), req.getValue().getVoiceName()); } + private void blockingCallSpeak(String speech, IDelegate mock) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); diff --git a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java index d9a3b61..05cac10 100644 --- a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java +++ b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java @@ -28,8 +28,6 @@ import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; -import java.util.ArrayList; - public class UsageLogActivity extends ListActivity implements Runnable { private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 14; @@ -166,6 +164,9 @@ public class UsageLogActivity extends ListActivity implements Runnable { case UsageEvents.Event.CONFIGURATION_CHANGE: return "Config change"; + case UsageEvents.Event.USER_INTERACTION: + return "User Interaction"; + default: return "Unknown: " + eventType; } diff --git a/tests/VectorDrawableTest/AndroidManifest.xml b/tests/VectorDrawableTest/AndroidManifest.xml index 991ec57..e648897 100644 --- a/tests/VectorDrawableTest/AndroidManifest.xml +++ b/tests/VectorDrawableTest/AndroidManifest.xml @@ -144,6 +144,15 @@ </intent-filter> </activity> <activity + android:name="AnimatedVectorDrawableAttr" + android:label="AnimatedVectorDrawable Attr Test" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="com.android.test.dynamic.TEST" /> + </intent-filter> + </activity> + <activity android:name="BoundsCheckTest" android:label="SetBound check" > <intent-filter> @@ -154,4 +163,4 @@ </activity> </application> -</manifest>
\ No newline at end of file +</manifest> diff --git a/tests/VectorDrawableTest/res/anim/animation_favorite.xml b/tests/VectorDrawableTest/res/anim/animation_favorite.xml index 2e2d9bb..13bd6f5 100644 --- a/tests/VectorDrawableTest/res/anim/animation_favorite.xml +++ b/tests/VectorDrawableTest/res/anim/animation_favorite.xml @@ -45,12 +45,6 @@ android:valueTo="#FF00FF00" /> <objectAnimator android:duration="8000" - android:propertyName="strokeWidth" - android:repeatCount="-1" - android:valueFrom="5" - android:valueTo="20" /> - <objectAnimator - android:duration="8000" android:propertyName="fillColor" android:repeatCount="-1" android:valueFrom="#FFFF0000" diff --git a/tests/VectorDrawableTest/res/anim/blink.xml b/tests/VectorDrawableTest/res/anim/blink.xml new file mode 100644 index 0000000..714f491 --- /dev/null +++ b/tests/VectorDrawableTest/res/anim/blink.xml @@ -0,0 +1,28 @@ +<!-- + Copyright (C) 2015 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. +--> +<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:anim/linear_interpolator" + android:duration="@android:integer/config_longAnimTime" + android:repeatCount="-1" + android:repeatMode="reverse" > + + <propertyValuesHolder + android:propertyName="fillColor" + android:valueType="colorType" + android:valueFrom="?attr/color1" + android:valueTo="@android:color/white" /> + +</objectAnimator> diff --git a/tests/VectorDrawableTest/res/drawable/animated_vector_drawable_attr_icon.xml b/tests/VectorDrawableTest/res/drawable/animated_vector_drawable_attr_icon.xml new file mode 100644 index 0000000..10a0970 --- /dev/null +++ b/tests/VectorDrawableTest/res/drawable/animated_vector_drawable_attr_icon.xml @@ -0,0 +1,93 @@ +<!-- +Copyright (C) 2015 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="250dp" + android:height="250dp" + android:viewportWidth="200" + android:viewportHeight="200"> + + <path + android:pathData="M-3.476563,-21.275826l34.441406,18.748753 0.000000,37.497501 -34.441406,18.748756 -34.441406,-18.718758 0.000000,-37.527500z" + android:strokeWidth="2.5" + android:fillColor="@color/color0" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M65.5,-21.497507l34.441406,18.748756 0.000000,37.497498 -34.441406,18.748756 -34.441406,-18.718754 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color0" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M202.75,-21.497507l34.441406,18.748756 0.000000,37.497498 -34.441406,18.748760 -34.441406,-18.718758 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color0" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M134.125,-21.497505l34.441406,18.748756 0.000000,37.497498 -34.441406,18.748756 -34.441406,-18.718758 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color0" + android:strokeColor="@android:color/white"/> + <path + android:name="hex" + android:pathData="M99.8125,34.752495l34.441406,18.748753 0.000000,37.497501 -34.441406,18.748749 -34.441406,-18.718750 0.000000,-37.527500z" + android:strokeWidth="2.5" + android:fillColor="?attr/color1" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M30.6875,34.689995l34.441406,18.748756 0.000000,37.497498 -34.441406,18.748749 -34.441406,-18.718750 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color0" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M168.3125,35.002495l34.441406,18.748756 0.000000,37.497498 -34.441406,18.748749 -34.441406,-18.718750 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color0" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M203.0,91.002495l34.441406,18.748756 0.000000,37.497498 -34.441406,18.748749 -34.441406,-18.718750 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color0" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M133.8125,91.314995l34.441406,18.748756 0.000000,37.497498 -34.441406,18.748749 -34.441406,-18.718750 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color3" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M65.0625,91.127495l34.441406,18.748756 0.000000,37.497498 -34.441406,18.748749 -34.441406,-18.718750 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color2" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M-3.25,91.189995l34.441406,18.748756 0.000000,37.497498 -34.441406,18.748749 -34.441406,-18.718750 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color0" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M31.0625,147.81499l34.441406,18.748764 0.000000,37.497498 -34.441406,18.748749 -34.441406,-18.718750 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color0" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M99.625,147.37749l34.441406,18.748764 0.000000,37.497498 -34.441406,18.748749 -34.441406,-18.718750 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color0" + android:strokeColor="@android:color/white"/> + <path + android:pathData="M168.8125,147.50249l34.441406,18.748764 0.000000,37.497498 -34.441406,18.748749 -34.441406,-18.718750 0.000000,-37.527496z" + android:strokeWidth="2.5" + android:fillColor="@color/color0" + android:strokeColor="@android:color/white"/> +</vector> diff --git a/tests/VectorDrawableTest/res/drawable/animated_vector_drawable_attr_icon_animated.xml b/tests/VectorDrawableTest/res/drawable/animated_vector_drawable_attr_icon_animated.xml new file mode 100644 index 0000000..7e65229 --- /dev/null +++ b/tests/VectorDrawableTest/res/drawable/animated_vector_drawable_attr_icon_animated.xml @@ -0,0 +1,21 @@ +<!-- +Copyright (C) 2015 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. +--> +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" + android:drawable="@drawable/animated_vector_drawable_attr_icon" > + <target + android:name="hex" + android:animation="@anim/blink" /> +</animated-vector> diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml index a0b0e00..7cddda1 100644 --- a/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml @@ -14,10 +14,10 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:height="64dp" - android:width="64dp" - android:viewportHeight="12.25" - android:viewportWidth="7.30625" > + android:height="64dp" + android:viewportHeight="12.25" + android:viewportWidth="7.30625" + android:width="64dp" > <group android:pivotX="3.65" @@ -31,14 +31,18 @@ l 0, 12.25 l-7.3, 0 z" /> - </group> - <group> - <path - android:name="one" - android:fillColor="#ff88ff" - android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125 + + <group + android:pivotX="3.65" + android:pivotY="6.125" + android:rotation="30" > + <path + android:name="one" + android:fillColor="#ff88ff" + android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125 l 2.09375-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0 l-5.046875,0.0 0.0-1.0Z" /> + </group> </group> <group android:pivotX="3.65" @@ -52,12 +56,15 @@ l 0, 6.125 l-7.3, 0 z" /> - </group> - <group> - <path - android:name="two" - android:fillColor="#ff88ff" - android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375 + + <group + android:pivotX="3.65" + android:pivotY="6.125" + android:rotation="30" > + <path + android:name="two" + android:fillColor="#ff88ff" + android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375 q 1.1718752-1.1875 1.4687502-1.53125 0.578125-0.625 0.796875-1.0625 q 0.234375-0.453125 0.234375-0.875 0.0-0.703125-0.5-1.140625 q-0.484375-0.4375-1.2656252-0.4375-0.5625,0.0-1.1875,0.1875 @@ -66,6 +73,7 @@ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125-0.203125,1.015625 q-0.203125,0.484375-0.734375,1.140625-0.15625,0.171875-0.9375,0.984375 q-0.78125024,0.8125-2.2187502,2.265625Z" /> + </group> </group> </vector>
\ No newline at end of file diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml index d282fc9..0f3fb95 100644 --- a/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml @@ -13,37 +13,41 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="64dp" - android:height="64dp" - android:viewportWidth="7.30625" - android:viewportHeight="12.25" - android:autoMirrored="true"> + android:autoMirrored="true" + android:height="64dp" + android:viewportHeight="12.25" + android:viewportWidth="7.30625" + android:width="64dp" > <group> <clip-path - android:name="clip1" - android:pathData=" + android:name="clip1" + android:pathData=" M 3.65, 6.125 m-.001, 0 a .001,.001 0 1,0 .002,0 - a .001,.001 0 1,0-.002,0z"/> + a .001,.001 0 1,0-.002,0z" /> + <path - android:name="one" - android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125 + android:name="one" + android:fillColor="#ff88ff" + android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125 l 2.09375-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0 - l-5.046875,0.0 0.0-1.0Z" - android:fillColor="#ff88ff"/> - + l-5.046875,0.0 0.0-1.0Z" /> + </group> + <group> <clip-path - android:name="clip2" - android:pathData=" + android:name="clip2" + android:pathData=" M 3.65, 6.125 m-6, 0 a 6,6 0 1,0 12,0 - a 6,6 0 1,0-12,0z"/> + a 6,6 0 1,0-12,0z" /> + <path - android:name="two" - android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375 + android:name="two" + android:fillColor="#ff88ff" + android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375 q 1.1718752-1.1875 1.4687502-1.53125 0.578125-0.625 0.796875-1.0625 q 0.234375-0.453125 0.234375-0.875 0.0-0.703125-0.5-1.140625 q-0.484375-0.4375-1.2656252-0.4375-0.5625,0.0-1.1875,0.1875 @@ -51,7 +55,7 @@ q 0.625-0.15625 1.140625-0.15625 1.3593752,0.0 2.1718752,0.6875 q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125-0.203125,1.015625 q-0.203125,0.484375-0.734375,1.140625-0.15625,0.171875-0.9375,0.984375 - q-0.78125024,0.8125-2.2187502,2.265625Z" - android:fillColor="#ff88ff"/> + q-0.78125024,0.8125-2.2187502,2.265625Z" /> </group> -</vector> + +</vector>
\ No newline at end of file diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml index 7be49a9..f93486e 100644 --- a/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml @@ -26,6 +26,7 @@ <path android:name="favorite" android:fillColor="#ff000000" + android:strokeWidth="2" android:pathData="M2.100006104,-6 C0.1449127197,-6,1.600006104,-5.975006104,0,-5.975006104 C-1.574996948,-5.975006104,0.00309753418,-6-1.949996948-6 diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable_scale0.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable_scale0.xml new file mode 100644 index 0000000..88bf777 --- /dev/null +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable_scale0.xml @@ -0,0 +1,57 @@ +<!-- + Copyright (C) 2015 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="64dp" + android:viewportHeight="200" + android:viewportWidth="200" + android:width="64dp" > + + <group> + <path + android:name="background1" + android:fillColor="#FF000000" + android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" /> + <path + android:name="background2" + android:fillColor="#FF000000" + android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" /> + </group> + <group + android:pivotX="0" + android:pivotY="0" + android:rotation="90" > + <group + android:scaleX="1.5" + android:scaleY="1" > + <group + android:pivotX="0" + android:pivotY="0" + android:rotation="-90" > + <group + android:scaleX="1.5" + android:scaleY="1" > + <path + android:name="twoLines" + android:fillColor="#FFFF0000" + android:pathData="M 100, 0 l 0, 100, -100, 0 z" + android:strokeColor="#FF00FF00" + android:strokeWidth="10" /> + </group> + </group> + </group> + </group> + +</vector>
\ No newline at end of file diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable_scale1.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable_scale1.xml new file mode 100644 index 0000000..530c73b --- /dev/null +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable_scale1.xml @@ -0,0 +1,52 @@ +<!-- + Copyright (C) 2015 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="64dp" + android:viewportHeight="200" + android:viewportWidth="200" + android:width="64dp" > + + <group> + <path + android:name="background1" + android:fillColor="#FF000000" + android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" /> + <path + android:name="background2" + android:fillColor="#FF000000" + android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" /> + </group> + <group + android:scaleX="-1" + android:scaleY="-1" > + <group + android:scaleX="-1" + android:scaleY="-1" > + <group + android:pivotX="100" + android:pivotY="100" + android:rotation="45" > + <path + android:name="twoLines" + android:fillColor="#FFFF0000" + android:pathData="M 100, 0 l 0, 100, -100, 0 z" + android:strokeColor="#FF00FF00" + android:strokeWidth="10" /> + </group> + </group> + </group> + +</vector>
\ No newline at end of file diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable_scale2.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable_scale2.xml new file mode 100644 index 0000000..200eb61 --- /dev/null +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable_scale2.xml @@ -0,0 +1,48 @@ +<!-- + Copyright (C) 2015 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="64dp" + android:viewportHeight="200" + android:viewportWidth="200" + android:width="64dp" > + + <group> + <path + android:name="background1" + android:fillColor="#FF000000" + android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" /> + <path + android:name="background2" + android:fillColor="#FF000000" + android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" /> + </group> + <group + android:scaleX="2" + android:scaleY="0.5" > + <group + android:pivotX="100" + android:pivotY="100" + android:rotation="45" > + <path + android:name="twoLines" + android:fillColor="#FFFF0000" + android:pathData="M 100, 0 l 0, 100, -100, 0 z" + android:strokeColor="#FF00FF00" + android:strokeWidth="10" /> + </group> + </group> + +</vector>
\ No newline at end of file diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable_scale3.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable_scale3.xml new file mode 100644 index 0000000..a40fc9c --- /dev/null +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable_scale3.xml @@ -0,0 +1,62 @@ +<!-- + Copyright (C) 2015 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="64dp" + android:viewportHeight="200" + android:viewportWidth="200" + android:width="64dp" > + + <group> + <path + android:name="background1" + android:fillColor="#FF000000" + android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" /> + <path + android:name="background2" + android:fillColor="#FF000000" + android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" /> + </group> + <group + android:pivotX="0" + android:pivotY="0" + android:rotation="45" > + <group + android:pivotX="0" + android:pivotY="0" + android:rotation="90" > + <group + android:scaleX="1.5" + android:scaleY="1" > + <group + android:pivotX="0" + android:pivotY="0" + android:rotation="-90" > + <group + android:scaleX="1.5" + android:scaleY="1" > + <path + android:name="twoLines" + android:fillColor="#FFFF0000" + android:pathData="M 100, 0 l 0, 100, -100, 0 z" + android:strokeColor="#FF00FF00" + android:strokeWidth="10" /> + </group> + </group> + </group> + </group> + </group> + +</vector>
\ No newline at end of file diff --git a/tests/VectorDrawableTest/res/layout/activity_animated_vector_drawable_attr.xml b/tests/VectorDrawableTest/res/layout/activity_animated_vector_drawable_attr.xml new file mode 100644 index 0000000..92680d5 --- /dev/null +++ b/tests/VectorDrawableTest/res/layout/activity_animated_vector_drawable_attr.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 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="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" > + + <ImageView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="50dp" + android:src="@drawable/animated_vector_drawable_attr_icon" + android:theme="@style/ColorTheme" /> + + <ImageView + android:id="@+id/avd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/animated_vector_drawable_attr_icon_animated" + android:theme="@style/ColorTheme" /> + +</LinearLayout> + diff --git a/tests/VectorDrawableTest/res/values/attrs.xml b/tests/VectorDrawableTest/res/values/attrs.xml new file mode 100644 index 0000000..98bf992 --- /dev/null +++ b/tests/VectorDrawableTest/res/values/attrs.xml @@ -0,0 +1,17 @@ +<!-- Copyright (C) 2015 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. +--> +<resources> + <attr name="color1" format="color" /> +</resources> diff --git a/tests/VectorDrawableTest/res/values/colors.xml b/tests/VectorDrawableTest/res/values/colors.xml new file mode 100644 index 0000000..6eb3036 --- /dev/null +++ b/tests/VectorDrawableTest/res/values/colors.xml @@ -0,0 +1,20 @@ +<!-- Copyright (C) 2015 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. +--> +<resources> + <color name="color0">#a6e4ea</color> + <color name="color1">#ff3838</color> + <color name="color2">#ffff51</color> + <color name="color3">#0ed300</color> +</resources> diff --git a/tests/VectorDrawableTest/res/values/styles.xml b/tests/VectorDrawableTest/res/values/styles.xml index 460c0db..8adc034 100644 --- a/tests/VectorDrawableTest/res/values/styles.xml +++ b/tests/VectorDrawableTest/res/values/styles.xml @@ -13,4 +13,7 @@ limitations under the License. --> <resources> + <style name="ColorTheme"> + <item name="color1">@color/color1</item> + </style> </resources> diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableAttr.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableAttr.java new file mode 100644 index 0000000..8de2f6b --- /dev/null +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableAttr.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 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.test.dynamic; + +import android.app.Activity; +import android.graphics.drawable.AnimatedVectorDrawable; +import android.os.Bundle; +import android.widget.ImageView; + +public class AnimatedVectorDrawableAttr extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_animated_vector_drawable_attr); + + ImageView avdIv = (ImageView) findViewById(R.id.avd); + AnimatedVectorDrawable avd = (AnimatedVectorDrawable) avdIv.getDrawable(); + avd.start(); + } +} diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java index ecc7782..087e68a 100644 --- a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java @@ -15,8 +15,11 @@ package com.android.test.dynamic; import android.app.Activity; +import android.graphics.drawable.Animatable2; import android.graphics.drawable.AnimatedVectorDrawable; +import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.GridLayout; @@ -52,6 +55,19 @@ public class AnimatedVectorDrawableTest extends Activity implements View.OnClick button.setWidth(400); button.setHeight(400); button.setBackgroundResource(icon[i]); + AnimatedVectorDrawable d = (AnimatedVectorDrawable) button.getBackground(); + d.registerAnimationCallback(new Animatable2.AnimationCallback() { + @Override + public void onAnimationStart(Drawable drawable) { + Log.v(LOGCAT, "Animator start"); + } + + @Override + public void onAnimationEnd(Drawable drawable) { + Log.v(LOGCAT, "Animator end"); + } + }); + container.addView(button); button.setOnClickListener(this); } diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/ScaleDrawableTests.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/ScaleDrawableTests.java index 3787843..c5be6c4 100644 --- a/tests/VectorDrawableTest/src/com/android/test/dynamic/ScaleDrawableTests.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/ScaleDrawableTests.java @@ -37,8 +37,8 @@ public class ScaleDrawableTests extends Activity { }; protected int icon = R.drawable.bitmap_drawable01; - protected int vector_icon = R.drawable.vector_drawable16; + protected int animated_vector_icon = R.drawable.ic_hourglass_animation; @Override protected void onCreate(Bundle savedInstanceState) { @@ -46,12 +46,12 @@ public class ScaleDrawableTests extends Activity { ScrollView scrollView = new ScrollView(this); GridLayout container = new GridLayout(this); scrollView.addView(container); - container.setColumnCount(3); + container.setColumnCount(4); container.setBackgroundColor(0xFF888888); LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - params.width = 400; - params.height = 300; + params.width = 300; + params.height = 200; for (int i = 0; i < scaleTypes.length; i++) { TextView t = new TextView(this); @@ -71,6 +71,13 @@ public class ScaleDrawableTests extends Activity { view.setScaleType(scaleType); view.setImageResource(vector_icon); container.addView(view); + + ImageView avd_view = new ImageView(this); + avd_view.setLayoutParams(params); + avd_view.setScaleType(scaleType); + avd_view.setImageResource(animated_vector_icon); + container.addView(avd_view); + } setContentView(scrollView); diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java index d029050..b4a93f6 100644 --- a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java @@ -65,6 +65,10 @@ public class VectorDrawablePerformance extends Activity { R.drawable.vector_drawable28, R.drawable.vector_drawable29, R.drawable.vector_drawable30, + R.drawable.vector_drawable_scale0, + R.drawable.vector_drawable_scale1, + R.drawable.vector_drawable_scale2, + R.drawable.vector_drawable_scale3, }; public static VectorDrawable create(Resources resources, int rid) { diff --git a/tests/VoiceInteraction/AndroidManifest.xml b/tests/VoiceInteraction/AndroidManifest.xml index 06d31a4..fe17c6e 100644 --- a/tests/VoiceInteraction/AndroidManifest.xml +++ b/tests/VoiceInteraction/AndroidManifest.xml @@ -2,6 +2,7 @@ package="com.android.test.voiceinteraction"> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> + <uses-permission android:name="android.permission.READ_LOGS" /> <application> <activity android:name="VoiceInteractionMain" android:label="Voice Interaction" @@ -12,10 +13,19 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> - <activity android:name="SettingsActivity" - android:label="Voice Interaction Settings" + <activity android:name="AssistProxyActivity" + android:label="Test Assist Proxy" + android:theme="@android:style/Theme.NoDisplay" android:excludeFromRecents="true" - android:noHistory="true"> + android:noHistory="true" + android:taskAffinity=""> + <intent-filter> + <action android:name="android.intent.action.ASSIST" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + <activity android:name="SettingsActivity" + android:label="Voice Interaction Settings"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.DEFAULT" /> @@ -44,7 +54,7 @@ <meta-data android:name="android.speech" android:resource="@xml/recognition_service" /> </service> <activity android:name="TestInteractionActivity" android:label="Voice Interaction Target" - android:theme="@android:style/Theme.Material.Light.Voice"> + android:theme="@android:style/Theme.Material.Light"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.DEFAULT" /> diff --git a/tests/VoiceInteraction/res/layout/main.xml b/tests/VoiceInteraction/res/layout/main.xml index 3d7a418..a83d02c 100644 --- a/tests/VoiceInteraction/res/layout/main.xml +++ b/tests/VoiceInteraction/res/layout/main.xml @@ -26,6 +26,27 @@ android:text="@string/start" /> + <CheckBox android:id="@+id/secure" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/secure" + /> + + <com.android.test.voiceinteraction.AsyncStructure + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="64dp" + android:text="@string/asyncStructure" + /> + + <EditText android:id="@+id/text" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:paddingTop="64dp" + android:paddingBottom="64dp" + android:text="@string/largetext" /> + </LinearLayout> diff --git a/tests/VoiceInteraction/res/layout/test_interaction.xml b/tests/VoiceInteraction/res/layout/test_interaction.xml index d55736f..277117e 100644 --- a/tests/VoiceInteraction/res/layout/test_interaction.xml +++ b/tests/VoiceInteraction/res/layout/test_interaction.xml @@ -32,21 +32,77 @@ android:layout_weight="1" android:layout_marginTop="16dp" android:textAppearance="?android:attr/textAppearanceMedium" - android:textColor="#ffffffff" /> - <Button android:id="@+id/complete" - android:layout_width="wrap_content" + <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" - android:text="@string/completeVoice" - /> + android:orientation="horizontal"> + + <Button android:id="@+id/airplane" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/launchAirplane" + /> + + </LinearLayout> + + <LinearLayout android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:orientation="horizontal"> + + <Button android:id="@+id/complete" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/completeVoice" + /> + + <Button android:id="@+id/abort" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/abortVoice" + /> - <Button android:id="@+id/abort" - android:layout_width="wrap_content" + </LinearLayout> + + <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" - android:text="@string/abortVoice" + android:orientation="horizontal"> + + <Button android:id="@+id/command" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/commandVoice" + /> + + <Button android:id="@+id/pick" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/pickVoice" + /> + + </LinearLayout> + + <LinearLayout android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:layout_marginBottom="16dp" + android:orientation="horizontal"> + + <Button android:id="@+id/cancel" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/cancelVoice" + /> + + <Button android:id="@+id/jump" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/jumpOut" /> + </LinearLayout> + </LinearLayout> diff --git a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml index 002f350..b106437 100644 --- a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml +++ b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml @@ -15,51 +15,109 @@ --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="match_parent" - android:fitsSystemWindows="true"> + android:layout_width="match_parent" + android:layout_height="match_parent"> - <FrameLayout android:layout_width="fill_parent" + <ImageView android:id="@+id/full_screenshot" + android:layout_width="match_parent" android:layout_height="match_parent" - android:padding="8dp"> + android:visibility="invisible"/> - <LinearLayout android:id="@+id/content" - android:layout_width="fill_parent" - android:layout_height="match_parent" + <com.android.test.voiceinteraction.AssistVisualizer android:id="@+id/assist_visualizer" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <FrameLayout android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="top" + android:orientation="vertical" + android:background="#ffffffff" + android:elevation="8dp" + > + <LinearLayout android:id="@+id/top_content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <ImageView android:id="@+id/screenshot" + android:layout_width="wrap_content" + android:layout_height="46dp" + android:adjustViewBounds="true" /> + <View android:layout_width="0dp" + android:layout_height="0dp" + android:layout_weight="1" /> + <CheckBox android:id="@+id/show_options" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + <Button android:id="@+id/do_tree" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/tree" /> + <Button android:id="@+id/do_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/text" /> + <Button android:id="@+id/start" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/start" /> + </LinearLayout> + <LinearLayout android:id="@+id/options" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + > + <CheckBox android:id="@+id/disallow_structure" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Disallow context" /> + <CheckBox android:id="@+id/disallow_screenshot" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Disallow screenshot" /> + <TextView android:id="@+id/options_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:layout_marginBottom="16dp" + android:textAppearance="?android:attr/textAppearanceMedium" /> + </LinearLayout> + </LinearLayout> + + <LinearLayout android:id="@+id/bottom_content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" android:orientation="vertical" android:background="#ffffffff" android:elevation="8dp" > <TextView android:id="@+id/text" - android:layout_width="fill_parent" + android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" - android:textAppearance="?android:attr/textAppearanceMedium" - /> + android:textAppearance="?android:attr/textAppearanceMedium" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> - <Button android:id="@+id/start" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/start" - /> <Button android:id="@+id/confirm" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/confirm" - /> + android:text="@string/confirm" /> <Button android:id="@+id/complete" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/complete" - /> + android:text="@string/complete" /> <Button android:id="@+id/abort" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/abort" - /> + android:text="@string/abort" /> </LinearLayout> </LinearLayout> diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml index 7eec90c..c665c23 100644 --- a/tests/VoiceInteraction/res/values/strings.xml +++ b/tests/VoiceInteraction/res/values/strings.xml @@ -17,11 +17,248 @@ <resources> <string name="start">Start</string> + <string name="secure">Secure</string> + <string name="tree">Tree</string> + <string name="text">Text</string> + <string name="asyncStructure">(Async structure goes here)</string> + <string name="launchAirplane">Launch airplane mode</string> <string name="confirm">Confirm</string> <string name="abort">Abort</string> <string name="complete">Complete</string> <string name="abortVoice">Abort Voice</string> + <string name="commandVoice">Command</string> <string name="completeVoice">Complete Voice</string> + <string name="pickVoice">Pick Voice</string> + <string name="cancelVoice">Cancel</string> + <string name="jumpOut">Jump out</string> + <string name="largetext">This is a bunch of text that we will use to show how we handle it +when reporting it for assist data. We need many many lines of text, like\n +this\n +and\n +this other\n +one\n +two\n +three\n +four\n +five\n +six\n +seven\n +eight\n +nine\n +ten\n +eleven\n +twelve\n +thirteen\n +fourteen\n +fifteen\n +sixteen\n +seventeen\n +eighteen\n +nineteen\n +twenty\n +<big><big><big>So shaken as we are, so wan with care,\n +Find we a time for frighted peace to pant,\n</big> +And breathe short-winded accents of new broils\n +To be commenced in strands afar remote.\n</big> +No more the thirsty entrance of this soil\n +Shall daub her lips with her own children\'s blood;\n</big> +<b>Nor more shall trenching war channel her fields,\n +Nor bruise her flowerets with the armed hoofs\n</b> +<i>Of hostile paces: those opposed eyes,\n +Which, like the meteors of a troubled heaven,\n</i> +All of one nature, of one substance bred,\n +Did lately meet in the intestine shock\n +And furious close of civil butchery\n +Shall now, in mutual well-beseeming ranks,\n +March all one way and be no more opposed\n +Against acquaintance, kindred and allies:\n +The edge of war, like an ill-sheathed knife,\n +No more shall cut his master. Therefore, friends,\n +As far as to the sepulchre of Christ,\n +Whose soldier now, under whose blessed cross\n +We are impressed and engaged to fight,\n +Forthwith a power of English shall we levy;\n +Whose arms were moulded in their mothers\' womb\n +To chase these pagans in those holy fields\n +Over whose acres walk\'d those blessed feet\n +Which fourteen hundred years ago were nail\'d\n +For our advantage on the bitter cross.\n +But this our purpose now is twelve month old,\n +And bootless \'tis to tell you we will go:\n +Therefore we meet not now. Then let me hear\n +Of you, my gentle cousin Westmoreland,\n +What yesternight our council did decree\n +In forwarding this dear expedience.\n +\n +Hear him but reason in divinity,\n +And all-admiring with an inward wish\n +You would desire the king were made a prelate:\n +Hear him debate of commonwealth affairs,\n +You would say it hath been all in all his study:\n +List his discourse of war, and you shall hear\n +A fearful battle render\'d you in music:\n +Turn him to any cause of policy,\n +The Gordian knot of it he will unloose,\n +Familiar as his garter: that, when he speaks,\n +The air, a charter\'d libertine, is still,\n +And the mute wonder lurketh in men\'s ears,\n +To steal his sweet and honey\'d sentences;\n +So that the art and practic part of life\n +Must be the mistress to this theoric:\n +Which is a wonder how his grace should glean it,\n +Since his addiction was to courses vain,\n +His companies unletter\'d, rude and shallow,\n +His hours fill\'d up with riots, banquets, sports,\n +And never noted in him any study,\n +Any retirement, any sequestration\n +From open haunts and popularity.\n +\n +I come no more to make you laugh: things now,\n +That bear a weighty and a serious brow,\n +Sad, high, and working, full of state and woe,\n +Such noble scenes as draw the eye to flow,\n +e now present. Those that can pity, here\n +May, if they think it well, let fall a tear;\n +The subject will deserve it. Such as give\n +Their money out of hope they may believe,\n +May here find truth too. Those that come to see\n +Only a show or two, and so agree\n +The play may pass, if they be still and willing,\n +I\'ll undertake may see away their shilling\n +Richly in two short hours. Only they\n +That come to hear a merry bawdy play,\n +A noise of targets, or to see a fellow\n +In a long motley coat guarded with yellow,\n +Will be deceived; for, gentle hearers, know,\n +To rank our chosen truth with such a show\n +As fool and fight is, beside forfeiting\n +Our own brains, and the opinion that we bring,\n +To make that only true we now intend,\n +Will leave us never an understanding friend.\n +Therefore, for goodness\' sake, and as you are known\n +The first and happiest hearers of the town,\n +Be sad, as we would make ye: think ye see\n +The very persons of our noble story\n +As they were living; think you see them great,\n +And follow\'d with the general throng and sweat\n +Of thousand friends; then in a moment, see\n +How soon this mightiness meets misery:\n +And, if you can be merry then, I\'ll say\n +A man may weep upon his wedding-day.\n +\n +<big>First, heaven be the record to my speech!\n +In the devotion of a subject\'s love,\n</big> +<b>Tendering the precious safety of my prince,\n +And free from other misbegotten hate,\n</b> +Come I appellant to this princely presence.\n +Now, Thomas Mowbray, do I turn to thee,\n +And mark my greeting well; for what I speak\n +My body shall make good upon this earth,\n +Or my divine soul answer it in heaven.\n +Thou art a traitor and a miscreant,\n +Too good to be so and too bad to live,\n +Since the more fair and crystal is the sky,\n +The uglier seem the clouds that in it fly.\n +Once more, the more to aggravate the note,\n +With a foul traitor\'s name stuff I thy throat;\n +And wish, so please my sovereign, ere I move,\n +What my tongue speaks my right drawn sword may prove.\n +\n +Now is the winter of our discontent\n +Made glorious summer by this sun of York;\n +And all the clouds that lour\'d upon our house\n +In the deep bosom of the ocean buried.\n +Now are our brows bound with victorious wreaths;\n +Our bruised arms hung up for monuments;\n +Our stern alarums changed to merry meetings,\n +Our dreadful marches to delightful measures.\n +Grim-visaged war hath smooth\'d his wrinkled front;\n +And now, instead of mounting barded steeds\n +To fright the souls of fearful adversaries,\n +He capers nimbly in a lady\'s chamber\n +To the lascivious pleasing of a lute.\n +But I, that am not shaped for sportive tricks,\n +Nor made to court an amorous looking-glass;\n +I, that am rudely stamp\'d, and want love\'s majesty\n +To strut before a wanton ambling nymph;\n +I, that am curtail\'d of this fair proportion,\n +Cheated of feature by dissembling nature,\n +Deformed, unfinish\'d, sent before my time\n +Into this breathing world, scarce half made up,\n +And that so lamely and unfashionable\n +That dogs bark at me as I halt by them;\n +Why, I, in this weak piping time of peace,\n +Have no delight to pass away the time,\n +Unless to spy my shadow in the sun\n +And descant on mine own deformity:\n +And therefore, since I cannot prove a lover,\n +To entertain these fair well-spoken days,\n +I am determined to prove a villain\n +And hate the idle pleasures of these days.\n +Plots have I laid, inductions dangerous,\n +By drunken prophecies, libels and dreams,\n +To set my brother Clarence and the king\n +In deadly hate the one against the other:\n +And if King Edward be as true and just\n +As I am subtle, false and treacherous,\n +This day should Clarence closely be mew\'d up,\n +About a prophecy, which says that \'G\'\n +Of Edward\'s heirs the murderer shall be.\n +Dive, thoughts, down to my soul: here\n +Clarence comes.\n +\n +To bait fish withal: if it will feed nothing else,\n +it will feed my revenge. He hath disgraced me, and\n +hindered me half a million; laughed at my losses,\n +mocked at my gains, scorned my nation, thwarted my\n +bargains, cooled my friends, heated mine\n +enemies; and what\'s his reason? I am a Jew. Hath\n +not a Jew eyes? hath not a Jew hands, organs,\n +dimensions, senses, affections, passions? fed with\n +the same food, hurt with the same weapons, subject\n +to the same diseases, healed by the same means,\n +warmed and cooled by the same winter and summer, as\n +a Christian is? If you prick us, do we not bleed?\n +if you tickle us, do we not laugh? if you poison\n +us, do we not die? and if you wrong us, shall we not\n +revenge? If we are like you in the rest, we will\n +resemble you in that. If a Jew wrong a Christian,\n +what is his humility? Revenge. If a Christian\n +wrong a Jew, what should his sufferance be by\n +Christian example? Why, revenge. The villany you\n +teach me, I will execute, and it shall go hard but I\n +will better the instruction.\n +\n +Virtue! a fig! \'tis in ourselves that we are thus\n +or thus. Our bodies are our gardens, to the which\n +our wills are gardeners: so that if we will plant\n +nettles, or sow lettuce, set hyssop and weed up\n +thyme, supply it with one gender of herbs, or\n +distract it with many, either to have it sterile\n +with idleness, or manured with industry, why, the\n +power and corrigible authority of this lies in our\n +wills. If the balance of our lives had not one\n +scale of reason to poise another of sensuality, the\n +blood and baseness of our natures would conduct us\n +to most preposterous conclusions: but we have\n +reason to cool our raging motions, our carnal\n +stings, our unbitted lusts, whereof I take this that\n +you call love to be a sect or scion.\n +\n +Blow, winds, and crack your cheeks! rage! blow!\n +You cataracts and hurricanoes, spout\n +Till you have drench\'d our steeples, drown\'d the cocks!\n +You sulphurous and thought-executing fires,\n +Vaunt-couriers to oak-cleaving thunderbolts,\n +Singe my white head! And thou, all-shaking thunder,\n +Smite flat the thick rotundity o\' the world!\n +Crack nature\'s moulds, an germens spill at once,\n +That make ingrateful man! +5...\n +4...\n +3...\n +2...\n +1...\n +BEEEEEEEEEEEEEEEEEP!</string> </resources> - diff --git a/tests/VoiceInteraction/res/xml/interaction_service.xml b/tests/VoiceInteraction/res/xml/interaction_service.xml index ce5669c..c015ad2 100644 --- a/tests/VoiceInteraction/res/xml/interaction_service.xml +++ b/tests/VoiceInteraction/res/xml/interaction_service.xml @@ -20,4 +20,5 @@ <voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android" android:sessionService="com.android.test.voiceinteraction.MainInteractionSessionService" android:recognitionService="com.android.test.voiceinteraction.MainRecognitionService" - android:settingsActivity="com.android.test.voiceinteraction.SettingsActivity" /> + android:settingsActivity="com.android.test.voiceinteraction.SettingsActivity" + android:supportsAssist="true" /> diff --git a/tests/WebViewTests/src/com/android/webviewtests/WebViewStubActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistProxyActivity.java index ccfd3d5..d0c5e36 100644 --- a/tests/WebViewTests/src/com/android/webviewtests/WebViewStubActivity.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistProxyActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2015 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. @@ -14,25 +14,20 @@ * limitations under the License. */ -package com.android.webviewtests; - -import com.android.webviewtests.R; +package com.android.test.voiceinteraction; import android.app.Activity; +import android.content.Intent; import android.os.Bundle; -import android.webkit.WebView; -public class WebViewStubActivity extends Activity { - private WebView mWebView; +public class AssistProxyActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.webview_layout); - mWebView = (WebView) findViewById(R.id.web_page); - } - - public WebView getWebView() { - return mWebView; + finish(); + Intent intent = new Intent(this, MainInteractionService.class); + intent.setAction(Intent.ACTION_ASSIST); + startService(intent); } } diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java new file mode 100644 index 0000000..005a483 --- /dev/null +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2015 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.test.voiceinteraction; + +import android.annotation.Nullable; +import android.app.assist.AssistStructure; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; + +import java.util.ArrayList; + +public class AssistVisualizer extends View { + static final String TAG = "AssistVisualizer"; + + static class TextEntry { + final Rect bounds; + final int parentLeft, parentTop; + final Matrix matrix; + final String className; + final CharSequence text; + final int scrollY; + final int[] lineCharOffsets; + final int[] lineBaselines; + + TextEntry(AssistStructure.ViewNode node, int parentLeft, int parentTop, Matrix matrix) { + int left = parentLeft+node.getLeft(); + int top = parentTop+node.getTop(); + bounds = new Rect(left, top, left+node.getWidth(), top+node.getHeight()); + this.parentLeft = parentLeft; + this.parentTop = parentTop; + this.matrix = new Matrix(matrix); + this.className = node.getClassName(); + this.text = node.getText() != null ? node.getText() : node.getContentDescription(); + this.scrollY = node.getScrollY(); + this.lineCharOffsets = node.getTextLineCharOffsets(); + this.lineBaselines = node.getTextLineBaselines(); + } + } + + AssistStructure mAssistStructure; + final Paint mFramePaint = new Paint(); + final Paint mFrameBaselinePaint = new Paint(); + final Paint mFrameNoTransformPaint = new Paint(); + final ArrayList<Matrix> mMatrixStack = new ArrayList<>(); + final ArrayList<TextEntry> mTextRects = new ArrayList<>(); + final int[] mTmpLocation = new int[2]; + + public AssistVisualizer(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + setWillNotDraw(false); + mFramePaint.setColor(0xffff0000); + mFramePaint.setStyle(Paint.Style.STROKE); + mFramePaint.setStrokeWidth(0); + mFrameBaselinePaint.setColor(0xa0b0b000); + mFrameBaselinePaint.setStyle(Paint.Style.STROKE); + mFrameBaselinePaint.setStrokeWidth(0); + float density = getResources().getDisplayMetrics().density; + mFramePaint.setShadowLayer(density, density, density, 0xff000000); + mFrameNoTransformPaint.setColor(0xff0000ff); + mFrameNoTransformPaint.setStyle(Paint.Style.STROKE); + mFrameNoTransformPaint.setStrokeWidth(0); + mFrameNoTransformPaint.setShadowLayer(density, density, density, 0xff000000); + } + + public void setAssistStructure(AssistStructure as) { + mAssistStructure = as; + mTextRects.clear(); + final int N = as.getWindowNodeCount(); + if (N > 0) { + for (int i=0; i<N; i++) { + AssistStructure.WindowNode windowNode = as.getWindowNodeAt(i); + mMatrixStack.clear(); + Matrix matrix = new Matrix(); + matrix.setTranslate(windowNode.getLeft(), windowNode.getTop()); + mMatrixStack.add(matrix); + buildTextRects(windowNode.getRootViewNode(), 0, windowNode.getLeft(), + windowNode.getTop()); + } + } + Log.d(TAG, "Building text rects in " + this + ": found " + mTextRects.size()); + invalidate(); + } + + public void logTree() { + if (mAssistStructure != null) { + mAssistStructure.dump(); + } + } + + public void logText() { + final int N = mTextRects.size(); + for (int i=0; i<N; i++) { + TextEntry te = mTextRects.get(i); + Log.d(TAG, "View " + te.className + " " + te.bounds.toShortString() + + " in " + te.parentLeft + "," + te.parentTop + + " matrix=" + te.matrix.toShortString() + ": " + + te.text); + if (te.lineCharOffsets != null && te.lineBaselines != null) { + final int num = te.lineCharOffsets.length < te.lineBaselines.length + ? te.lineCharOffsets.length : te.lineBaselines.length; + for (int j=0; j<num; j++) { + Log.d(TAG, " Line #" + j + ": offset=" + te.lineCharOffsets[j] + + " baseline=" + te.lineBaselines[j]); + } + } + } + } + + public void clearAssistData() { + mAssistStructure = null; + mTextRects.clear(); + } + + void buildTextRects(AssistStructure.ViewNode root, int matrixStackIndex, + int parentLeft, int parentTop) { + if (root.getVisibility() != View.VISIBLE) { + return; + } + Matrix parentMatrix = mMatrixStack.get(matrixStackIndex); + matrixStackIndex++; + Matrix matrix; + if (mMatrixStack.size() > matrixStackIndex) { + matrix = mMatrixStack.get(matrixStackIndex); + matrix.set(parentMatrix); + } else { + matrix = new Matrix(parentMatrix); + mMatrixStack.add(matrix); + } + matrix.preTranslate(root.getLeft(), root.getTop()); + int left = parentLeft + root.getLeft(); + int top = parentTop + root.getTop(); + Matrix transform = root.getTransformation(); + if (transform != null) { + matrix.preConcat(transform); + } + if (root.getText() != null || root.getContentDescription() != null) { + TextEntry te = new TextEntry(root, parentLeft, parentTop, matrix); + mTextRects.add(te); + } + final int N = root.getChildCount(); + if (N > 0) { + left -= root.getScrollX(); + top -= root.getScrollY(); + matrix.preTranslate(-root.getScrollX(), -root.getScrollY()); + for (int i=0; i<N; i++) { + AssistStructure.ViewNode child = root.getChildAt(i); + buildTextRects(child, matrixStackIndex, left, top); + } + } + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + getLocationOnScreen(mTmpLocation); + final int N = mTextRects.size(); + Log.d(TAG, "Drawing text rects in " + this + ": found " + mTextRects.size()); + for (int i=0; i<N; i++) { + TextEntry te = mTextRects.get(i); + canvas.drawRect(te.bounds.left - mTmpLocation[0], te.bounds.top - mTmpLocation[1], + te.bounds.right - mTmpLocation[0], te.bounds.bottom - mTmpLocation[1], + mFrameNoTransformPaint); + } + for (int i=0; i<N; i++) { + TextEntry te = mTextRects.get(i); + canvas.save(); + canvas.translate(-mTmpLocation[0], -mTmpLocation[1]); + canvas.concat(te.matrix); + canvas.drawRect(0, 0, te.bounds.right - te.bounds.left, te.bounds.bottom - te.bounds.top, + mFramePaint); + if (te.lineBaselines != null) { + for (int j=0; j<te.lineBaselines.length; j++) { + canvas.drawLine(0, te.lineBaselines[j] - te.scrollY, + te.bounds.right - te.bounds.left, te.lineBaselines[j] - te.scrollY, + mFrameBaselinePaint); + } + } + canvas.restore(); + } + } +} diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AsyncStructure.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AsyncStructure.java new file mode 100644 index 0000000..ae8e9e4 --- /dev/null +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AsyncStructure.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 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.test.voiceinteraction; + +import android.annotation.Nullable; +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewStructure; +import android.widget.TextView; + +/** + * Test for asynchronously creating additional assist structure. + */ +public class AsyncStructure extends TextView { + public AsyncStructure(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + @Override + public void onProvideVirtualStructure(ViewStructure structure) { + structure.setChildCount(1); + final ViewStructure child = structure.asyncNewChild(0); + final int width = getWidth(); + final int height = getHeight(); + (new Thread() { + @Override + public void run() { + // Simulate taking a long time to build this. + try { + sleep(2000); + } catch (InterruptedException e) { + } + child.setClassName(AsyncStructure.class.getName()); + child.setVisibility(View.VISIBLE); + child.setDimens(width / 4, height / 4, 0, 0, width / 2, height / 2); + child.setEnabled(true); + child.setContentDescription("This is some async content"); + child.setText("We could have lots and lots of async text!"); + child.asyncCommit(); + } + }).start(); + } +} diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java index 4639114..f1dd1de 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java @@ -16,12 +16,14 @@ package com.android.test.voiceinteraction; +import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.service.voice.AlwaysOnHotwordDetector; import android.service.voice.AlwaysOnHotwordDetector.Callback; import android.service.voice.AlwaysOnHotwordDetector.EventPayload; import android.service.voice.VoiceInteractionService; +import android.service.voice.VoiceInteractionSession; import android.util.Log; import java.util.Arrays; @@ -72,15 +74,6 @@ public class MainInteractionService extends VoiceInteractionService { "Hello There", Locale.forLanguageTag("en-US"), mHotwordCallback); } - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - Bundle args = new Bundle(); - args.putParcelable("intent", new Intent(this, TestInteractionActivity.class)); - startSession(args); - stopSelf(startId); - return START_NOT_STICKY; - } - private void hotwordAvailabilityChangeHelper(int availability) { Log.i(TAG, "Hotword availability = " + availability); switch (availability) { diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java index d20906e..6e3694b 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java @@ -16,13 +16,21 @@ package com.android.test.voiceinteraction; +import android.app.ActivityManager; +import android.app.VoiceInteractor; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; import android.content.Context; import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; import android.os.Bundle; import android.service.voice.VoiceInteractionSession; import android.util.Log; import android.view.View; import android.widget.Button; +import android.widget.CheckBox; +import android.widget.ImageView; import android.widget.TextView; public class MainInteractionSession extends VoiceInteractionSession @@ -31,129 +39,402 @@ public class MainInteractionSession extends VoiceInteractionSession Intent mStartIntent; View mContentView; + AssistVisualizer mAssistVisualizer; + View mTopContent; + View mBottomContent; TextView mText; + Button mTreeButton; + Button mTextButton; Button mStartButton; + CheckBox mOptionsCheck; + View mOptionsContainer; + CheckBox mDisallowAssist; + CheckBox mDisallowScreenshot; + TextView mOptionsText; + ImageView mScreenshot; + ImageView mFullScreenshot; Button mConfirmButton; Button mCompleteButton; Button mAbortButton; + AssistStructure mAssistStructure; + static final int STATE_IDLE = 0; static final int STATE_LAUNCHING = 1; static final int STATE_CONFIRM = 2; - static final int STATE_COMMAND = 3; - static final int STATE_ABORT_VOICE = 4; - static final int STATE_COMPLETE_VOICE = 5; + static final int STATE_PICK_OPTION = 3; + static final int STATE_COMMAND = 4; + static final int STATE_ABORT_VOICE = 5; + static final int STATE_COMPLETE_VOICE = 6; + static final int STATE_DONE = 7; int mState = STATE_IDLE; + VoiceInteractor.PickOptionRequest.Option[] mPendingOptions; + CharSequence mPendingPrompt; Request mPendingRequest; + int mCurrentTask = -1; MainInteractionSession(Context context) { super(context); } @Override - public void onCreate(Bundle args) { - super.onCreate(args); - showWindow(); - mStartIntent = args.getParcelable("intent"); + public void onCreate() { + super.onCreate(); + ActivityManager am = getContext().getSystemService(ActivityManager.class); + am.setWatchHeapLimit(40 * 1024 * 1024); + } + + @Override + public void onShow(Bundle args, int showFlags) { + super.onShow(args, showFlags); + Log.i(TAG, "onShow: flags=0x" + Integer.toHexString(showFlags) + " args=" + args); + mState = STATE_IDLE; + mStartIntent = args != null ? (Intent)args.getParcelable("intent") : null; + if (mStartIntent == null) { + mStartIntent = new Intent(getContext(), TestInteractionActivity.class); + } + if (mAssistVisualizer != null) { + mAssistVisualizer.clearAssistData(); + } + onHandleScreenshot(null); + updateState(); + refreshOptions(); + } + + @Override + public void onHide() { + super.onHide(); + if (mAssistVisualizer != null) { + mAssistVisualizer.clearAssistData(); + } + mState = STATE_DONE; + updateState(); } @Override public View onCreateContentView() { mContentView = getLayoutInflater().inflate(R.layout.voice_interaction_session, null); + mAssistVisualizer = (AssistVisualizer)mContentView.findViewById(R.id.assist_visualizer); + if (mAssistStructure != null) { + mAssistVisualizer.setAssistStructure(mAssistStructure); + } + mTopContent = mContentView.findViewById(R.id.top_content); + mBottomContent = mContentView.findViewById(R.id.bottom_content); mText = (TextView)mContentView.findViewById(R.id.text); + mTreeButton = (Button)mContentView.findViewById(R.id.do_tree); + mTreeButton.setOnClickListener(this); + mTextButton = (Button)mContentView.findViewById(R.id.do_text); + mTextButton.setOnClickListener(this); mStartButton = (Button)mContentView.findViewById(R.id.start); mStartButton.setOnClickListener(this); + mScreenshot = (ImageView)mContentView.findViewById(R.id.screenshot); + mScreenshot.setOnClickListener(this); + mFullScreenshot = (ImageView)mContentView.findViewById(R.id.full_screenshot); + mOptionsCheck = (CheckBox)mContentView.findViewById(R.id.show_options); + mOptionsCheck.setOnClickListener(this); + mOptionsContainer = mContentView.findViewById(R.id.options); + mDisallowAssist = (CheckBox)mContentView.findViewById(R.id.disallow_structure); + mDisallowAssist.setOnClickListener(this); + mDisallowScreenshot = (CheckBox)mContentView.findViewById(R.id.disallow_screenshot); + mDisallowScreenshot.setOnClickListener(this); + mOptionsText = (TextView)mContentView.findViewById(R.id.options_text); mConfirmButton = (Button)mContentView.findViewById(R.id.confirm); mConfirmButton.setOnClickListener(this); mCompleteButton = (Button)mContentView.findViewById(R.id.complete); mCompleteButton.setOnClickListener(this); mAbortButton = (Button)mContentView.findViewById(R.id.abort); mAbortButton.setOnClickListener(this); - updateState(); + refreshOptions(); return mContentView; } + void refreshOptions() { + if (mOptionsContainer != null) { + if (mOptionsCheck.isChecked()) { + mOptionsContainer.setVisibility(View.VISIBLE); + int flags = getDisabledShowContext(); + mDisallowAssist.setChecked((flags & SHOW_WITH_ASSIST) != 0); + mDisallowScreenshot.setChecked((flags & SHOW_WITH_SCREENSHOT) != 0); + int disabled = getUserDisabledShowContext(); + mOptionsText.setText("Disabled: 0x" + Integer.toHexString(disabled)); + } else { + mOptionsContainer.setVisibility(View.GONE); + } + } + } + + public void onHandleAssist(Bundle assistBundle) { + } + + @Override + public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) { + mAssistStructure = structure; + if (mAssistStructure != null) { + if (mAssistVisualizer != null) { + mAssistVisualizer.setAssistStructure(mAssistStructure); + } + } else { + if (mAssistVisualizer != null) { + mAssistVisualizer.clearAssistData(); + } + } + if (content != null) { + Log.i(TAG, "Assist intent: " + content.getIntent()); + Log.i(TAG, "Assist clipdata: " + content.getClipData()); + } + if (data != null) { + Uri referrer = data.getParcelable(Intent.EXTRA_REFERRER); + if (referrer != null) { + Log.i(TAG, "Referrer: " + referrer); + } + } + } + + @Override + public void onHandleScreenshot(Bitmap screenshot) { + if (screenshot != null) { + mScreenshot.setImageBitmap(screenshot); + mScreenshot.setAdjustViewBounds(true); + mScreenshot.setMaxWidth(screenshot.getWidth() / 3); + mScreenshot.setMaxHeight(screenshot.getHeight() / 3); + mFullScreenshot.setImageBitmap(screenshot); + } else { + mScreenshot.setImageDrawable(null); + mFullScreenshot.setImageDrawable(null); + } + } + void updateState() { + if (mState == STATE_IDLE) { + mTopContent.setVisibility(View.VISIBLE); + mBottomContent.setVisibility(View.GONE); + mAssistVisualizer.setVisibility(View.VISIBLE); + } else if (mState == STATE_DONE) { + mTopContent.setVisibility(View.GONE); + mBottomContent.setVisibility(View.GONE); + mAssistVisualizer.setVisibility(View.GONE); + } else { + mTopContent.setVisibility(View.GONE); + mBottomContent.setVisibility(View.VISIBLE); + mAssistVisualizer.setVisibility(View.GONE); + } mStartButton.setEnabled(mState == STATE_IDLE); - mConfirmButton.setEnabled(mState == STATE_CONFIRM || mState == STATE_COMMAND); + mConfirmButton.setEnabled(mState == STATE_CONFIRM || mState == STATE_PICK_OPTION + || mState == STATE_COMMAND); mAbortButton.setEnabled(mState == STATE_ABORT_VOICE); mCompleteButton.setEnabled(mState == STATE_COMPLETE_VOICE); } public void onClick(View v) { - if (v == mStartButton) { + if (v == mTreeButton) { + if (mAssistVisualizer != null) { + mAssistVisualizer.logTree(); + } + } else if (v == mTextButton) { + if (mAssistVisualizer != null) { + mAssistVisualizer.logText(); + } + } else if (v == mOptionsCheck) { + refreshOptions(); + } else if (v == mDisallowAssist) { + int flags = getDisabledShowContext(); + if (mDisallowAssist.isChecked()) { + flags |= SHOW_WITH_ASSIST; + } else { + flags &= ~SHOW_WITH_ASSIST; + } + setDisabledShowContext(flags); + } else if (v == mDisallowScreenshot) { + int flags = getDisabledShowContext(); + if (mDisallowScreenshot.isChecked()) { + flags |= SHOW_WITH_SCREENSHOT; + } else { + flags &= ~SHOW_WITH_SCREENSHOT; + } + setDisabledShowContext(flags); + } else if (v == mStartButton) { mState = STATE_LAUNCHING; updateState(); startVoiceActivity(mStartIntent); } else if (v == mConfirmButton) { - if (mState == STATE_CONFIRM) { - mPendingRequest.sendConfirmResult(true, null); - } else { - mPendingRequest.sendCommandResult(true, null); + if (mPendingRequest instanceof ConfirmationRequest) { + ((ConfirmationRequest)mPendingRequest).sendConfirmationResult(true, null); + mPendingRequest = null; + mState = STATE_LAUNCHING; + } else if (mPendingRequest instanceof PickOptionRequest) { + PickOptionRequest pick = (PickOptionRequest)mPendingRequest; + int numReturn = mPendingOptions.length/2; + if (numReturn <= 0) { + numReturn = 1; + } + VoiceInteractor.PickOptionRequest.Option[] picked + = new VoiceInteractor.PickOptionRequest.Option[numReturn]; + for (int i=0; i<picked.length; i++) { + picked[i] = mPendingOptions[i*2]; + } + mPendingOptions = picked; + if (picked.length <= 1) { + pick.sendPickOptionResult(picked, null); + mPendingRequest = null; + mState = STATE_LAUNCHING; + } else { + pick.sendIntermediatePickOptionResult(picked, null); + updatePickText(); + } + } else if (mPendingRequest instanceof CommandRequest) { + Bundle result = new Bundle(); + result.putString("key", "a result!"); + ((CommandRequest)mPendingRequest).sendResult(result); + mPendingRequest = null; + mState = STATE_LAUNCHING; } + } else if (v == mAbortButton && mPendingRequest instanceof AbortVoiceRequest) { + ((AbortVoiceRequest)mPendingRequest).sendAbortResult(null); mPendingRequest = null; - mState = STATE_IDLE; - updateState(); - } else if (v == mAbortButton) { - mPendingRequest.sendAbortVoiceResult(null); - mPendingRequest = null; - mState = STATE_IDLE; - updateState(); - } else if (v== mCompleteButton) { - mPendingRequest.sendCompleteVoiceResult(null); + } else if (v == mCompleteButton && mPendingRequest instanceof CompleteVoiceRequest) { + ((CompleteVoiceRequest)mPendingRequest).sendCompleteResult(null); mPendingRequest = null; - mState = STATE_IDLE; - updateState(); + } else if (v == mScreenshot) { + if (mFullScreenshot.getVisibility() != View.VISIBLE) { + mFullScreenshot.setVisibility(View.VISIBLE); + } else { + mFullScreenshot.setVisibility(View.INVISIBLE); + } } + updateState(); } @Override - public boolean[] onGetSupportedCommands(Caller caller, String[] commands) { - return new boolean[commands.length]; + public void onComputeInsets(Insets outInsets) { + super.onComputeInsets(outInsets); + if (mState != STATE_IDLE) { + outInsets.contentInsets.top = mBottomContent.getTop(); + outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_CONTENT; + } } @Override - public void onConfirm(Caller caller, Request request, CharSequence prompt, Bundle extras) { - Log.i(TAG, "onConfirm: prompt=" + prompt + " extras=" + extras); - mText.setText(prompt); - mStartButton.setText("Confirm"); + public void onTaskStarted(Intent intent, int taskId) { + super.onTaskStarted(intent, taskId); + mCurrentTask = taskId; + } + + @Override + public void onTaskFinished(Intent intent, int taskId) { + super.onTaskFinished(intent, taskId); + if (mCurrentTask == taskId) { + mCurrentTask = -1; + } + } + + @Override + public void onLockscreenShown() { + if (mCurrentTask < 0) { + hide(); + } + } + + @Override + public boolean[] onGetSupportedCommands(String[] commands) { + boolean[] res = new boolean[commands.length]; + for (int i=0; i<commands.length; i++) { + if ("com.android.test.voiceinteraction.COMMAND".equals(commands[i])) { + res[i] = true; + } + } + return res; + } + + void setPrompt(VoiceInteractor.Prompt prompt) { + if (prompt == null) { + mText.setText("(null)"); + mPendingPrompt = ""; + } else { + mText.setText(prompt.getVisualPrompt()); + mPendingPrompt = prompt.getVisualPrompt(); + } + } + + @Override + public void onRequestConfirmation(ConfirmationRequest request) { + Log.i(TAG, "onConfirm: prompt=" + request.getVoicePrompt() + " extras=" + + request.getExtras()); + setPrompt(request.getVoicePrompt()); + mConfirmButton.setText("Confirm"); mPendingRequest = request; mState = STATE_CONFIRM; updateState(); } @Override - public void onCompleteVoice(Caller caller, Request request, CharSequence message, Bundle extras) { - Log.i(TAG, "onCompleteVoice: message=" + message + " extras=" + extras); - mText.setText(message); + public void onRequestPickOption(PickOptionRequest request) { + Log.i(TAG, "onPickOption: prompt=" + request.getVoicePrompt() + " options=" + + request.getOptions() + " extras=" + request.getExtras()); + mConfirmButton.setText("Pick Option"); + mPendingRequest = request; + setPrompt(request.getVoicePrompt()); + mPendingOptions = request.getOptions(); + mState = STATE_PICK_OPTION; + updatePickText(); + updateState(); + } + + void updatePickText() { + StringBuilder sb = new StringBuilder(); + sb.append(mPendingPrompt); + sb.append(": "); + for (int i=0; i<mPendingOptions.length; i++) { + if (i > 0) { + sb.append(", "); + } + sb.append(mPendingOptions[i].getLabel()); + } + mText.setText(sb.toString()); + } + + @Override + public void onRequestCompleteVoice(CompleteVoiceRequest request) { + Log.i(TAG, "onCompleteVoice: message=" + request.getVoicePrompt() + " extras=" + + request.getExtras()); + setPrompt(request.getVoicePrompt()); mPendingRequest = request; mState = STATE_COMPLETE_VOICE; updateState(); } @Override - public void onAbortVoice(Caller caller, Request request, CharSequence message, Bundle extras) { - Log.i(TAG, "onAbortVoice: message=" + message + " extras=" + extras); - mText.setText(message); + public void onRequestAbortVoice(AbortVoiceRequest request) { + Log.i(TAG, "onAbortVoice: message=" + request.getVoicePrompt() + " extras=" + + request.getExtras()); + setPrompt(request.getVoicePrompt()); mPendingRequest = request; mState = STATE_ABORT_VOICE; updateState(); } @Override - public void onCommand(Caller caller, Request request, String command, Bundle extras) { - Log.i(TAG, "onCommand: command=" + command + " extras=" + extras); - mText.setText("Command: " + command); - mStartButton.setText("Finish Command"); + public void onRequestCommand(CommandRequest request) { + Bundle extras = request.getExtras(); + if (extras != null) { + extras.getString("arg"); + } + Log.i(TAG, "onCommand: command=" + request.getCommand() + " extras=" + extras); + mText.setText("Command: " + request.getCommand() + ", " + extras); + mConfirmButton.setText("Finish Command"); mPendingRequest = request; mState = STATE_COMMAND; updateState(); } @Override - public void onCancel(Request request) { + public void onCancelRequest(Request request) { Log.i(TAG, "onCancel"); - request.sendCancelResult(); + if (mPendingRequest == request) { + mPendingRequest = null; + mState = STATE_LAUNCHING; + updateState(); + } + request.cancel(); } } diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java index d64eefa..ada0e21 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java @@ -18,19 +18,35 @@ package com.android.test.voiceinteraction; import android.app.Activity; import android.app.VoiceInteractor; +import android.content.ComponentName; +import android.content.Intent; import android.os.Bundle; +import android.provider.Settings; +import android.service.voice.VoiceInteractionService; import android.util.Log; -import android.view.Gravity; import android.view.View; -import android.view.ViewGroup; import android.widget.Button; +import android.widget.TextView; public class TestInteractionActivity extends Activity implements View.OnClickListener { static final String TAG = "TestInteractionActivity"; + static final String REQUEST_ABORT = "abort"; + static final String REQUEST_COMPLETE = "complete"; + static final String REQUEST_COMMAND = "command"; + static final String REQUEST_PICK = "pick"; + static final String REQUEST_CONFIRM = "confirm"; + VoiceInteractor mInteractor; + VoiceInteractor.Request mCurrentRequest = null; + TextView mLog; + Button mAirplaneButton; Button mAbortButton; Button mCompleteButton; + Button mCommandButton; + Button mPickButton; + Button mJumpOutButton; + Button mCancelButton; @Override public void onCreate(Bundle savedInstanceState) { @@ -42,72 +58,108 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis return; } + if (!VoiceInteractionService.isActiveService(this, + new ComponentName(this, MainInteractionService.class))) { + Log.w(TAG, "Not current voice interactor!"); + finish(); + return; + } + setContentView(R.layout.test_interaction); + mLog = (TextView)findViewById(R.id.log); + mAirplaneButton = (Button)findViewById(R.id.airplane); + mAirplaneButton.setOnClickListener(this); mAbortButton = (Button)findViewById(R.id.abort); mAbortButton.setOnClickListener(this); mCompleteButton = (Button)findViewById(R.id.complete); mCompleteButton.setOnClickListener(this); - - // Framework should take care of these. - getWindow().setGravity(Gravity.TOP); - getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT); + mCommandButton = (Button)findViewById(R.id.command); + mCommandButton.setOnClickListener(this); + mPickButton = (Button)findViewById(R.id.pick); + mPickButton.setOnClickListener(this); + mJumpOutButton = (Button)findViewById(R.id.jump); + mJumpOutButton.setOnClickListener(this); + mCancelButton = (Button)findViewById(R.id.cancel); + mCancelButton.setOnClickListener(this); mInteractor = getVoiceInteractor(); - VoiceInteractor.ConfirmationRequest req = new VoiceInteractor.ConfirmationRequest( - "This is a confirmation", null) { - @Override - public void onCancel() { - Log.i(TAG, "Canceled!"); - getActivity().finish(); - } - @Override - public void onConfirmationResult(boolean confirmed, Bundle result) { - Log.i(TAG, "Confirmation result: confirmed=" + confirmed + " result=" + result); - getActivity().finish(); - } - }; - mInteractor.submitRequest(req); - } - - @Override - public void onResume() { - super.onResume(); - } + VoiceInteractor.Request[] active = mInteractor.getActiveRequests(); + for (int i=0; i<active.length; i++) { + Log.i(TAG, "Active #" + i + " / " + active[i].getName() + ": " + active[i]); + } - @Override - public void onClick(View v) { - if (v == mAbortButton) { - VoiceInteractor.AbortVoiceRequest req = new VoiceInteractor.AbortVoiceRequest( - "Dammit, we suck :(", null) { + mCurrentRequest = mInteractor.getActiveRequest(REQUEST_CONFIRM); + if (mCurrentRequest == null) { + mCurrentRequest = new VoiceInteractor.ConfirmationRequest( + new VoiceInteractor.Prompt("This is a confirmation"), null) { @Override public void onCancel() { Log.i(TAG, "Canceled!"); - } - - @Override - public void onAbortResult(Bundle result) { - Log.i(TAG, "Abort result: result=" + result); getActivity().finish(); } - }; - mInteractor.submitRequest(req); - } else if (v == mCompleteButton) { - VoiceInteractor.CompleteVoiceRequest req = new VoiceInteractor.CompleteVoiceRequest( - "Woohoo, completed!", null) { - @Override - public void onCancel() { - Log.i(TAG, "Canceled!"); - } @Override - public void onCompleteResult(Bundle result) { - Log.i(TAG, "Complete result: result=" + result); + public void onConfirmationResult(boolean confirmed, Bundle result) { + Log.i(TAG, "Confirmation result: confirmed=" + confirmed + " result=" + result); getActivity().finish(); } }; - mInteractor.submitRequest(req); + mInteractor.submitRequest(mCurrentRequest, REQUEST_CONFIRM); + String[] cmds = new String[] { + "com.android.test.voiceinteraction.COMMAND", + "com.example.foo.bar" + }; + boolean sup[] = mInteractor.supportsCommands(cmds); + for (int i=0; i<cmds.length; i++) { + mLog.append(cmds[i] + ": " + (sup[i] ? "SUPPORTED" : "NOT SUPPORTED") + "\n"); + } + } else { + Log.i(TAG, "Restarting with active confirmation: " + mCurrentRequest); + } + } + + @Override + public void onResume() { + super.onResume(); + } + + @Override + public void onClick(View v) { + if (v == mAirplaneButton) { + Intent intent = new Intent(Settings.ACTION_VOICE_CONTROL_AIRPLANE_MODE); + intent.addCategory(Intent.CATEGORY_VOICE); + intent.putExtra(Settings.EXTRA_AIRPLANE_MODE_ENABLED, true); + startActivity(intent); + } else if (v == mAbortButton) { + VoiceInteractor.AbortVoiceRequest req = new TestAbortVoice(); + mInteractor.submitRequest(req, REQUEST_ABORT); + } else if (v == mCompleteButton) { + VoiceInteractor.CompleteVoiceRequest req = new TestCompleteVoice(); + mInteractor.submitRequest(req, REQUEST_COMPLETE); + } else if (v == mCommandButton) { + VoiceInteractor.CommandRequest req = new TestCommand("Some arg"); + mInteractor.submitRequest(req, REQUEST_COMMAND); + } else if (v == mPickButton) { + VoiceInteractor.PickOptionRequest.Option[] options = + new VoiceInteractor.PickOptionRequest.Option[5]; + options[0] = new VoiceInteractor.PickOptionRequest.Option("One"); + options[1] = new VoiceInteractor.PickOptionRequest.Option("Two"); + options[2] = new VoiceInteractor.PickOptionRequest.Option("Three"); + options[3] = new VoiceInteractor.PickOptionRequest.Option("Four"); + options[4] = new VoiceInteractor.PickOptionRequest.Option("Five"); + VoiceInteractor.PickOptionRequest req = new TestPickOption(options); + mInteractor.submitRequest(req, REQUEST_PICK); + } else if (v == mJumpOutButton) { + Log.i(TAG, "Jump out"); + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + intent.setComponent(new ComponentName(this, VoiceInteractionMain.class)); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } else if (v == mCancelButton && mCurrentRequest != null) { + Log.i(TAG, "Cancel request"); + mCurrentRequest.cancel(); } } @@ -115,4 +167,95 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis public void onDestroy() { super.onDestroy(); } + + static class TestAbortVoice extends VoiceInteractor.AbortVoiceRequest { + public TestAbortVoice() { + super(new VoiceInteractor.Prompt("Dammit, we suck :("), null); + } + @Override public void onCancel() { + Log.i(TAG, "Canceled!"); + ((TestInteractionActivity)getActivity()).mLog.append("Canceled abort\n"); + } + @Override public void onAbortResult(Bundle result) { + Log.i(TAG, "Abort result: result=" + result); + ((TestInteractionActivity)getActivity()).mLog.append("Abort: result=" + result + "\n"); + getActivity().finish(); + } + } + + static class TestCompleteVoice extends VoiceInteractor.CompleteVoiceRequest { + public TestCompleteVoice() { + super(new VoiceInteractor.Prompt("Woohoo, completed!"), null); + } + @Override public void onCancel() { + Log.i(TAG, "Canceled!"); + ((TestInteractionActivity)getActivity()).mLog.append("Canceled complete\n"); + } + @Override public void onCompleteResult(Bundle result) { + Log.i(TAG, "Complete result: result=" + result); + ((TestInteractionActivity)getActivity()).mLog.append("Complete: result=" + + result + "\n"); + getActivity().finish(); + } + } + + static class TestCommand extends VoiceInteractor.CommandRequest { + public TestCommand(String arg) { + super("com.android.test.voiceinteraction.COMMAND", makeBundle(arg)); + } + @Override public void onCancel() { + Log.i(TAG, "Canceled!"); + ((TestInteractionActivity)getActivity()).mLog.append("Canceled command\n"); + } + @Override + public void onCommandResult(boolean finished, Bundle result) { + Log.i(TAG, "Command result: finished=" + finished + " result=" + result); + StringBuilder sb = new StringBuilder(); + if (finished) { + sb.append("Command final result: "); + } else { + sb.append("Command intermediate result: "); + } + if (result != null) { + result.getString("key"); + } + sb.append(result); + sb.append("\n"); + ((TestInteractionActivity)getActivity()).mLog.append(sb.toString()); + } + static Bundle makeBundle(String arg) { + Bundle b = new Bundle(); + b.putString("key", arg); + return b; + } + } + + static class TestPickOption extends VoiceInteractor.PickOptionRequest { + public TestPickOption(Option[] options) { + super(new VoiceInteractor.Prompt("Need to pick something"), options, null); + } + @Override public void onCancel() { + Log.i(TAG, "Canceled!"); + ((TestInteractionActivity)getActivity()).mLog.append("Canceled pick\n"); + } + @Override + public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) { + Log.i(TAG, "Pick result: finished=" + finished + " selections=" + selections + + " result=" + result); + StringBuilder sb = new StringBuilder(); + if (finished) { + sb.append("Pick final result: "); + } else { + sb.append("Pick intermediate result: "); + } + for (int i=0; i<selections.length; i++) { + if (i >= 1) { + sb.append(", "); + } + sb.append(selections[i].getLabel()); + } + sb.append("\n"); + ((TestInteractionActivity)getActivity()).mLog.append(sb.toString()); + } + } } diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java index 5d212a4..87fa91a 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java @@ -18,8 +18,11 @@ package com.android.test.voiceinteraction; import android.app.Activity; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.view.View; +import android.view.WindowManager; +import android.widget.CheckBox; public class VoiceInteractionMain extends Activity { @@ -29,6 +32,7 @@ public class VoiceInteractionMain extends Activity { setContentView(R.layout.main); findViewById(R.id.start).setOnClickListener(mStartListener); + findViewById(R.id.secure).setOnClickListener(mSecureListener); } @Override @@ -41,9 +45,24 @@ public class VoiceInteractionMain extends Activity { super.onDestroy(); } + @Override + public Uri onProvideReferrer() { + return Uri.parse("http://www.example.com/VoiceInteractionMain"); + } + View.OnClickListener mStartListener = new View.OnClickListener() { public void onClick(View v) { - startService(new Intent(VoiceInteractionMain.this, MainInteractionService.class)); + showAssist(null); + } + }; + + View.OnClickListener mSecureListener = new View.OnClickListener() { + public void onClick(View v) { + if (((CheckBox)v).isChecked()) { + getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); + } else { + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE); + } } }; } diff --git a/tests/WebViewTests/Android.mk b/tests/WebViewTests/Android.mk deleted file mode 100644 index b118845..0000000 --- a/tests/WebViewTests/Android.mk +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (C) 2011 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. -# -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -LOCAL_JAVA_LIBRARIES := android.test.runner - -LOCAL_PACKAGE_NAME := WebViewTests - -include $(BUILD_PACKAGE) diff --git a/tests/WebViewTests/AndroidManifest.xml b/tests/WebViewTests/AndroidManifest.xml deleted file mode 100644 index 8b080c1..0000000 --- a/tests/WebViewTests/AndroidManifest.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright (C) 2011 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. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.webviewtests"> - <application> - <uses-library android:name="android.test.runner" /> - <activity android:name="WebViewStubActivity" android:label="WebViewStubActivity"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.TEST" /> - </intent-filter> - </activity> - </application> - - <instrumentation android:name="android.test.InstrumentationTestRunner" - android:targetPackage="com.android.webviewtests" - android:label="Tests for android.webkit.WebView" /> -</manifest> diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayCoercionTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayCoercionTest.java deleted file mode 100644 index c2bbdf5..0000000 --- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayCoercionTest.java +++ /dev/null @@ -1,625 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/** - * Part of the test suite for the WebView's Java Bridge. This class tests that - * we correctly convert JavaScript arrays to Java arrays when passing them to - * the methods of injected Java objects. - * - * The conversions should follow - * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in - * which the implementation differs from the spec are marked with - * LIVECONNECT_COMPLIANCE. - * FIXME: Consider making our implementation more compliant, if it will not - * break backwards-compatibility. See b/4408210. - * - * To run this test ... - * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeArrayCoercionTest \ - * com.android.webviewtests/android.test.InstrumentationTestRunner - */ - -package com.android.webviewtests; - -public class JavaBridgeArrayCoercionTest extends JavaBridgeTestBase { - private class TestObject extends Controller { - private Object mObjectInstance; - private CustomType mCustomTypeInstance; - - private boolean[] mBooleanArray; - private byte[] mByteArray; - private char[] mCharArray; - private short[] mShortArray; - private int[] mIntArray; - private long[] mLongArray; - private float[] mFloatArray; - private double[] mDoubleArray; - private String[] mStringArray; - private Object[] mObjectArray; - private CustomType[] mCustomTypeArray; - - public TestObject() { - mObjectInstance = new Object(); - mCustomTypeInstance = new CustomType(); - } - - public Object getObjectInstance() { - return mObjectInstance; - } - public CustomType getCustomTypeInstance() { - return mCustomTypeInstance; - } - - public synchronized void setBooleanArray(boolean[] x) { - mBooleanArray = x; - notifyResultIsReady(); - } - public synchronized void setByteArray(byte[] x) { - mByteArray = x; - notifyResultIsReady(); - } - public synchronized void setCharArray(char[] x) { - mCharArray = x; - notifyResultIsReady(); - } - public synchronized void setShortArray(short[] x) { - mShortArray = x; - notifyResultIsReady(); - } - public synchronized void setIntArray(int[] x) { - mIntArray = x; - notifyResultIsReady(); - } - public synchronized void setLongArray(long[] x) { - mLongArray = x; - notifyResultIsReady(); - } - public synchronized void setFloatArray(float[] x) { - mFloatArray = x; - notifyResultIsReady(); - } - public synchronized void setDoubleArray(double[] x) { - mDoubleArray = x; - notifyResultIsReady(); - } - public synchronized void setStringArray(String[] x) { - mStringArray = x; - notifyResultIsReady(); - } - public synchronized void setObjectArray(Object[] x) { - mObjectArray = x; - notifyResultIsReady(); - } - public synchronized void setCustomTypeArray(CustomType[] x) { - mCustomTypeArray = x; - notifyResultIsReady(); - } - - public synchronized boolean[] waitForBooleanArray() { - waitForResult(); - return mBooleanArray; - } - public synchronized byte[] waitForByteArray() { - waitForResult(); - return mByteArray; - } - public synchronized char[] waitForCharArray() { - waitForResult(); - return mCharArray; - } - public synchronized short[] waitForShortArray() { - waitForResult(); - return mShortArray; - } - public synchronized int[] waitForIntArray() { - waitForResult(); - return mIntArray; - } - public synchronized long[] waitForLongArray() { - waitForResult(); - return mLongArray; - } - public synchronized float[] waitForFloatArray() { - waitForResult(); - return mFloatArray; - } - public synchronized double[] waitForDoubleArray() { - waitForResult(); - return mDoubleArray; - } - public synchronized String[] waitForStringArray() { - waitForResult(); - return mStringArray; - } - public synchronized Object[] waitForObjectArray() { - waitForResult(); - return mObjectArray; - } - public synchronized CustomType[] waitForCustomTypeArray() { - waitForResult(); - return mCustomTypeArray; - } - } - - // Two custom types used when testing passing objects. - private class CustomType { - } - - private TestObject mTestObject; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mTestObject = new TestObject(); - setUpWebView(mTestObject, "testObject"); - } - - // Note that all tests use a single element array for simplicity. We test - // multiple elements elsewhere. - - // Test passing an array of JavaScript numbers in the int32 range to a - // method which takes a Java array. - public void testPassNumberInt32() throws Throwable { - executeJavaScript("testObject.setBooleanArray([0]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); - // LIVECONNECT_COMPLIANCE: Should convert to boolean. - executeJavaScript("testObject.setBooleanArray([42]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); - - executeJavaScript("testObject.setByteArray([42]);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should convert to numeric char value. - executeJavaScript("testObject.setCharArray([42]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - - executeJavaScript("testObject.setShortArray([42]);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); - - executeJavaScript("testObject.setIntArray([42]);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); - - executeJavaScript("testObject.setLongArray([42]);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); - - executeJavaScript("testObject.setFloatArray([42]);"); - assertEquals(42.0f, mTestObject.waitForFloatArray()[0]); - - executeJavaScript("testObject.setDoubleArray([42]);"); - assertEquals(42.0, mTestObject.waitForDoubleArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([42]);"); - assertNull(mTestObject.waitForObjectArray()); - - // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. - executeJavaScript("testObject.setStringArray([42]);"); - assertNull(mTestObject.waitForStringArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([42]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - } - - // Test passing an array of JavaScript numbers in the double range to a - // method which takes a Java array. - public void testPassNumberDouble() throws Throwable { - // LIVECONNECT_COMPLIANCE: Should convert to boolean. - executeJavaScript("testObject.setBooleanArray([42.1]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); - - executeJavaScript("testObject.setByteArray([42.1]);"); - assertEquals(42, mTestObject.waitForByteArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should convert to numeric char value. - executeJavaScript("testObject.setCharArray([42.1]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - - executeJavaScript("testObject.setShortArray([42.1]);"); - assertEquals(42, mTestObject.waitForShortArray()[0]); - - executeJavaScript("testObject.setIntArray([42.1]);"); - assertEquals(42, mTestObject.waitForIntArray()[0]); - - executeJavaScript("testObject.setLongArray([42.1]);"); - assertEquals(42L, mTestObject.waitForLongArray()[0]); - - executeJavaScript("testObject.setFloatArray([42.1]);"); - assertEquals(42.1f, mTestObject.waitForFloatArray()[0]); - - executeJavaScript("testObject.setDoubleArray([42.1]);"); - assertEquals(42.1, mTestObject.waitForDoubleArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([42.1]);"); - assertNull(mTestObject.waitForObjectArray()); - - // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. - executeJavaScript("testObject.setStringArray([42.1]);"); - assertNull(mTestObject.waitForStringArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([42.1]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - } - - // Test passing an array of JavaScript NaN values to a method which takes a - // Java array. - public void testPassNumberNaN() throws Throwable { - executeJavaScript("testObject.setBooleanArray([Number.NaN]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); - - executeJavaScript("testObject.setByteArray([Number.NaN]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); - - executeJavaScript("testObject.setCharArray([Number.NaN]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - - executeJavaScript("testObject.setShortArray([Number.NaN]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); - - executeJavaScript("testObject.setIntArray([Number.NaN]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); - - executeJavaScript("testObject.setLongArray([Number.NaN]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); - - executeJavaScript("testObject.setFloatArray([Number.NaN]);"); - assertEquals(Float.NaN, mTestObject.waitForFloatArray()[0]); - - executeJavaScript("testObject.setDoubleArray([Number.NaN]);"); - assertEquals(Double.NaN, mTestObject.waitForDoubleArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([Number.NaN]);"); - assertNull(mTestObject.waitForObjectArray()); - - // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. - executeJavaScript("testObject.setStringArray([Number.NaN]);"); - assertNull(mTestObject.waitForStringArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([Number.NaN]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - } - - // Test passing an array of JavaScript infinity values to a method which - // takes a Java array. - public void testPassNumberInfinity() throws Throwable { - executeJavaScript("testObject.setBooleanArray([Infinity]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); - - executeJavaScript("testObject.setByteArray([Infinity]);"); - assertEquals(-1, mTestObject.waitForByteArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should convert to maximum numeric char value. - executeJavaScript("testObject.setCharArray([Infinity]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - - executeJavaScript("testObject.setShortArray([Infinity]);"); - assertEquals(-1, mTestObject.waitForShortArray()[0]); - - executeJavaScript("testObject.setIntArray([Infinity]);"); - assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE. - executeJavaScript("testObject.setLongArray([Infinity]);"); - assertEquals(-1L, mTestObject.waitForLongArray()[0]); - - executeJavaScript("testObject.setFloatArray([Infinity]);"); - assertEquals(Float.POSITIVE_INFINITY, mTestObject.waitForFloatArray()[0]); - - executeJavaScript("testObject.setDoubleArray([Infinity]);"); - assertEquals(Double.POSITIVE_INFINITY, mTestObject.waitForDoubleArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([Infinity]);"); - assertNull(mTestObject.waitForObjectArray()); - - // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. - executeJavaScript("testObject.setStringArray([Infinity]);"); - assertNull(mTestObject.waitForStringArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([Infinity]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - } - - // Test passing an array of JavaScript boolean values to a method which - // takes a Java array. - public void testPassBoolean() throws Throwable { - executeJavaScript("testObject.setBooleanArray([true]);"); - assertTrue(mTestObject.waitForBooleanArray()[0]); - executeJavaScript("testObject.setBooleanArray([false]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setByteArray([true]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); - executeJavaScript("testObject.setByteArray([false]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should convert to numeric char value 1. - executeJavaScript("testObject.setCharArray([true]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - executeJavaScript("testObject.setCharArray([false]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setShortArray([true]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); - executeJavaScript("testObject.setShortArray([false]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setIntArray([true]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); - executeJavaScript("testObject.setIntArray([false]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setLongArray([true]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); - executeJavaScript("testObject.setLongArray([false]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should be 1.0. - executeJavaScript("testObject.setFloatArray([true]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); - executeJavaScript("testObject.setFloatArray([false]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should be 1.0. - executeJavaScript("testObject.setDoubleArray([true]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); - executeJavaScript("testObject.setDoubleArray([false]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([true]);"); - assertNull(mTestObject.waitForObjectArray()); - - // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. - executeJavaScript("testObject.setStringArray([true]);"); - assertNull(mTestObject.waitForStringArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([true]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - } - - // Test passing an array of JavaScript strings to a method which takes a - // Java array. - public void testPassString() throws Throwable { - // LIVECONNECT_COMPLIANCE: Non-empty string should convert to true. - executeJavaScript("testObject.setBooleanArray([\"+042.10\"]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setByteArray([\"+042.10\"]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should decode and convert to numeric char value. - executeJavaScript("testObject.setCharArray([\"+042.10\"]);"); - assertEquals(0, mTestObject.waitForCharArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setShortArray([\"+042.10\"]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setIntArray([\"+042.10\"]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setLongArray([\"+042.10\"]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setFloatArray([\"+042.10\"]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setDoubleArray([\"+042.10\"]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. - executeJavaScript("testObject.setObjectArray([\"+042.10\"]);"); - assertNull(mTestObject.waitForObjectArray()); - - executeJavaScript("testObject.setStringArray([\"+042.10\"]);"); - assertEquals("+042.10", mTestObject.waitForStringArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([\"+042.10\"]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - } - - // Test passing an array of JavaScript objects to a method which takes a - // Java array. - public void testPassJavaScriptObject() throws Throwable { - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setBooleanArray([{foo: 42}]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setByteArray([{foo: 42}]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCharArray([{foo: 42}]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setShortArray([{foo: 42}]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setIntArray([{foo: 42}]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setLongArray([{foo: 42}]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setFloatArray([{foo: 42}]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setDoubleArray([{foo: 42}]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setObjectArray([{foo: 42}]);"); - assertNull(mTestObject.waitForObjectArray()); - - // LIVECONNECT_COMPLIANCE: Should call toString() on object. - executeJavaScript("testObject.setStringArray([{foo: 42}]);"); - assertNull(mTestObject.waitForStringArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeArray([{foo: 42}]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - } - - // Test passing an array of Java objects to a method which takes a Java - // array. - public void testPassJavaObject() throws Throwable { - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setBooleanArray([testObject.getObjectInstance()]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setByteArray([testObject.getObjectInstance()]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCharArray([testObject.getObjectInstance()]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setShortArray([testObject.getObjectInstance()]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setIntArray([testObject.getObjectInstance()]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setLongArray([testObject.getObjectInstance()]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setFloatArray([testObject.getObjectInstance()]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setDoubleArray([testObject.getObjectInstance()]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create an array and pass Java object. - executeJavaScript("testObject.setObjectArray([testObject.getObjectInstance()]);"); - assertNull(mTestObject.waitForObjectArray()); - - // LIVECONNECT_COMPLIANCE: Should call toString() on object. - executeJavaScript("testObject.setStringArray([testObject.getObjectInstance()]);"); - assertNull(mTestObject.waitForStringArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create array and pass Java object. - executeJavaScript("testObject.setCustomTypeArray([testObject.getObjectInstance()]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - executeJavaScript("testObject.setCustomTypeArray([testObject.getCustomTypeInstance()]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - } - - // Test passing an array of JavaScript null values to a method which takes - // a Java array. - public void testPassNull() throws Throwable { - executeJavaScript("testObject.setByteArray([null]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); - - executeJavaScript("testObject.setCharArray([null]);"); - assertEquals('\u0000', mTestObject.waitForCharArray()[0]); - - executeJavaScript("testObject.setShortArray([null]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); - - executeJavaScript("testObject.setIntArray([null]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); - - executeJavaScript("testObject.setLongArray([null]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); - - executeJavaScript("testObject.setFloatArray([null]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); - - executeJavaScript("testObject.setDoubleArray([null]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); - - executeJavaScript("testObject.setBooleanArray([null]);"); - assertFalse(mTestObject.waitForBooleanArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create array and pass null. - executeJavaScript("testObject.setObjectArray([null]);"); - assertNull(mTestObject.waitForObjectArray()); - - executeJavaScript("testObject.setStringArray([null]);"); - assertNull(mTestObject.waitForStringArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create array and pass null. - executeJavaScript("testObject.setCustomTypeArray([null]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - } - - // Test passing an array of JavaScript undefined values to a method which - // takes a Java array. - public void testPassUndefined() throws Throwable { - executeJavaScript("testObject.setByteArray([undefined]);"); - assertEquals(0, mTestObject.waitForByteArray()[0]); - - executeJavaScript("testObject.setCharArray([undefined]);"); - assertEquals(0, mTestObject.waitForCharArray()[0]); - - executeJavaScript("testObject.setShortArray([undefined]);"); - assertEquals(0, mTestObject.waitForShortArray()[0]); - - executeJavaScript("testObject.setIntArray([undefined]);"); - assertEquals(0, mTestObject.waitForIntArray()[0]); - - executeJavaScript("testObject.setLongArray([undefined]);"); - assertEquals(0L, mTestObject.waitForLongArray()[0]); - - executeJavaScript("testObject.setFloatArray([undefined]);"); - assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); - - executeJavaScript("testObject.setDoubleArray([undefined]);"); - assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); - - executeJavaScript("testObject.setBooleanArray([undefined]);"); - assertEquals(false, mTestObject.waitForBooleanArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create array and pass null. - executeJavaScript("testObject.setObjectArray([undefined]);"); - assertNull(mTestObject.waitForObjectArray()); - - executeJavaScript("testObject.setStringArray([undefined]);"); - assertNull(mTestObject.waitForStringArray()[0]); - - // LIVECONNECT_COMPLIANCE: Should create array and pass null. - executeJavaScript("testObject.setCustomTypeArray([undefined]);"); - assertNull(mTestObject.waitForCustomTypeArray()); - } -} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayTest.java deleted file mode 100644 index 2fd42a7..0000000 --- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayTest.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/** - * Part of the test suite for the WebView's Java Bridge. This class tests the - * general use of arrays. - * - * The conversions should follow - * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in - * which the implementation differs from the spec are marked with - * LIVECONNECT_COMPLIANCE. - * FIXME: Consider making our implementation more compliant, if it will not - * break backwards-compatibility. See b/4408210. - * - * To run this test ... - * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeArrayTest \ - * com.android.webviewtests/android.test.InstrumentationTestRunner - */ - -package com.android.webviewtests; - -public class JavaBridgeArrayTest extends JavaBridgeTestBase { - private class TestObject extends Controller { - private boolean mBooleanValue; - private int mIntValue; - private String mStringValue; - - private int[] mIntArray; - private int[][] mIntIntArray; - - private boolean mWasArrayMethodCalled; - - public synchronized void setBooleanValue(boolean x) { - mBooleanValue = x; - notifyResultIsReady(); - } - public synchronized void setIntValue(int x) { - mIntValue = x; - notifyResultIsReady(); - } - public synchronized void setStringValue(String x) { - mStringValue = x; - notifyResultIsReady(); - } - - public synchronized boolean waitForBooleanValue() { - waitForResult(); - return mBooleanValue; - } - public synchronized int waitForIntValue() { - waitForResult(); - return mIntValue; - } - public synchronized String waitForStringValue() { - waitForResult(); - return mStringValue; - } - - public synchronized void setIntArray(int[] x) { - mIntArray = x; - notifyResultIsReady(); - } - public synchronized void setIntIntArray(int[][] x) { - mIntIntArray = x; - notifyResultIsReady(); - } - - public synchronized int[] waitForIntArray() { - waitForResult(); - return mIntArray; - } - public synchronized int[][] waitForIntIntArray() { - waitForResult(); - return mIntIntArray; - } - - public synchronized int[] arrayMethod() { - mWasArrayMethodCalled = true; - return new int[] {42, 43, 44}; - } - - public synchronized boolean wasArrayMethodCalled() { - return mWasArrayMethodCalled; - } - } - - private TestObject mTestObject; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mTestObject = new TestObject(); - setUpWebView(mTestObject, "testObject"); - } - - public void testArrayLength() throws Throwable { - executeJavaScript("testObject.setIntArray([42, 43, 44]);"); - int[] result = mTestObject.waitForIntArray(); - assertEquals(3, result.length); - assertEquals(42, result[0]); - assertEquals(43, result[1]); - assertEquals(44, result[2]); - } - - public void testPassNull() throws Throwable { - executeJavaScript("testObject.setIntArray(null);"); - assertNull(mTestObject.waitForIntArray()); - } - - public void testPassUndefined() throws Throwable { - executeJavaScript("testObject.setIntArray(undefined);"); - assertNull(mTestObject.waitForIntArray()); - } - - public void testPassEmptyArray() throws Throwable { - executeJavaScript("testObject.setIntArray([]);"); - assertEquals(0, mTestObject.waitForIntArray().length); - } - - // Note that this requires being able to pass a string from JavaScript to - // Java. - public void testPassArrayToStringMethod() throws Throwable { - // LIVECONNECT_COMPLIANCE: Should call toString() on array. - executeJavaScript("testObject.setStringValue([42, 42, 42]);"); - assertEquals("undefined", mTestObject.waitForStringValue()); - } - - // Note that this requires being able to pass an integer from JavaScript to - // Java. - public void testPassArrayToNonStringNonArrayMethod() throws Throwable { - // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception. - executeJavaScript("testObject.setIntValue([42, 42, 42]);"); - assertEquals(0, mTestObject.waitForIntValue()); - } - - public void testPassNonArrayToArrayMethod() throws Throwable { - // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception. - executeJavaScript("testObject.setIntArray(42);"); - assertNull(mTestObject.waitForIntArray()); - } - - public void testObjectWithLengthProperty() throws Throwable { - executeJavaScript("testObject.setIntArray({length: 3, 1: 42});"); - int[] result = mTestObject.waitForIntArray(); - assertEquals(3, result.length); - assertEquals(0, result[0]); - assertEquals(42, result[1]); - assertEquals(0, result[2]); - } - - public void testNonNumericLengthProperty() throws Throwable { - // LIVECONNECT_COMPLIANCE: This should not count as an array, so we - // should raise a JavaScript exception. - executeJavaScript("testObject.setIntArray({length: \"foo\"});"); - assertNull(mTestObject.waitForIntArray()); - } - - public void testLengthOutOfBounds() throws Throwable { - // LIVECONNECT_COMPLIANCE: This should not count as an array, so we - // should raise a JavaScript exception. - executeJavaScript("testObject.setIntArray({length: -1});"); - assertNull(mTestObject.waitForIntArray()); - - // LIVECONNECT_COMPLIANCE: This should not count as an array, so we - // should raise a JavaScript exception. - long length = (long)Integer.MAX_VALUE + 1L; - executeJavaScript("testObject.setIntArray({length: " + length + "});"); - assertNull(mTestObject.waitForIntArray()); - - // LIVECONNECT_COMPLIANCE: This should not count as an array, so we - // should raise a JavaScript exception. - length = (long)Integer.MAX_VALUE + 1L - (long)Integer.MIN_VALUE + 1L; - executeJavaScript("testObject.setIntArray({length: " + length + "});"); - assertNull(mTestObject.waitForIntArray()); - } - - public void testSparseArray() throws Throwable { - executeJavaScript("var x = [42, 43]; x[3] = 45; testObject.setIntArray(x);"); - int[] result = mTestObject.waitForIntArray(); - assertEquals(4, result.length); - assertEquals(42, result[0]); - assertEquals(43, result[1]); - assertEquals(0, result[2]); - assertEquals(45, result[3]); - } - - // Note that this requires being able to pass a boolean from JavaScript to - // Java. - public void testMethodReturningArrayNotCalled() throws Throwable { - // We don't invoke methods which return arrays, but note that no - // exception is raised. - // LIVECONNECT_COMPLIANCE: Should call method and convert result to - // JavaScript array. - executeJavaScript("testObject.setBooleanValue(undefined === testObject.arrayMethod())"); - assertTrue(mTestObject.waitForBooleanValue()); - assertFalse(mTestObject.wasArrayMethodCalled()); - } - - public void testMultiDimensionalArrayMethod() throws Throwable { - // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays. - executeJavaScript("testObject.setIntIntArray([ [42, 43], [44, 45] ]);"); - assertNull(mTestObject.waitForIntIntArray()); - } - - public void testPassMultiDimensionalArray() throws Throwable { - // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays. - executeJavaScript("testObject.setIntArray([ [42, 43], [44, 45] ]);"); - int[] result = mTestObject.waitForIntArray(); - assertEquals(2, result.length); - assertEquals(0, result[0]); - assertEquals(0, result[1]); - } -} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java deleted file mode 100644 index 1ecccf6..0000000 --- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/** - * Part of the test suite for the WebView's Java Bridge. Tests a number of features including ... - * - The type of injected objects - * - The type of their methods - * - Replacing objects - * - Removing objects - * - Access control - * - Calling methods on returned objects - * - Multiply injected objects - * - Threading - * - Inheritance - * - * To run this test ... - * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeBasicsTest \ - * com.android.webviewtests/android.test.InstrumentationTestRunner - */ - -package com.android.webviewtests; - -public class JavaBridgeBasicsTest extends JavaBridgeTestBase { - private class TestController extends Controller { - private int mIntValue; - private long mLongValue; - private String mStringValue; - private boolean mBooleanValue; - - public synchronized void setIntValue(int x) { - mIntValue = x; - notifyResultIsReady(); - } - public synchronized void setLongValue(long x) { - mLongValue = x; - notifyResultIsReady(); - } - public synchronized void setStringValue(String x) { - mStringValue = x; - notifyResultIsReady(); - } - public synchronized void setBooleanValue(boolean x) { - mBooleanValue = x; - notifyResultIsReady(); - } - - public synchronized int waitForIntValue() { - waitForResult(); - return mIntValue; - } - public synchronized long waitForLongValue() { - waitForResult(); - return mLongValue; - } - public synchronized String waitForStringValue() { - waitForResult(); - return mStringValue; - } - public synchronized boolean waitForBooleanValue() { - waitForResult(); - return mBooleanValue; - } - } - - private static class ObjectWithStaticMethod { - public static String staticMethod() { - return "foo"; - } - } - - TestController mTestController; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mTestController = new TestController(); - setUpWebView(mTestController, "testController"); - } - - // Note that this requires that we can pass a JavaScript string to Java. - protected String executeJavaScriptAndGetStringResult(String script) throws Throwable { - executeJavaScript("testController.setStringValue(" + script + ");"); - return mTestController.waitForStringValue(); - } - - protected void injectObjectAndReload(final Object object, final String name) throws Throwable { - runTestOnUiThread(new Runnable() { - @Override - public void run() { - getWebView().addJavascriptInterface(object, name); - getWebView().reload(); - } - }); - mWebViewClient.waitForOnPageFinished(); - } - - // Note that this requires that we can pass a JavaScript boolean to Java. - private void assertRaisesException(String script) throws Throwable { - executeJavaScript("try {" + - script + ";" + - " testController.setBooleanValue(false);" + - "} catch (exception) {" + - " testController.setBooleanValue(true);" + - "}"); - assertTrue(mTestController.waitForBooleanValue()); - } - - public void testTypeOfInjectedObject() throws Throwable { - assertEquals("object", executeJavaScriptAndGetStringResult("typeof testController")); - } - - public void testAdditionNotReflectedUntilReload() throws Throwable { - assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject")); - runTestOnUiThread(new Runnable() { - @Override - public void run() { - getWebView().addJavascriptInterface(new Object(), "testObject"); - } - }); - assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject")); - runTestOnUiThread(new Runnable() { - @Override - public void run() { - getWebView().reload(); - } - }); - mWebViewClient.waitForOnPageFinished(); - assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); - } - - public void testRemovalNotReflectedUntilReload() throws Throwable { - injectObjectAndReload(new Object(), "testObject"); - assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); - runTestOnUiThread(new Runnable() { - @Override - public void run() { - getWebView().removeJavascriptInterface("testObject"); - } - }); - assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); - runTestOnUiThread(new Runnable() { - @Override - public void run() { - getWebView().reload(); - } - }); - mWebViewClient.waitForOnPageFinished(); - assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject")); - } - - public void testRemoveObjectNotAdded() throws Throwable { - runTestOnUiThread(new Runnable() { - @Override - public void run() { - getWebView().removeJavascriptInterface("foo"); - getWebView().reload(); - } - }); - mWebViewClient.waitForOnPageFinished(); - assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof foo")); - } - - public void testTypeOfMethod() throws Throwable { - assertEquals("function", - executeJavaScriptAndGetStringResult("typeof testController.setStringValue")); - } - - public void testTypeOfInvalidMethod() throws Throwable { - assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testController.foo")); - } - - public void testCallingInvalidMethodRaisesException() throws Throwable { - assertRaisesException("testController.foo()"); - } - - public void testUncaughtJavaExceptionRaisesJavaException() throws Throwable { - injectObjectAndReload(new Object() { - public void method() { throw new RuntimeException("foo"); } - }, "testObject"); - assertRaisesException("testObject.method()"); - } - - // Note that this requires that we can pass a JavaScript string to Java. - public void testTypeOfStaticMethod() throws Throwable { - injectObjectAndReload(new ObjectWithStaticMethod(), "testObject"); - executeJavaScript("testController.setStringValue(typeof testObject.staticMethod)"); - assertEquals("function", mTestController.waitForStringValue()); - } - - // Note that this requires that we can pass a JavaScript string to Java. - public void testCallStaticMethod() throws Throwable { - injectObjectAndReload(new ObjectWithStaticMethod(), "testObject"); - executeJavaScript("testController.setStringValue(testObject.staticMethod())"); - assertEquals("foo", mTestController.waitForStringValue()); - } - - public void testPrivateMethodNotExposed() throws Throwable { - injectObjectAndReload(new Object() { - private void method() {} - }, "testObject"); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.method")); - } - - public void testReplaceInjectedObject() throws Throwable { - injectObjectAndReload(new Object() { - public void method() { mTestController.setStringValue("object 1"); } - }, "testObject"); - executeJavaScript("testObject.method()"); - assertEquals("object 1", mTestController.waitForStringValue()); - - injectObjectAndReload(new Object() { - public void method() { mTestController.setStringValue("object 2"); } - }, "testObject"); - executeJavaScript("testObject.method()"); - assertEquals("object 2", mTestController.waitForStringValue()); - } - - public void testInjectNullObjectIsIgnored() throws Throwable { - injectObjectAndReload(null, "testObject"); - assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject")); - } - - public void testReplaceInjectedObjectWithNullObjectIsIgnored() throws Throwable { - injectObjectAndReload(new Object(), "testObject"); - assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); - injectObjectAndReload(null, "testObject"); - assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); - } - - public void testCallOverloadedMethodWithDifferentNumberOfArguments() throws Throwable { - injectObjectAndReload(new Object() { - public void method() { mTestController.setStringValue("0 args"); } - public void method(int x) { mTestController.setStringValue("1 arg"); } - public void method(int x, int y) { mTestController.setStringValue("2 args"); } - }, "testObject"); - executeJavaScript("testObject.method()"); - assertEquals("0 args", mTestController.waitForStringValue()); - executeJavaScript("testObject.method(42)"); - assertEquals("1 arg", mTestController.waitForStringValue()); - executeJavaScript("testObject.method(null)"); - assertEquals("1 arg", mTestController.waitForStringValue()); - executeJavaScript("testObject.method(undefined)"); - assertEquals("1 arg", mTestController.waitForStringValue()); - executeJavaScript("testObject.method(42, 42)"); - assertEquals("2 args", mTestController.waitForStringValue()); - } - - public void testCallMethodWithWrongNumberOfArgumentsRaisesException() throws Throwable { - assertRaisesException("testController.setIntValue()"); - assertRaisesException("testController.setIntValue(42, 42)"); - } - - public void testObjectPersistsAcrossPageLoads() throws Throwable { - assertEquals("object", executeJavaScriptAndGetStringResult("typeof testController")); - runTestOnUiThread(new Runnable() { - @Override - public void run() { - getWebView().reload(); - } - }); - mWebViewClient.waitForOnPageFinished(); - assertEquals("object", executeJavaScriptAndGetStringResult("typeof testController")); - } - - public void testSameObjectInjectedMultipleTimes() throws Throwable { - class TestObject { - private int mNumMethodInvocations; - public void method() { mTestController.setIntValue(++mNumMethodInvocations); } - } - final TestObject testObject = new TestObject(); - runTestOnUiThread(new Runnable() { - @Override - public void run() { - getWebView().addJavascriptInterface(testObject, "testObject1"); - getWebView().addJavascriptInterface(testObject, "testObject2"); - getWebView().reload(); - } - }); - mWebViewClient.waitForOnPageFinished(); - executeJavaScript("testObject1.method()"); - assertEquals(1, mTestController.waitForIntValue()); - executeJavaScript("testObject2.method()"); - assertEquals(2, mTestController.waitForIntValue()); - } - - public void testCallMethodOnReturnedObject() throws Throwable { - injectObjectAndReload(new Object() { - public Object getInnerObject() { - return new Object() { - public void method(int x) { mTestController.setIntValue(x); } - }; - } - }, "testObject"); - executeJavaScript("testObject.getInnerObject().method(42)"); - assertEquals(42, mTestController.waitForIntValue()); - } - - public void testReturnedObjectInjectedElsewhere() throws Throwable { - class InnerObject { - private int mNumMethodInvocations; - public void method() { mTestController.setIntValue(++mNumMethodInvocations); } - } - final InnerObject innerObject = new InnerObject(); - final Object object = new Object() { - public InnerObject getInnerObject() { - return innerObject; - } - }; - runTestOnUiThread(new Runnable() { - @Override - public void run() { - getWebView().addJavascriptInterface(object, "testObject"); - getWebView().addJavascriptInterface(innerObject, "innerObject"); - getWebView().reload(); - } - }); - mWebViewClient.waitForOnPageFinished(); - executeJavaScript("testObject.getInnerObject().method()"); - assertEquals(1, mTestController.waitForIntValue()); - executeJavaScript("innerObject.method()"); - assertEquals(2, mTestController.waitForIntValue()); - } - - public void testMethodInvokedOnBackgroundThread() throws Throwable { - injectObjectAndReload(new Object() { - public void captureThreadId() { - mTestController.setLongValue(Thread.currentThread().getId()); - } - }, "testObject"); - executeJavaScript("testObject.captureThreadId()"); - final long threadId = mTestController.waitForLongValue(); - assertFalse(threadId == Thread.currentThread().getId()); - runTestOnUiThread(new Runnable() { - @Override - public void run() { - assertFalse(threadId == Thread.currentThread().getId()); - } - }); - } - - public void testPublicInheritedMethod() throws Throwable { - class Base { - public void method(int x) { mTestController.setIntValue(x); } - } - class Derived extends Base { - } - injectObjectAndReload(new Derived(), "testObject"); - assertEquals("function", executeJavaScriptAndGetStringResult("typeof testObject.method")); - executeJavaScript("testObject.method(42)"); - assertEquals(42, mTestController.waitForIntValue()); - } - - public void testPrivateInheritedMethod() throws Throwable { - class Base { - private void method() {} - } - class Derived extends Base { - } - injectObjectAndReload(new Derived(), "testObject"); - assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject.method")); - } - - public void testOverriddenMethod() throws Throwable { - class Base { - public void method() { mTestController.setStringValue("base"); } - } - class Derived extends Base { - public void method() { mTestController.setStringValue("derived"); } - } - injectObjectAndReload(new Derived(), "testObject"); - executeJavaScript("testObject.method()"); - assertEquals("derived", mTestController.waitForStringValue()); - } - - public void testEnumerateMembers() throws Throwable { - injectObjectAndReload(new Object() { - public void method() {} - private void privateMethod() {} - public int field; - private int privateField; - }, "testObject"); - executeJavaScript( - "var result = \"\"; " + - "for (x in testObject) { result += \" \" + x } " + - "testController.setStringValue(result);"); - // LIVECONNECT_COMPLIANCE: Should be able to enumerate members. - assertEquals("", mTestController.waitForStringValue()); - } - - public void testReflectPublicMethod() throws Throwable { - injectObjectAndReload(new Object() { - public String method() { return "foo"; } - }, "testObject"); - assertEquals("foo", executeJavaScriptAndGetStringResult( - "testObject.getClass().getMethod('method', null).invoke(testObject, null)" + - ".toString()")); - } - - public void testReflectPublicField() throws Throwable { - injectObjectAndReload(new Object() { - public String field = "foo"; - }, "testObject"); - assertEquals("foo", executeJavaScriptAndGetStringResult( - "testObject.getClass().getField('field').get(testObject).toString()")); - } - - public void testReflectPrivateMethodRaisesException() throws Throwable { - injectObjectAndReload(new Object() { - private void method() {}; - }, "testObject"); - assertRaisesException("testObject.getClass().getMethod('method', null)"); - // getDeclaredMethod() is able to access a private method, but invoke() - // throws a Java exception. - assertRaisesException( - "testObject.getClass().getDeclaredMethod('method', null).invoke(testObject, null)"); - } - - public void testReflectPrivateFieldRaisesException() throws Throwable { - injectObjectAndReload(new Object() { - private int field; - }, "testObject"); - assertRaisesException("testObject.getClass().getField('field')"); - // getDeclaredField() is able to access a private field, but getInt() - // throws a Java exception. - assertRaisesException( - "testObject.getClass().getDeclaredField('field').getInt(testObject)"); - } -} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeChildFrameTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeChildFrameTest.java deleted file mode 100644 index 3f0e2b3..0000000 --- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeChildFrameTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -/** - * Part of the test suite for the WebView's Java Bridge. - * - * Ensures that injected objects are exposed to child frames as well as the - * main frame. - * - * To run this test ... - * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeChildFrameTest \ - * com.android.webviewtests/android.test.InstrumentationTestRunner - */ - -package com.android.webviewtests; - -public class JavaBridgeChildFrameTest extends JavaBridgeTestBase { - private class TestController extends Controller { - private String mStringValue; - - public synchronized void setStringValue(String x) { - mStringValue = x; - notifyResultIsReady(); - } - public synchronized String waitForStringValue() { - waitForResult(); - return mStringValue; - } - } - - TestController mTestController; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mTestController = new TestController(); - setUpWebView(mTestController, "testController"); - } - - public void testInjectedObjectPresentInChildFrame() throws Throwable { - // In the case that the test fails (i.e. the child frame doesn't get the injected object, - // the call to testController.setStringValue in the child frame's onload handler will - // not be made. - getActivity().getWebView().loadData( - "<html><head></head><body>" + - "<iframe id=\"childFrame\" onload=\"testController.setStringValue('PASS');\" />" + - "</body></html>", "text/html", null); - assertEquals("PASS", mTestController.waitForStringValue()); - } -} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeCoercionTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeCoercionTest.java deleted file mode 100644 index a0f78a4..0000000 --- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeCoercionTest.java +++ /dev/null @@ -1,646 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/** - * Part of the test suite for the WebView's Java Bridge. This class tests that - * we correctly convert JavaScript values to Java values when passing them to - * the methods of injected Java objects. - * - * The conversions should follow - * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in - * which the implementation differs from the spec are marked with - * LIVECONNECT_COMPLIANCE. - * FIXME: Consider making our implementation more compliant, if it will not - * break backwards-compatibility. See b/4408210. - * - * To run this test ... - * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeCoercionTest \ - * com.android.webviewtests/android.test.InstrumentationTestRunner - */ - -package com.android.webviewtests; - -public class JavaBridgeCoercionTest extends JavaBridgeTestBase { - private class TestObject extends Controller { - private Object objectInstance; - private CustomType customTypeInstance; - private CustomType2 customType2Instance; - - private boolean mBooleanValue; - private byte mByteValue; - private char mCharValue; - private short mShortValue; - private int mIntValue; - private long mLongValue; - private float mFloatValue; - private double mDoubleValue; - private String mStringValue; - private Object mObjectValue; - private CustomType mCustomTypeValue; - - public TestObject() { - objectInstance = new Object(); - customTypeInstance = new CustomType(); - customType2Instance = new CustomType2(); - } - - public Object getObjectInstance() { - return objectInstance; - } - public CustomType getCustomTypeInstance() { - return customTypeInstance; - } - public CustomType2 getCustomType2Instance() { - return customType2Instance; - } - - public synchronized void setBooleanValue(boolean x) { - mBooleanValue = x; - notifyResultIsReady(); - } - public synchronized void setByteValue(byte x) { - mByteValue = x; - notifyResultIsReady(); - } - public synchronized void setCharValue(char x) { - mCharValue = x; - notifyResultIsReady(); - } - public synchronized void setShortValue(short x) { - mShortValue = x; - notifyResultIsReady(); - } - public synchronized void setIntValue(int x) { - mIntValue = x; - notifyResultIsReady(); - } - public synchronized void setLongValue(long x) { - mLongValue = x; - notifyResultIsReady(); - } - public synchronized void setFloatValue(float x) { - mFloatValue = x; - notifyResultIsReady(); - } - public synchronized void setDoubleValue(double x) { - mDoubleValue = x; - notifyResultIsReady(); - } - public synchronized void setStringValue(String x) { - mStringValue = x; - notifyResultIsReady(); - } - public synchronized void setObjectValue(Object x) { - mObjectValue = x; - notifyResultIsReady(); - } - public synchronized void setCustomTypeValue(CustomType x) { - mCustomTypeValue = x; - notifyResultIsReady(); - } - - public synchronized boolean waitForBooleanValue() { - waitForResult(); - return mBooleanValue; - } - public synchronized byte waitForByteValue() { - waitForResult(); - return mByteValue; - } - public synchronized char waitForCharValue() { - waitForResult(); - return mCharValue; - } - public synchronized short waitForShortValue() { - waitForResult(); - return mShortValue; - } - public synchronized int waitForIntValue() { - waitForResult(); - return mIntValue; - } - public synchronized long waitForLongValue() { - waitForResult(); - return mLongValue; - } - public synchronized float waitForFloatValue() { - waitForResult(); - return mFloatValue; - } - public synchronized double waitForDoubleValue() { - waitForResult(); - return mDoubleValue; - } - public synchronized String waitForStringValue() { - waitForResult(); - return mStringValue; - } - public synchronized Object waitForObjectValue() { - waitForResult(); - return mObjectValue; - } - public synchronized CustomType waitForCustomTypeValue() { - waitForResult(); - return mCustomTypeValue; - } - } - - // Two custom types used when testing passing objects. - private static class CustomType { - } - private static class CustomType2 { - } - - private TestObject mTestObject; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mTestObject = new TestObject(); - setUpWebView(mTestObject, "testObject"); - } - - // Test passing a JavaScript number in the int32 range to a method of an - // injected object. - public void testPassNumberInt32() throws Throwable { - executeJavaScript("testObject.setByteValue(42);"); - assertEquals(42, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42);"); - assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue()); - - // LIVECONNECT_COMPLIANCE: Should convert to numeric char value. - executeJavaScript("testObject.setCharValue(42);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - - executeJavaScript("testObject.setShortValue(42);"); - assertEquals(42, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setShortValue(" + Short.MAX_VALUE + " + 42);"); - assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue()); - - executeJavaScript("testObject.setIntValue(42);"); - assertEquals(42, mTestObject.waitForIntValue()); - - executeJavaScript("testObject.setLongValue(42);"); - assertEquals(42L, mTestObject.waitForLongValue()); - - executeJavaScript("testObject.setFloatValue(42);"); - assertEquals(42.0f, mTestObject.waitForFloatValue()); - - executeJavaScript("testObject.setDoubleValue(42);"); - assertEquals(42.0, mTestObject.waitForDoubleValue()); - - // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. - executeJavaScript("testObject.setObjectValue(42);"); - assertNull(mTestObject.waitForObjectValue()); - - // The spec allows the JS engine flexibility in how to format the number. - executeJavaScript("testObject.setStringValue(42);"); - String str = mTestObject.waitForStringValue(); - assertTrue("42".equals(str) || "42.0".equals(str)); - - executeJavaScript("testObject.setBooleanValue(0);"); - assertFalse(mTestObject.waitForBooleanValue()); - // LIVECONNECT_COMPLIANCE: Should be true; - executeJavaScript("testObject.setBooleanValue(42);"); - assertFalse(mTestObject.waitForBooleanValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(42);"); - assertNull(mTestObject.waitForCustomTypeValue()); - } - - // Test passing a JavaScript number in the double range to a method of an - // injected object. - public void testPassNumberDouble() throws Throwable { - executeJavaScript("testObject.setByteValue(42.1);"); - assertEquals(42, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42.1);"); - assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setByteValue(" + Integer.MAX_VALUE + " + 42.1);"); - assertEquals(-1, mTestObject.waitForByteValue()); - - // LIVECONNECT_COMPLIANCE: Should convert to numeric char value. - executeJavaScript("testObject.setCharValue(42.1);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - - executeJavaScript("testObject.setShortValue(42.1);"); - assertEquals(42, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setShortValue(" + Short.MAX_VALUE + " + 42.1);"); - assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setShortValue(" + Integer.MAX_VALUE + " + 42.1);"); - assertEquals(-1, mTestObject.waitForShortValue()); - - executeJavaScript("testObject.setIntValue(42.1);"); - assertEquals(42, mTestObject.waitForIntValue()); - executeJavaScript("testObject.setIntValue(" + Integer.MAX_VALUE + " + 42.1);"); - assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue()); - - executeJavaScript("testObject.setLongValue(42.1);"); - assertEquals(42L, mTestObject.waitForLongValue()); - // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE. - executeJavaScript("testObject.setLongValue(" + Long.MAX_VALUE + " + 42.1);"); - assertEquals(Long.MIN_VALUE, mTestObject.waitForLongValue()); - - executeJavaScript("testObject.setFloatValue(42.1);"); - assertEquals(42.1f, mTestObject.waitForFloatValue()); - - executeJavaScript("testObject.setDoubleValue(42.1);"); - assertEquals(42.1, mTestObject.waitForDoubleValue()); - - // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. - executeJavaScript("testObject.setObjectValue(42.1);"); - assertNull(mTestObject.waitForObjectValue()); - - executeJavaScript("testObject.setStringValue(42.1);"); - assertEquals("42.1", mTestObject.waitForStringValue()); - - executeJavaScript("testObject.setBooleanValue(0.0);"); - assertFalse(mTestObject.waitForBooleanValue()); - // LIVECONNECT_COMPLIANCE: Should be true. - executeJavaScript("testObject.setBooleanValue(42.1);"); - assertFalse(mTestObject.waitForBooleanValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(42.1);"); - assertNull(mTestObject.waitForCustomTypeValue()); - } - - // Test passing JavaScript NaN to a method of an injected object. - public void testPassNumberNaN() throws Throwable { - executeJavaScript("testObject.setByteValue(Number.NaN);"); - assertEquals(0, mTestObject.waitForByteValue()); - - executeJavaScript("testObject.setCharValue(Number.NaN);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - - executeJavaScript("testObject.setShortValue(Number.NaN);"); - assertEquals(0, mTestObject.waitForShortValue()); - - executeJavaScript("testObject.setIntValue(Number.NaN);"); - assertEquals(0, mTestObject.waitForIntValue()); - - executeJavaScript("testObject.setLongValue(Number.NaN);"); - assertEquals(0L, mTestObject.waitForLongValue()); - - executeJavaScript("testObject.setFloatValue(Number.NaN);"); - assertEquals(Float.NaN, mTestObject.waitForFloatValue()); - - executeJavaScript("testObject.setDoubleValue(Number.NaN);"); - assertEquals(Double.NaN, mTestObject.waitForDoubleValue()); - - // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. - executeJavaScript("testObject.setObjectValue(Number.NaN);"); - assertNull(mTestObject.waitForObjectValue()); - - executeJavaScript("testObject.setStringValue(Number.NaN);"); - assertEquals("NaN", mTestObject.waitForStringValue()); - - executeJavaScript("testObject.setBooleanValue(Number.NaN);"); - assertFalse(mTestObject.waitForBooleanValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(Number.NaN);"); - assertNull(mTestObject.waitForCustomTypeValue()); - } - - // Test passing JavaScript infinity to a method of an injected object. - public void testPassNumberInfinity() throws Throwable { - executeJavaScript("testObject.setByteValue(Infinity);"); - assertEquals(-1, mTestObject.waitForByteValue()); - - // LIVECONNECT_COMPLIANCE: Should convert to maximum numeric char value. - executeJavaScript("testObject.setCharValue(Infinity);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - - executeJavaScript("testObject.setShortValue(Infinity);"); - assertEquals(-1, mTestObject.waitForShortValue()); - - executeJavaScript("testObject.setIntValue(Infinity);"); - assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue()); - - // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE. - executeJavaScript("testObject.setLongValue(Infinity);"); - assertEquals(-1L, mTestObject.waitForLongValue()); - - executeJavaScript("testObject.setFloatValue(Infinity);"); - assertEquals(Float.POSITIVE_INFINITY, mTestObject.waitForFloatValue()); - - executeJavaScript("testObject.setDoubleValue(Infinity);"); - assertEquals(Double.POSITIVE_INFINITY, mTestObject.waitForDoubleValue()); - - // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. - executeJavaScript("testObject.setObjectValue(Infinity);"); - assertNull(mTestObject.waitForObjectValue()); - - executeJavaScript("testObject.setStringValue(Infinity);"); - assertEquals("Inf", mTestObject.waitForStringValue()); - - executeJavaScript("testObject.setBooleanValue(Infinity);"); - assertFalse(mTestObject.waitForBooleanValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(Infinity);"); - assertNull(mTestObject.waitForCustomTypeValue()); - } - - // Test passing a JavaScript boolean to a method of an injected object. - public void testPassBoolean() throws Throwable { - executeJavaScript("testObject.setBooleanValue(true);"); - assertTrue(mTestObject.waitForBooleanValue()); - executeJavaScript("testObject.setBooleanValue(false);"); - assertFalse(mTestObject.waitForBooleanValue()); - - // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Boolean. - executeJavaScript("testObject.setObjectValue(true);"); - assertNull(mTestObject.waitForObjectValue()); - - executeJavaScript("testObject.setStringValue(false);"); - assertEquals("false", mTestObject.waitForStringValue()); - executeJavaScript("testObject.setStringValue(true);"); - assertEquals("true", mTestObject.waitForStringValue()); - - // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setByteValue(true);"); - assertEquals(0, mTestObject.waitForByteValue()); - executeJavaScript("testObject.setByteValue(false);"); - assertEquals(0, mTestObject.waitForByteValue()); - - // LIVECONNECT_COMPLIANCE: Should convert to numeric char value 1. - executeJavaScript("testObject.setCharValue(true);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - executeJavaScript("testObject.setCharValue(false);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - - // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setShortValue(true);"); - assertEquals(0, mTestObject.waitForShortValue()); - executeJavaScript("testObject.setShortValue(false);"); - assertEquals(0, mTestObject.waitForShortValue()); - - // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setIntValue(true);"); - assertEquals(0, mTestObject.waitForIntValue()); - executeJavaScript("testObject.setIntValue(false);"); - assertEquals(0, mTestObject.waitForIntValue()); - - // LIVECONNECT_COMPLIANCE: Should be 1. - executeJavaScript("testObject.setLongValue(true);"); - assertEquals(0L, mTestObject.waitForLongValue()); - executeJavaScript("testObject.setLongValue(false);"); - assertEquals(0L, mTestObject.waitForLongValue()); - - // LIVECONNECT_COMPLIANCE: Should be 1.0. - executeJavaScript("testObject.setFloatValue(true);"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); - executeJavaScript("testObject.setFloatValue(false);"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); - - // LIVECONNECT_COMPLIANCE: Should be 1.0. - executeJavaScript("testObject.setDoubleValue(true);"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); - executeJavaScript("testObject.setDoubleValue(false);"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(true);"); - assertNull(mTestObject.waitForCustomTypeValue()); - } - - // Test passing a JavaScript string to a method of an injected object. - public void testPassString() throws Throwable { - executeJavaScript("testObject.setStringValue(\"+042.10\");"); - assertEquals("+042.10", mTestObject.waitForStringValue()); - - // Make sure that we distinguish between the empty string and NULL. - executeJavaScript("testObject.setStringValue(\"\");"); - assertEquals("", mTestObject.waitForStringValue()); - - // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.String. - executeJavaScript("testObject.setObjectValue(\"+042.10\");"); - assertNull(mTestObject.waitForObjectValue()); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setByteValue(\"+042.10\");"); - assertEquals(0, mTestObject.waitForByteValue()); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setShortValue(\"+042.10\");"); - assertEquals(0, mTestObject.waitForShortValue()); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setIntValue(\"+042.10\");"); - assertEquals(0, mTestObject.waitForIntValue()); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setLongValue(\"+042.10\");"); - assertEquals(0L, mTestObject.waitForLongValue()); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setFloatValue(\"+042.10\");"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); - - // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. - executeJavaScript("testObject.setDoubleValue(\"+042.10\");"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); - - // LIVECONNECT_COMPLIANCE: Should decode and convert to numeric char value. - executeJavaScript("testObject.setCharValue(\"+042.10\");"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - - // LIVECONNECT_COMPLIANCE: Non-empty string should convert to true. - executeJavaScript("testObject.setBooleanValue(\"+042.10\");"); - assertFalse(mTestObject.waitForBooleanValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue(\"+042.10\");"); - assertNull(mTestObject.waitForCustomTypeValue()); - } - - // Test passing a JavaScript object to a method of an injected object. - public void testPassJavaScriptObject() throws Throwable { - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setObjectValue({foo: 42});"); - assertNull(mTestObject.waitForObjectValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCustomTypeValue({foo: 42});"); - assertNull(mTestObject.waitForCustomTypeValue()); - - // LIVECONNECT_COMPLIANCE: Should call toString() on object. - executeJavaScript("testObject.setStringValue({foo: 42});"); - assertEquals("undefined", mTestObject.waitForStringValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setByteValue({foo: 42});"); - assertEquals(0, mTestObject.waitForByteValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCharValue({foo: 42});"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setShortValue({foo: 42});"); - assertEquals(0, mTestObject.waitForShortValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setIntValue({foo: 42});"); - assertEquals(0, mTestObject.waitForIntValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setLongValue({foo: 42});"); - assertEquals(0L, mTestObject.waitForLongValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setFloatValue({foo: 42});"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setDoubleValue({foo: 42});"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setBooleanValue({foo: 42});"); - assertFalse(mTestObject.waitForBooleanValue()); - } - - // Test passing a Java object to a method of an injected object. Note that - // this test requires being able to return objects from the methods of - // injected objects. This is tested elsewhere. - public void testPassJavaObject() throws Throwable { - executeJavaScript("testObject.setObjectValue(testObject.getObjectInstance());"); - assertTrue(mTestObject.getObjectInstance() == mTestObject.waitForObjectValue()); - executeJavaScript("testObject.setObjectValue(testObject.getCustomTypeInstance());"); - assertTrue(mTestObject.getCustomTypeInstance() == mTestObject.waitForObjectValue()); - - executeJavaScript("testObject.setCustomTypeValue(testObject.getObjectInstance());"); - assertTrue(mTestObject.getObjectInstance() == mTestObject.waitForCustomTypeValue()); - executeJavaScript("testObject.setCustomTypeValue(testObject.getCustomTypeInstance());"); - assertTrue(mTestObject.getCustomTypeInstance() == mTestObject.waitForCustomTypeValue()); - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception, as the types are unrelated. - executeJavaScript("testObject.setCustomTypeValue(testObject.getCustomType2Instance());"); - assertTrue(mTestObject.getCustomType2Instance() == - (Object)mTestObject.waitForCustomTypeValue()); - - // LIVECONNECT_COMPLIANCE: Should call toString() on object. - executeJavaScript("testObject.setStringValue(testObject.getObjectInstance());"); - assertEquals("undefined", mTestObject.waitForStringValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setByteValue(testObject.getObjectInstance());"); - assertEquals(0, mTestObject.waitForByteValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setCharValue(testObject.getObjectInstance());"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setShortValue(testObject.getObjectInstance());"); - assertEquals(0, mTestObject.waitForShortValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setIntValue(testObject.getObjectInstance());"); - assertEquals(0, mTestObject.waitForIntValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setLongValue(testObject.getObjectInstance());"); - assertEquals(0L, mTestObject.waitForLongValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setFloatValue(testObject.getObjectInstance());"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setDoubleValue(testObject.getObjectInstance());"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); - - // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. - executeJavaScript("testObject.setBooleanValue(testObject.getObjectInstance());"); - assertFalse(mTestObject.waitForBooleanValue()); - } - - // Test passing JavaScript null to a method of an injected object. - public void testPassNull() throws Throwable { - executeJavaScript("testObject.setObjectValue(null);"); - assertNull(mTestObject.waitForObjectValue()); - - executeJavaScript("testObject.setCustomTypeValue(null);"); - assertNull(mTestObject.waitForCustomTypeValue()); - - executeJavaScript("testObject.setStringValue(null);"); - assertNull(mTestObject.waitForStringValue()); - - executeJavaScript("testObject.setByteValue(null);"); - assertEquals(0, mTestObject.waitForByteValue()); - - executeJavaScript("testObject.setCharValue(null);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - - executeJavaScript("testObject.setShortValue(null);"); - assertEquals(0, mTestObject.waitForShortValue()); - - executeJavaScript("testObject.setIntValue(null);"); - assertEquals(0, mTestObject.waitForIntValue()); - - executeJavaScript("testObject.setLongValue(null);"); - assertEquals(0L, mTestObject.waitForLongValue()); - - executeJavaScript("testObject.setFloatValue(null);"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); - - executeJavaScript("testObject.setDoubleValue(null);"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); - - executeJavaScript("testObject.setBooleanValue(null);"); - assertFalse(mTestObject.waitForBooleanValue()); - } - - // Test passing JavaScript undefined to a method of an injected object. - public void testPassUndefined() throws Throwable { - executeJavaScript("testObject.setObjectValue(undefined);"); - assertNull(mTestObject.waitForObjectValue()); - - executeJavaScript("testObject.setCustomTypeValue(undefined);"); - assertNull(mTestObject.waitForCustomTypeValue()); - - // LIVECONNECT_COMPLIANCE: Should be NULL. - executeJavaScript("testObject.setStringValue(undefined);"); - assertEquals("undefined", mTestObject.waitForStringValue()); - - executeJavaScript("testObject.setByteValue(undefined);"); - assertEquals(0, mTestObject.waitForByteValue()); - - executeJavaScript("testObject.setCharValue(undefined);"); - assertEquals('\u0000', mTestObject.waitForCharValue()); - - executeJavaScript("testObject.setShortValue(undefined);"); - assertEquals(0, mTestObject.waitForShortValue()); - - executeJavaScript("testObject.setIntValue(undefined);"); - assertEquals(0, mTestObject.waitForIntValue()); - - executeJavaScript("testObject.setLongValue(undefined);"); - assertEquals(0L, mTestObject.waitForLongValue()); - - executeJavaScript("testObject.setFloatValue(undefined);"); - assertEquals(0.0f, mTestObject.waitForFloatValue()); - - executeJavaScript("testObject.setDoubleValue(undefined);"); - assertEquals(0.0, mTestObject.waitForDoubleValue()); - - executeJavaScript("testObject.setBooleanValue(undefined);"); - assertFalse(mTestObject.waitForBooleanValue()); - } -} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeFieldsTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeFieldsTest.java deleted file mode 100644 index 0ccd175..0000000 --- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeFieldsTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/** - * Part of the test suite for the WebView's Java Bridge. This test tests the - * use of fields. - * - * To run this test ... - * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeFieldsTest \ - * com.android.webviewtests/android.test.InstrumentationTestRunner - */ - -package com.android.webviewtests; - -public class JavaBridgeFieldsTest extends JavaBridgeTestBase { - private class TestObject extends Controller { - private String mStringValue; - - // These methods are used to control the test. - public synchronized void setStringValue(String x) { - mStringValue = x; - notifyResultIsReady(); - } - public synchronized String waitForStringValue() { - waitForResult(); - return mStringValue; - } - - public boolean booleanField = true; - public byte byteField = 42; - public char charField = '\u002A'; - public short shortField = 42; - public int intField = 42; - public long longField = 42L; - public float floatField = 42.0f; - public double doubleField = 42.0; - public String stringField = "foo"; - public Object objectField = new Object(); - public CustomType customTypeField = new CustomType(); - } - - // A custom type used when testing passing objects. - private class CustomType { - } - - TestObject mTestObject; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mTestObject = new TestObject(); - setUpWebView(mTestObject, "testObject"); - } - - // Note that this requires that we can pass a JavaScript string to Java. - protected String executeJavaScriptAndGetStringResult(String script) throws Throwable { - executeJavaScript("testObject.setStringValue(" + script + ");"); - return mTestObject.waitForStringValue(); - } - - // The Java bridge does not provide access to fields. - // FIXME: Consider providing support for this. See See b/4408210. - public void testFieldTypes() throws Throwable { - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.booleanField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.byteField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.charField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.shortField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.intField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.longField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.floatField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.doubleField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.objectField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.stringField")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.customTypeField")); - } -} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeReturnValuesTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeReturnValuesTest.java deleted file mode 100644 index 44d5cc6..0000000 --- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeReturnValuesTest.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/** - * Part of the test suite for the WebView's Java Bridge. This test checks that - * we correctly convert Java values to JavaScript values when returning them - * from the methods of injected Java objects. - * - * The conversions should follow - * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in - * which the implementation differs from the spec are marked with - * LIVECONNECT_COMPLIANCE. - * FIXME: Consider making our implementation more compliant, if it will not - * break backwards-compatibility. See b/4408210. - * - * To run this test ... - * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeReturnValuesTest \ - * com.android.webviewtests/android.test.InstrumentationTestRunner - */ - -package com.android.webviewtests; - -public class JavaBridgeReturnValuesTest extends JavaBridgeTestBase { - // An instance of this class is injected into the page to test returning - // Java values to JavaScript. - private class TestObject extends Controller { - private String mStringValue; - private boolean mBooleanValue; - - // These four methods are used to control the test. - public synchronized void setStringValue(String x) { - mStringValue = x; - notifyResultIsReady(); - } - public synchronized String waitForStringValue() { - waitForResult(); - return mStringValue; - } - public synchronized void setBooleanValue(boolean x) { - mBooleanValue = x; - notifyResultIsReady(); - } - public synchronized boolean waitForBooleanValue() { - waitForResult(); - return mBooleanValue; - } - - public boolean getBooleanValue() { - return true; - } - public byte getByteValue() { - return 42; - } - public char getCharValue() { - return '\u002A'; - } - public short getShortValue() { - return 42; - } - public int getIntValue() { - return 42; - } - public long getLongValue() { - return 42L; - } - public float getFloatValue() { - return 42.1f; - } - public float getFloatValueNoDecimal() { - return 42.0f; - } - public double getDoubleValue() { - return 42.1; - } - public double getDoubleValueNoDecimal() { - return 42.0; - } - public String getStringValue() { - return "foo"; - } - public String getEmptyStringValue() { - return ""; - } - public String getNullStringValue() { - return null; - } - public Object getObjectValue() { - return new Object(); - } - public Object getNullObjectValue() { - return null; - } - public CustomType getCustomTypeValue() { - return new CustomType(); - } - public void getVoidValue() { - } - } - - // A custom type used when testing passing objects. - private class CustomType { - } - - TestObject mTestObject; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mTestObject = new TestObject(); - setUpWebView(mTestObject, "testObject"); - } - - // Note that this requires that we can pass a JavaScript string to Java. - protected String executeJavaScriptAndGetStringResult(String script) throws Throwable { - executeJavaScript("testObject.setStringValue(" + script + ");"); - return mTestObject.waitForStringValue(); - } - - // Note that this requires that we can pass a JavaScript boolean to Java. - private boolean executeJavaScriptAndGetBooleanResult(String script) throws Throwable { - executeJavaScript("testObject.setBooleanValue(" + script + ");"); - return mTestObject.waitForBooleanValue(); - } - - public void testMethodReturnTypes() throws Throwable { - assertEquals("boolean", - executeJavaScriptAndGetStringResult("typeof testObject.getBooleanValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getByteValue()")); - // char values are returned to JavaScript as numbers. - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getCharValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getShortValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getIntValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getLongValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getFloatValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getFloatValueNoDecimal()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getDoubleValue()")); - assertEquals("number", - executeJavaScriptAndGetStringResult("typeof testObject.getDoubleValueNoDecimal()")); - assertEquals("string", - executeJavaScriptAndGetStringResult("typeof testObject.getStringValue()")); - assertEquals("string", - executeJavaScriptAndGetStringResult("typeof testObject.getEmptyStringValue()")); - // LIVECONNECT_COMPLIANCE: This should have type object. - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.getNullStringValue()")); - assertEquals("object", - executeJavaScriptAndGetStringResult("typeof testObject.getObjectValue()")); - assertEquals("object", - executeJavaScriptAndGetStringResult("typeof testObject.getNullObjectValue()")); - assertEquals("object", - executeJavaScriptAndGetStringResult("typeof testObject.getCustomTypeValue()")); - assertEquals("undefined", - executeJavaScriptAndGetStringResult("typeof testObject.getVoidValue()")); - } - - public void testMethodReturnValues() throws Throwable { - // We do the string comparison in JavaScript, to avoid relying on the - // coercion algorithm from JavaScript to Java. - assertTrue(executeJavaScriptAndGetBooleanResult("testObject.getBooleanValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getByteValue()")); - // char values are returned to JavaScript as numbers. - assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getCharValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getShortValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getIntValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getLongValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult( - "Math.abs(42.1 - testObject.getFloatValue()) < 0.001")); - assertTrue(executeJavaScriptAndGetBooleanResult( - "42.0 === testObject.getFloatValueNoDecimal()")); - assertTrue(executeJavaScriptAndGetBooleanResult( - "Math.abs(42.1 - testObject.getDoubleValue()) < 0.001")); - assertTrue(executeJavaScriptAndGetBooleanResult( - "42.0 === testObject.getDoubleValueNoDecimal()")); - assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.getStringValue()")); - assertEquals("", executeJavaScriptAndGetStringResult("testObject.getEmptyStringValue()")); - assertTrue(executeJavaScriptAndGetBooleanResult("undefined === testObject.getVoidValue()")); - } -} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java deleted file mode 100644 index a451015..0000000 --- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/** - * Common functionality for testing the WebView's Java Bridge. - */ - -package com.android.webviewtests; - -import android.test.ActivityInstrumentationTestCase2; -import android.util.Log; -import android.webkit.WebView; -import android.webkit.WebViewClient; - -import junit.framework.Assert; - -public class JavaBridgeTestBase extends ActivityInstrumentationTestCase2<WebViewStubActivity> { - protected class TestWebViewClient extends WebViewClient { - private boolean mIsPageFinished; - @Override - public synchronized void onPageFinished(WebView webView, String url) { - mIsPageFinished = true; - notify(); - } - public synchronized void waitForOnPageFinished() throws RuntimeException { - while (!mIsPageFinished) { - try { - wait(5000); - } catch (Exception e) { - continue; - } - if (!mIsPageFinished) { - throw new RuntimeException("Timed out waiting for onPageFinished()"); - } - } - mIsPageFinished = false; - } - } - - protected class Controller { - private boolean mIsResultReady; - - protected synchronized void notifyResultIsReady() { - mIsResultReady = true; - notify(); - } - protected synchronized void waitForResult() { - while (!mIsResultReady) { - try { - wait(5000); - } catch (Exception e) { - continue; - } - if (!mIsResultReady) { - Assert.fail("Wait timed out"); - } - } - mIsResultReady = false; - } - } - - protected TestWebViewClient mWebViewClient; - - public JavaBridgeTestBase() { - super(WebViewStubActivity.class); - } - - // Sets up the WebView and injects the supplied object. Intended to be called from setUp(). - protected void setUpWebView(final Object object, final String name) throws Exception { - mWebViewClient = new TestWebViewClient(); - // This starts the activity, so must be called on the test thread. - final WebViewStubActivity activity = getActivity(); - // On the UI thread, load an empty page and wait for it to finish - // loading so that the Java object is injected. - try { - runTestOnUiThread(new Runnable() { - @Override - public void run() { - WebView webView = activity.getWebView(); - webView.addJavascriptInterface(object, name); - webView.getSettings().setJavaScriptEnabled(true); - webView.setWebViewClient(mWebViewClient); - webView.loadData("<!DOCTYPE html><title></title>", "text/html", null); - } - }); - mWebViewClient.waitForOnPageFinished(); - } catch (Throwable e) { - throw new RuntimeException("Failed to set up WebView: " + Log.getStackTraceString(e)); - } - } - - protected void executeJavaScript(final String script) throws Throwable { - runTestOnUiThread(new Runnable() { - @Override - public void run() { - // When a JavaScript URL is executed, if the value of the last - // expression evaluated is not 'undefined', this value is - // converted to a string and used as the new document for the - // frame. We don't want this behaviour, so wrap the script in - // an anonymous function. - getWebView().loadUrl("javascript:(function() { " + script + " })()"); - } - }); - } - - protected WebView getWebView() { - return getActivity().getWebView(); - } -} diff --git a/tests/notification/Android.mk b/tests/notification/Android.mk new file mode 100644 index 0000000..0669553 --- /dev/null +++ b/tests/notification/Android.mk @@ -0,0 +1,16 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +# We only want this apk build for tests. +LOCAL_MODULE_TAGS := tests + +# Include all test java files. +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_JAVA_LIBRARIES := android.test.runner +LOCAL_PACKAGE_NAME := NotificationTests + +LOCAL_SDK_VERSION := 21 + +include $(BUILD_PACKAGE) + diff --git a/tests/notification/AndroidManifest.xml b/tests/notification/AndroidManifest.xml new file mode 100644 index 0000000..7cee00a --- /dev/null +++ b/tests/notification/AndroidManifest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.tests.notification" + > + <application> + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation + android:name="android.test.InstrumentationTestRunner" + android:targetPackage="com.android.frameworks.tests.notification" + android:label="Frameworks Notification Tests" /> +</manifest> diff --git a/tests/notification/res/drawable-nodpi/arubin_hed.jpeg b/tests/notification/res/drawable-nodpi/arubin_hed.jpeg Binary files differnew file mode 100644 index 0000000..c6d8ae9 --- /dev/null +++ b/tests/notification/res/drawable-nodpi/arubin_hed.jpeg diff --git a/tests/notification/res/drawable-nodpi/bucket.png b/tests/notification/res/drawable-nodpi/bucket.png Binary files differnew file mode 100644 index 0000000..c865649 --- /dev/null +++ b/tests/notification/res/drawable-nodpi/bucket.png diff --git a/tests/notification/res/drawable-nodpi/matias_hed.jpg b/tests/notification/res/drawable-nodpi/matias_hed.jpg Binary files differnew file mode 100644 index 0000000..8cc3081 --- /dev/null +++ b/tests/notification/res/drawable-nodpi/matias_hed.jpg diff --git a/tests/notification/res/drawable-nodpi/page_hed.jpg b/tests/notification/res/drawable-nodpi/page_hed.jpg Binary files differnew file mode 100644 index 0000000..ea950c8 --- /dev/null +++ b/tests/notification/res/drawable-nodpi/page_hed.jpg diff --git a/tests/notification/res/drawable-nodpi/romainguy_hed.jpg b/tests/notification/res/drawable-nodpi/romainguy_hed.jpg Binary files differnew file mode 100644 index 0000000..5b7643e --- /dev/null +++ b/tests/notification/res/drawable-nodpi/romainguy_hed.jpg diff --git a/tests/notification/res/drawable-nodpi/romainguy_rockaway.jpg b/tests/notification/res/drawable-nodpi/romainguy_rockaway.jpg Binary files differnew file mode 100644 index 0000000..68473ba --- /dev/null +++ b/tests/notification/res/drawable-nodpi/romainguy_rockaway.jpg diff --git a/tests/notification/res/drawable-xhdpi/add.png b/tests/notification/res/drawable-xhdpi/add.png Binary files differnew file mode 100644 index 0000000..7226b3d --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/add.png diff --git a/tests/notification/res/drawable-xhdpi/ic_dial_action_call.png b/tests/notification/res/drawable-xhdpi/ic_dial_action_call.png Binary files differnew file mode 100644 index 0000000..ca20a91 --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/ic_dial_action_call.png diff --git a/tests/notification/res/drawable-xhdpi/ic_end_call.png b/tests/notification/res/drawable-xhdpi/ic_end_call.png Binary files differnew file mode 100644 index 0000000..c464a6d --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/ic_end_call.png diff --git a/tests/notification/res/drawable-xhdpi/ic_media_next.png b/tests/notification/res/drawable-xhdpi/ic_media_next.png Binary files differnew file mode 100644 index 0000000..4def965 --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/ic_media_next.png diff --git a/tests/notification/res/drawable-xhdpi/ic_menu_upload.png b/tests/notification/res/drawable-xhdpi/ic_menu_upload.png Binary files differnew file mode 100644 index 0000000..f1438ed --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/ic_menu_upload.png diff --git a/tests/notification/res/drawable-xhdpi/icon.png b/tests/notification/res/drawable-xhdpi/icon.png Binary files differnew file mode 100644 index 0000000..189e85b --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/icon.png diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_alarm.png b/tests/notification/res/drawable-xhdpi/stat_notify_alarm.png Binary files differnew file mode 100644 index 0000000..658d04f --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/stat_notify_alarm.png diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_calendar.png b/tests/notification/res/drawable-xhdpi/stat_notify_calendar.png Binary files differnew file mode 100644 index 0000000..5ae7782 --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/stat_notify_calendar.png diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_email.png b/tests/notification/res/drawable-xhdpi/stat_notify_email.png Binary files differnew file mode 100644 index 0000000..23c4672 --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/stat_notify_email.png diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_missed_call.png b/tests/notification/res/drawable-xhdpi/stat_notify_missed_call.png Binary files differnew file mode 100644 index 0000000..8719eff --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/stat_notify_missed_call.png diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_sms.png b/tests/notification/res/drawable-xhdpi/stat_notify_sms.png Binary files differnew file mode 100644 index 0000000..323cb3d --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/stat_notify_sms.png diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_snooze.png b/tests/notification/res/drawable-xhdpi/stat_notify_snooze.png Binary files differnew file mode 100644 index 0000000..26dcda35 --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/stat_notify_snooze.png diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_snooze_longer.png b/tests/notification/res/drawable-xhdpi/stat_notify_snooze_longer.png Binary files differnew file mode 100644 index 0000000..b8b2f8a --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/stat_notify_snooze_longer.png diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_talk_text.png b/tests/notification/res/drawable-xhdpi/stat_notify_talk_text.png Binary files differnew file mode 100644 index 0000000..12cae9f --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/stat_notify_talk_text.png diff --git a/tests/notification/res/drawable-xhdpi/stat_sys_phone_call.png b/tests/notification/res/drawable-xhdpi/stat_sys_phone_call.png Binary files differnew file mode 100644 index 0000000..db42b7c --- /dev/null +++ b/tests/notification/res/drawable-xhdpi/stat_sys_phone_call.png diff --git a/tests/notification/res/layout/full_screen.xml b/tests/notification/res/layout/full_screen.xml new file mode 100644 index 0000000..6ff7552 --- /dev/null +++ b/tests/notification/res/layout/full_screen.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ImageView + android:layout_height="match_parent" + android:layout_width="match_parent" + android:src="@drawable/page_hed" + android:onClick="dismiss" + /> +</FrameLayout>
\ No newline at end of file diff --git a/tests/notification/res/layout/main.xml b/tests/notification/res/layout/main.xml new file mode 100644 index 0000000..f5a740f --- /dev/null +++ b/tests/notification/res/layout/main.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + > + <LinearLayout android:id="@+id/linearLayout1" android:orientation="vertical" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_width="match_parent" android:layout_margin="35dp"> + <Button android:id="@+id/button1" android:text="@string/post_button_label" android:layout_height="wrap_content" android:layout_width="match_parent" android:onClick="doPost"></Button> + <Button android:id="@+id/button2" android:text="@string/remove_button_label" android:layout_height="wrap_content" android:layout_width="match_parent" android:onClick="doRemove"></Button> + </LinearLayout> +</FrameLayout> diff --git a/tests/notification/res/values/dimens.xml b/tests/notification/res/values/dimens.xml new file mode 100644 index 0000000..21e7bc3 --- /dev/null +++ b/tests/notification/res/values/dimens.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +** Copyright 2012, 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. +*/ +--> +<resources> + <!-- The width of the big icons in notifications. --> + <dimen name="notification_large_icon_width">64dp</dimen> + <!-- The width of the big icons in notifications. --> + <dimen name="notification_large_icon_height">64dp</dimen> +</resources> diff --git a/tests/notification/res/values/strings.xml b/tests/notification/res/values/strings.xml new file mode 100644 index 0000000..80bf103 --- /dev/null +++ b/tests/notification/res/values/strings.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="hello">Hello World, NotificationShowcaseActivity!</string> + <string name="app_name">NotificationShowcase</string> + <string name="post_button_label">Post Notifications</string> + <string name="remove_button_label">Remove Notifications</string> + <string name="answered">call answered</string> + <string name="ignored">call ignored</string> + <string name="full_screen_name">Full Screen Activity</string> +</resources> diff --git a/tests/notification/src/com/android/frameworks/tests/notification/NotificationTests.java b/tests/notification/src/com/android/frameworks/tests/notification/NotificationTests.java new file mode 100644 index 0000000..7cda977 --- /dev/null +++ b/tests/notification/src/com/android/frameworks/tests/notification/NotificationTests.java @@ -0,0 +1,494 @@ +/* + * Copyright (C) 2015 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.app; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Typeface; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Parcel; +import android.os.SystemClock; +import android.provider.ContactsContract; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.Suppress; +import android.text.SpannableStringBuilder; +import android.text.TextUtils; +import android.text.style.StyleSpan; +import android.util.Log; +import android.view.View; +import android.widget.Toast; + +import java.lang.reflect.Method; +import java.lang.InterruptedException; +import java.lang.NoSuchMethodError; +import java.lang.NoSuchMethodException; +import java.util.ArrayList; + +import com.android.frameworks.tests.notification.R; + +public class NotificationTests extends AndroidTestCase { + private static final String TAG = "NOTEST"; + public static void L(String msg, Object... args) { + Log.v(TAG, (args == null || args.length == 0) ? msg : String.format(msg, args)); + } + + public static final String ACTION_CREATE = "create"; + public static final int NOTIFICATION_ID = 31338; + + public static final boolean SHOW_PHONE_CALL = false; + public static final boolean SHOW_INBOX = true; + public static final boolean SHOW_BIG_TEXT = true; + public static final boolean SHOW_BIG_PICTURE = true; + public static final boolean SHOW_MEDIA = true; + public static final boolean SHOW_STOPWATCH = false; + public static final boolean SHOW_SOCIAL = false; + public static final boolean SHOW_CALENDAR = false; + public static final boolean SHOW_PROGRESS = false; + + private static Bitmap getBitmap(Context context, int resId) { + int largeIconWidth = (int) context.getResources() + .getDimension(R.dimen.notification_large_icon_width); + int largeIconHeight = (int) context.getResources() + .getDimension(R.dimen.notification_large_icon_height); + Drawable d = context.getResources().getDrawable(resId); + Bitmap b = Bitmap.createBitmap(largeIconWidth, largeIconHeight, Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(b); + d.setBounds(0, 0, largeIconWidth, largeIconHeight); + d.draw(c); + return b; + } + + private static PendingIntent makeEmailIntent(Context context, String who) { + final Intent intent = new Intent(android.content.Intent.ACTION_SENDTO, + Uri.parse("mailto:" + who)); + return PendingIntent.getActivity( + context, 0, intent, + PendingIntent.FLAG_CANCEL_CURRENT); + } + + static final String[] LINES = new String[] { + "Uh oh", + "Getting kicked out of this room", + "I'll be back in 5-10 minutes.", + "And now \u2026 I have to find my shoes. \uD83D\uDC63", + "\uD83D\uDC5F \uD83D\uDC5F", + "\uD83D\uDC60 \uD83D\uDC60", + }; + static final int MAX_LINES = 5; + public static Notification makeBigTextNotification(Context context, int update, int id, + long when) { + String personUri = null; + /* + Cursor c = null; + try { + String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY }; + String selections = ContactsContract.Contacts.DISPLAY_NAME + " = 'Mike Cleron'"; + final ContentResolver contentResolver = context.getContentResolver(); + c = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, + projection, selections, null, null); + if (c != null && c.getCount() > 0) { + c.moveToFirst(); + int lookupIdx = c.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY); + int idIdx = c.getColumnIndex(ContactsContract.Contacts._ID); + String lookupKey = c.getString(lookupIdx); + long contactId = c.getLong(idIdx); + Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey); + personUri = lookupUri.toString(); + } + } finally { + if (c != null) { + c.close(); + } + } + if (TextUtils.isEmpty(personUri)) { + Log.w(TAG, "failed to find contact for Mike Cleron"); + } else { + Log.w(TAG, "Mike Cleron is " + personUri); + } + */ + + StringBuilder longSmsText = new StringBuilder(); + int end = 2 + update; + if (end > LINES.length) { + end = LINES.length; + } + final int start = Math.max(0, end - MAX_LINES); + for (int i=start; i<end; i++) { + if (i >= LINES.length) break; + if (i > start) longSmsText.append("\n"); + longSmsText.append(LINES[i]); + } + if (update > 2) { + when = System.currentTimeMillis(); + } + Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle() + .bigText(longSmsText); + Notification bigText = new Notification.Builder(context) + .setContentTitle("Mike Cleron") + .setContentIntent(ToastService.getPendingIntent(context, "Clicked on bigText")) + .setContentText(longSmsText) + //.setTicker("Mike Cleron: " + longSmsText) + .setWhen(when) + .setLargeIcon(getBitmap(context, R.drawable.bucket)) + .setPriority(Notification.PRIORITY_HIGH) + .setNumber(update) + .setSmallIcon(R.drawable.stat_notify_talk_text) + .setStyle(bigTextStyle) + .setDefaults(Notification.DEFAULT_SOUND) + .addPerson(personUri) + .build(); + return bigText; + } + + public static Notification makeUploadNotification(Context context, int progress, long when) { + Notification.Builder uploadNotification = new Notification.Builder(context) + .setContentTitle("File Upload") + .setContentText("foo.txt") + .setPriority(Notification.PRIORITY_MIN) + .setContentIntent(ToastService.getPendingIntent(context, "Clicked on Upload")) + .setWhen(when) + .setSmallIcon(R.drawable.ic_menu_upload) + .setProgress(100, Math.min(progress, 100), false); + return uploadNotification.build(); + } + + static SpannableStringBuilder BOLD(CharSequence str) { + final SpannableStringBuilder ssb = new SpannableStringBuilder(str); + ssb.setSpan(new StyleSpan(Typeface.BOLD), 0, ssb.length(), 0); + return ssb; + } + + public static class ToastService extends IntentService { + + private static final String TAG = "ToastService"; + + private static final String ACTION_TOAST = "toast"; + + private Handler handler; + + public ToastService() { + super(TAG); + } + public ToastService(String name) { + super(name); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + handler = new Handler(); + return super.onStartCommand(intent, flags, startId); + } + + @Override + protected void onHandleIntent(Intent intent) { + Log.v(TAG, "clicked a thing! intent=" + intent.toString()); + if (intent.hasExtra("text")) { + final String text = intent.getStringExtra("text"); + handler.post(new Runnable() { + @Override + public void run() { + Toast.makeText(ToastService.this, text, Toast.LENGTH_LONG).show(); + Log.v(TAG, "toast " + text); + } + }); + } + } + + public static PendingIntent getPendingIntent(Context context, String text) { + Intent toastIntent = new Intent(context, ToastService.class); + toastIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + toastIntent.setAction(ACTION_TOAST + ":" + text); // one per toast message + toastIntent.putExtra("text", text); + PendingIntent pi = PendingIntent.getService( + context, 58, toastIntent, PendingIntent.FLAG_UPDATE_CURRENT); + return pi; + } + } + + public static void sleepIfYouCan(int ms) { + try { + Thread.sleep(ms); + } catch (InterruptedException e) {} + } + + @Override + public void setUp() throws Exception { + super.setUp(); + } + + public static String summarize(Notification n) { + return String.format("<notif title=\"%s\" icon=0x%08x view=%s>", + n.extras.get(Notification.EXTRA_TITLE), + n.icon, + String.valueOf(n.contentView)); + } + + public void testCreate() throws Exception { + ArrayList<Notification> mNotifications = new ArrayList<Notification>(); + NotificationManager noMa = + (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); + + L("Constructing notifications..."); + if (SHOW_BIG_TEXT) { + int bigtextId = mNotifications.size(); + final long time = SystemClock.currentThreadTimeMillis(); + final Notification n = makeBigTextNotification(mContext, 0, bigtextId, System.currentTimeMillis()); + L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); + mNotifications.add(n); + } + + int uploadId = mNotifications.size(); + long uploadWhen = System.currentTimeMillis(); + + if (SHOW_PROGRESS) { + mNotifications.add(makeUploadNotification(mContext, 0, uploadWhen)); + } + + if (SHOW_PHONE_CALL) { + int phoneId = mNotifications.size(); + final PendingIntent fullscreenIntent + = FullScreenActivity.getPendingIntent(mContext, phoneId); + final long time = SystemClock.currentThreadTimeMillis(); + Notification phoneCall = new Notification.Builder(mContext) + .setContentTitle("Incoming call") + .setContentText("Matias Duarte") + .setLargeIcon(getBitmap(mContext, R.drawable.matias_hed)) + .setSmallIcon(R.drawable.stat_sys_phone_call) + .setDefaults(Notification.DEFAULT_SOUND) + .setPriority(Notification.PRIORITY_MAX) + .setContentIntent(fullscreenIntent) + .setFullScreenIntent(fullscreenIntent, true) + .addAction(R.drawable.ic_dial_action_call, "Answer", + ToastService.getPendingIntent(mContext, "Clicked on Answer")) + .addAction(R.drawable.ic_end_call, "Ignore", + ToastService.getPendingIntent(mContext, "Clicked on Ignore")) + .setOngoing(true) + .addPerson(Uri.fromParts("tel", "1 (617) 555-1212", null).toString()) + .build(); + L(" %s: create=%dms", phoneCall.toString(), SystemClock.currentThreadTimeMillis() - time); + mNotifications.add(phoneCall); + } + + if (SHOW_STOPWATCH) { + final long time = SystemClock.currentThreadTimeMillis(); + final Notification n = new Notification.Builder(mContext) + .setContentTitle("Stopwatch PRO") + .setContentText("Counting up") + .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on Stopwatch")) + .setSmallIcon(R.drawable.stat_notify_alarm) + .setUsesChronometer(true) + .build(); + L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); + mNotifications.add(n); + } + + if (SHOW_CALENDAR) { + final long time = SystemClock.currentThreadTimeMillis(); + final Notification n = new Notification.Builder(mContext) + .setContentTitle("J Planning") + .setContentText("The Botcave") + .setWhen(System.currentTimeMillis()) + .setSmallIcon(R.drawable.stat_notify_calendar) + .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on calendar event")) + .setContentInfo("7PM") + .addAction(R.drawable.stat_notify_snooze, "+10 min", + ToastService.getPendingIntent(mContext, "snoozed 10 min")) + .addAction(R.drawable.stat_notify_snooze_longer, "+1 hour", + ToastService.getPendingIntent(mContext, "snoozed 1 hr")) + .addAction(R.drawable.stat_notify_email, "Email", + ToastService.getPendingIntent(mContext, + "Congratulations, you just destroyed someone's inbox zero")) + .build(); + L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); + mNotifications.add(n); + } + + if (SHOW_BIG_PICTURE) { + BitmapDrawable d = + (BitmapDrawable) mContext.getResources().getDrawable(R.drawable.romainguy_rockaway); + final long time = SystemClock.currentThreadTimeMillis(); + final Notification n = new Notification.Builder(mContext) + .setContentTitle("Romain Guy") + .setContentText("I was lucky to find a Canon 5D Mk III at a local Bay Area " + + "store last week but I had not been able to try it in the field " + + "until tonight. After a few days of rain the sky finally cleared " + + "up. Rockaway Beach did not disappoint and I was finally able to " + + "see what my new camera feels like when shooting landscapes.") + .setSmallIcon(android.R.drawable.stat_notify_chat) + .setContentIntent( + ToastService.getPendingIntent(mContext, "Clicked picture")) + .setLargeIcon(getBitmap(mContext, R.drawable.romainguy_hed)) + .addAction(R.drawable.add, "Add to Gallery", + ToastService.getPendingIntent(mContext, "Added")) + .setStyle(new Notification.BigPictureStyle() + .bigPicture(d.getBitmap())) + .build(); + L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); + mNotifications.add(n); + } + + if (SHOW_INBOX) { + final long time = SystemClock.currentThreadTimeMillis(); + final Notification n = new Notification.Builder(mContext) + .setContentTitle("New mail") + .setContentText("3 new messages") + .setSubText("example@gmail.com") + .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on Mail")) + .setSmallIcon(R.drawable.stat_notify_email) + .setStyle(new Notification.InboxStyle() + .setSummaryText("example@gmail.com") + .addLine(BOLD("Alice:").append(" hey there!")) + .addLine(BOLD("Bob:").append(" hi there!")) + .addLine(BOLD("Charlie:").append(" Iz IN UR EMAILZ!!")) + ).build(); + L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); + mNotifications.add(n); + } + + if (SHOW_SOCIAL) { + final long time = SystemClock.currentThreadTimeMillis(); + final Notification n = new Notification.Builder(mContext) + .setContentTitle("Social Network") + .setContentText("You were mentioned in a post") + .setContentInfo("example@gmail.com") + .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on Social")) + .setSmallIcon(android.R.drawable.stat_notify_chat) + .setPriority(Notification.PRIORITY_LOW) + .build(); + L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time); + mNotifications.add(n); + } + + L("Posting notifications..."); + for (int i=0; i<mNotifications.size(); i++) { + final int count = 4; + for (int j=0; j<count; j++) { + long time = SystemClock.currentThreadTimeMillis(); + final Notification n = mNotifications.get(i); + noMa.notify(NOTIFICATION_ID + i, n); + time = SystemClock.currentThreadTimeMillis() - time; + L(" %s: notify=%dms (%d/%d)", summarize(n), time, + j + 1, count); + sleepIfYouCan(150); + } + } + + sleepIfYouCan(1000); + + L("Canceling notifications..."); + for (int i=0; i<mNotifications.size(); i++) { + final Notification n = mNotifications.get(i); + long time = SystemClock.currentThreadTimeMillis(); + noMa.cancel(NOTIFICATION_ID + i); + time = SystemClock.currentThreadTimeMillis() - time; + L(" %s: cancel=%dms", summarize(n), time); + } + + sleepIfYouCan(500); + + L("Parceling notifications..."); + // we want to be able to use this test on older OSes that do not have getBlobAshmemSize + Method getBlobAshmemSize = null; + try { + getBlobAshmemSize = Parcel.class.getMethod("getBlobAshmemSize"); + } catch (NoSuchMethodException ex) { + } + for (int i=0; i<mNotifications.size(); i++) { + Parcel p = Parcel.obtain(); + { + final Notification n = mNotifications.get(i); + long time = SystemClock.currentThreadTimeMillis(); + n.writeToParcel(p, 0); + time = SystemClock.currentThreadTimeMillis() - time; + L(" %s: write parcel=%dms size=%d ashmem=%s", + summarize(n), time, p.dataPosition(), + (getBlobAshmemSize != null) + ? getBlobAshmemSize.invoke(p) + : "???"); + p.setDataPosition(0); + } + + long time = SystemClock.currentThreadTimeMillis(); + final Notification n2 = Notification.CREATOR.createFromParcel(p); + time = SystemClock.currentThreadTimeMillis() - time; + L(" %s: parcel read=%dms", summarize(n2), time); + + time = SystemClock.currentThreadTimeMillis(); + noMa.notify(NOTIFICATION_ID + i, n2); + time = SystemClock.currentThreadTimeMillis() - time; + L(" %s: notify=%dms", summarize(n2), time); + } + + sleepIfYouCan(500); + + L("Canceling notifications..."); + for (int i=0; i<mNotifications.size(); i++) { + long time = SystemClock.currentThreadTimeMillis(); + final Notification n = mNotifications.get(i); + noMa.cancel(NOTIFICATION_ID + i); + time = SystemClock.currentThreadTimeMillis() - time; + L(" %s: cancel=%dms", summarize(n), time); + } + + +// if (SHOW_PROGRESS) { +// ProgressService.startProgressUpdater(this, uploadId, uploadWhen, 0); +// } + } + + public static class FullScreenActivity extends Activity { + public static final String EXTRA_ID = "id"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.full_screen); + final Intent intent = getIntent(); + if (intent != null && intent.hasExtra(EXTRA_ID)) { + final int id = intent.getIntExtra(EXTRA_ID, -1); + if (id >= 0) { + NotificationManager noMa = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + noMa.cancel(NOTIFICATION_ID + id); + } + } + } + + public void dismiss(View v) { + finish(); + } + + public static PendingIntent getPendingIntent(Context context, int id) { + Intent fullScreenIntent = new Intent(context, FullScreenActivity.class); + fullScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + fullScreenIntent.putExtra(EXTRA_ID, id); + PendingIntent pi = PendingIntent.getActivity( + context, 22, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT); + return pi; + } + } +} + diff --git a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java index 3bd35a7..3791d02 100644 --- a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java @@ -47,17 +47,7 @@ public class ActivityManagerPermissionTests extends TestCase { } catch (RemoteException e) { fail("Unexpected remote exception"); } - - try { - mAm.moveTaskToBack(-1); - fail("IActivityManager.moveTaskToBack did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - + try { mAm.moveTaskBackwards(-1); fail("IActivityManager.moveTaskToFront did not throw SecurityException as" diff --git a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java index 322b853..4098b98 100644 --- a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java @@ -52,6 +52,16 @@ public class ServiceManagerPermissionTests extends TestCase { public boolean checkPermission(java.lang.String permission, int pid, int uid) { return true; } + + @Override + public String[] getPackagesForUid(int uid) { + return new String[0]; + } + + @Override + public boolean isRuntimePermission(String permission) { + return false; + } }; ServiceManagerNative.asInterface(BinderInternal.getContextObject()) .setPermissionController(pc); diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java index 62c92a1..e44969d 100644 --- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java @@ -103,7 +103,7 @@ public class WindowManagerPermissionTests extends TestCase { } try { - mWm.setAppGroupId(null, 0); + mWm.setAppTask(null, 0); fail("IWindowManager.setAppGroupId did not throw SecurityException as" + " expected"); } catch (SecurityException e) { |