diff options
Diffstat (limited to 'tests')
159 files changed, 3664 insertions, 194 deletions
diff --git a/tests/ActivityTests/AndroidManifest.xml b/tests/ActivityTests/AndroidManifest.xml index 33d40ad..c105491 100644 --- a/tests/ActivityTests/AndroidManifest.xml +++ b/tests/ActivityTests/AndroidManifest.xml @@ -75,5 +75,6 @@ <provider android:name="SingleUserProvider" android:authorities="com.google.android.test.activity.single_user" android:singleUser="true" android:exported="true" /> + <receiver android:name="TrackTimeReceiver" /> </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..ddcfd9e 100644 --- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java +++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java @@ -23,6 +23,7 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.AlertDialog; +import android.app.PendingIntent; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -412,6 +413,29 @@ 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; + } + }); return true; } 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..c30d33a --- /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_REPORT_TIME); + 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..0b522c0 --- /dev/null +++ b/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java @@ -0,0 +1,181 @@ +/* + * 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.RevealAnimator; +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.VoiceInteractionService; +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 onConfirm(Caller caller, + Request request, CharSequence prompt, Bundle extras) { + + } + + @Override + public void onPickOption(Caller caller, + Request request, CharSequence prompt, + VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) { + + } + + @Override + public void onCommand(Caller caller, + Request request, String command, Bundle extras) { + + } + + @Override + public void onCreate(Bundle args) { + super.onCreate(args); + + // Simulate slowness of Assist app + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Override + public void onCancel(Request request) { + + } + + @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 & VoiceInteractionService.START_SOURCE_ASSIST_GESTURE) != 0) { + mBackground.getViewTreeObserver().addOnPreDrawListener( + new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + mBackground.getViewTreeObserver().removeOnPreDrawListener(this); + playAssistAnimation(); + return true; + } + }); + } + } + + 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..eb40200 --- /dev/null +++ b/tests/CameraPrewarmTest/AndroidManifest.xml @@ -0,0 +1,52 @@ +<?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_SECURE" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + <intent-filter> + <action android:name="android.media.action.STILL_IMAGE_CAMERA" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </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> + </activity> + + <receiver android:name=".PrewarmReceiver" > + <intent-filter> + <action android:name="android.media.action.STILL_IMAGE_CAMERA_PREWARM" /> + </intent-filter> + <intent-filter> + <action android:name="android.media.action.STILL_IMAGE_CAMERA_COOLDOWN" /> + </intent-filter> + </receiver> + + </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..11f7ac7 --- /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">Assistant</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..4d22234 --- /dev/null +++ b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/CameraActivity.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.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 CameraActivity extends Activity { + + public final static String TAG = "PrewarmTest"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.camera_activity); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); + Log.i(TAG, "Activity created"); + } +} diff --git a/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/PrewarmReceiver.java b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/PrewarmReceiver.java new file mode 100644 index 0000000..d49f96d --- /dev/null +++ b/tests/CameraPrewarmTest/src/com/google/android/test/cameraprewarm/PrewarmReceiver.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.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.provider.MediaStore; +import android.util.Log; + +public class PrewarmReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(MediaStore.ACTION_STILL_IMAGE_CAMERA_PREWARM)) { + Log.i(CameraActivity.TAG, "Prewarm received"); + } else if (intent.getAction().equals(MediaStore.ACTION_STILL_IMAGE_CAMERA_COOLDOWN)){ + Log.i(CameraActivity.TAG, "Cooldown received"); + } + } +} 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/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/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..8e6daea 100644 --- a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java +++ b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java @@ -166,6 +166,9 @@ public class UsageLogActivity extends ListActivity implements Runnable { case UsageEvents.Event.CONFIGURATION_CHANGE: return "Config change"; + case UsageEvents.Event.INTERACTION: + return "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/blink.xml b/tests/VectorDrawableTest/res/anim/blink.xml new file mode 100644 index 0000000..2af0b48 --- /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="#ff3838" + android:valueTo="?attr/color1" /> + +</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_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..56c8119 100644 --- a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java @@ -14,9 +14,12 @@ package com.android.test.dynamic; +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; import android.app.Activity; import android.graphics.drawable.AnimatedVectorDrawable; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.GridLayout; @@ -52,6 +55,26 @@ public class AnimatedVectorDrawableTest extends Activity implements View.OnClick button.setWidth(400); button.setHeight(400); button.setBackgroundResource(icon[i]); + AnimatedVectorDrawable d = (AnimatedVectorDrawable) button.getBackground(); + d.addListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + Log.v(LOGCAT, "Animator start"); + } + @Override + public void onAnimationRepeat(Animator animation) { + Log.v(LOGCAT, "Animator repeat"); + } + @Override + public void onAnimationEnd(Animator animation) { + Log.v(LOGCAT, "Animator end"); + } + @Override + public void onAnimationCancel(Animator animation) { + Log.v(LOGCAT, "Animator cancel"); + } + }); + container.addView(button); button.setOnClickListener(this); } 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..36d5d98 100644 --- a/tests/VoiceInteraction/AndroidManifest.xml +++ b/tests/VoiceInteraction/AndroidManifest.xml @@ -12,10 +12,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 +53,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..092d37d 100644 --- a/tests/VoiceInteraction/res/layout/main.xml +++ b/tests/VoiceInteraction/res/layout/main.xml @@ -26,6 +26,14 @@ android:text="@string/start" /> + <com.android.test.voiceinteraction.AsyncStructure + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="64dp" + android:paddingBottom="64dp" + android:text="@string/asyncStructure" + /> + </LinearLayout> diff --git a/tests/VoiceInteraction/res/layout/test_interaction.xml b/tests/VoiceInteraction/res/layout/test_interaction.xml index d55736f..6209bd0 100644 --- a/tests/VoiceInteraction/res/layout/test_interaction.xml +++ b/tests/VoiceInteraction/res/layout/test_interaction.xml @@ -32,21 +32,51 @@ 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/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/pick" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/pickVoice" + /> + + </LinearLayout> - <Button android:id="@+id/abort" - android:layout_width="wrap_content" + <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" - android:text="@string/abortVoice" + 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..d44afb0 100644 --- a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml +++ b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml @@ -15,24 +15,47 @@ --> <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" + <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:padding="8dp"> + android:fitsSystemWindows="true"> + + <LinearLayout android:id="@+id/top_content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="top" + android:orientation="vertical" + android:background="#ffffffff" + android:elevation="8dp" + > + <Button android:id="@+id/start" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="top|right" + android:text="@string/start" + /> + <ImageView android:id="@+id/screenshot" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + </LinearLayout> - <LinearLayout android:id="@+id/content" - android:layout_width="fill_parent" - android:layout_height="match_parent" + <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" @@ -40,11 +63,6 @@ <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" diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml index 7eec90c..6289929 100644 --- a/tests/VoiceInteraction/res/values/strings.xml +++ b/tests/VoiceInteraction/res/values/strings.xml @@ -17,11 +17,14 @@ <resources> <string name="start">Start</string> + <string name="asyncStructure">(Async structure goes here)</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> + <string name="jumpOut">Jump out</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/VoiceInteraction/src/com/android/test/voiceinteraction/AssistProxyActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistProxyActivity.java new file mode 100644 index 0000000..d0c5e36 --- /dev/null +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistProxyActivity.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.android.test.voiceinteraction; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; + +public class AssistProxyActivity extends Activity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + 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..8a72341 --- /dev/null +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java @@ -0,0 +1,104 @@ +/* + * 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.AssistStructure; +import android.content.Context; +import android.graphics.Canvas; +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"; + + AssistStructure mAssistStructure; + final Paint mFramePaint = new Paint(); + final ArrayList<Rect> 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); + } + + public void setAssistStructure(AssistStructure as) { + mAssistStructure = as; + mAssistStructure.dump(); + mTextRects.clear(); + final int N = as.getWindowNodeCount(); + if (N > 0) { + for (int i=0; i<N; i++) { + AssistStructure.WindowNode windowNode = as.getWindowNodeAt(i); + buildTextRects(windowNode.getRootViewNode(), windowNode.getLeft(), + windowNode.getTop()); + } + } + Log.d(TAG, "Building text rects in " + this + ": found " + mTextRects.size()); + invalidate(); + } + + public void clearAssistData() { + mAssistStructure = null; + mTextRects.clear(); + } + + void buildTextRects(AssistStructure.ViewNode root, int parentLeft, int parentTop) { + if (root.getVisibility() != View.VISIBLE) { + return; + } + int left = parentLeft+root.getLeft(); + int top = parentTop+root.getTop(); + if (root.getText() != null || root.getContentDescription() != null) { + Rect r = new Rect(left, top, left+root.getWidth(), top+root.getHeight()); + Log.d(TAG, "View " + root.getClassName() + " " + left + "," + top + " tr " + + r.toShortString() + ": " + + (root.getText() != null ? root.getText() : root.getContentDescription())); + mTextRects.add(r); + } + final int N = root.getChildCount(); + if (N > 0) { + left -= root.getScrollX(); + top -= root.getScrollY(); + for (int i=0; i<N; i++) { + AssistStructure.ViewNode child = root.getChildAt(i); + buildTextRects(child, 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++) { + Rect r = mTextRects.get(i); + canvas.drawRect(r.left-mTmpLocation[0], r.top-mTmpLocation[1], + r.right-mTmpLocation[0], r.bottom-mTmpLocation[1], mFramePaint); + } + } +} 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..15196b4 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java @@ -16,6 +16,7 @@ package com.android.test.voiceinteraction; +import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.service.voice.AlwaysOnHotwordDetector; @@ -74,9 +75,14 @@ public class MainInteractionService extends VoiceInteractionService { @Override public int onStartCommand(Intent intent, int flags, int startId) { - Bundle args = new Bundle(); - args.putParcelable("intent", new Intent(this, TestInteractionActivity.class)); - startSession(args); + if (isActiveService(this, new ComponentName(this, getClass()))) { + Bundle args = new Bundle(); + args.putParcelable("intent", new Intent(this, TestInteractionActivity.class)); + args.putBundle("assist", intent.getExtras()); + startSession(args, START_WITH_ASSIST|START_WITH_SCREENSHOT); + } else { + Log.w(TAG, "Not starting -- not current voice interaction service"); + } stopSelf(startId); return START_NOT_STICKY; } diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java index d20906e..70a6336 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java @@ -16,13 +16,19 @@ package com.android.test.voiceinteraction; +import android.app.ActivityManager; +import android.app.AssistContent; +import android.app.AssistStructure; +import android.app.VoiceInteractor; import android.content.Context; import android.content.Intent; +import android.graphics.Bitmap; import android.os.Bundle; import android.service.voice.VoiceInteractionSession; import android.util.Log; import android.view.View; import android.widget.Button; +import android.widget.ImageView; import android.widget.TextView; public class MainInteractionSession extends VoiceInteractionSession @@ -31,20 +37,30 @@ public class MainInteractionSession extends VoiceInteractionSession Intent mStartIntent; View mContentView; + AssistVisualizer mAssistVisualizer; + View mTopContent; + View mBottomContent; TextView mText; Button mStartButton; + ImageView mScreenshot; 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; MainInteractionSession(Context context) { @@ -52,31 +68,99 @@ public class MainInteractionSession extends VoiceInteractionSession } @Override - public void onCreate(Bundle args) { + public void onCreate(Bundle args, int startFlags) { super.onCreate(args); - showWindow(); + ActivityManager am = getContext().getSystemService(ActivityManager.class); + am.setWatchHeapLimit(40*1024*1024); + } + + @Override + public void onShow(Bundle args, int showFlags) { + super.onShow(args, showFlags); + mState = STATE_IDLE; mStartIntent = args.getParcelable("intent"); + if (mAssistVisualizer != null) { + mAssistVisualizer.clearAssistData(); + } + onHandleScreenshot(null); + updateState(); + } + + @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); mStartButton = (Button)mContentView.findViewById(R.id.start); mStartButton.setOnClickListener(this); + mScreenshot = (ImageView)mContentView.findViewById(R.id.screenshot); 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(); return mContentView; } + @Override + public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) { + mAssistStructure = structure; + if (mAssistStructure != null) { + if (mAssistVisualizer != null) { + mAssistVisualizer.setAssistStructure(mAssistStructure); + } + } + if (content != null) { + Log.i(TAG, "Assist intent: " + content.getIntent()); + Log.i(TAG, "Assist clipdata: " + content.getClipData()); + } + } + + @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); + } else { + mScreenshot.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); } @@ -89,22 +173,48 @@ public class MainInteractionSession extends VoiceInteractionSession } else if (v == mConfirmButton) { if (mState == STATE_CONFIRM) { mPendingRequest.sendConfirmResult(true, null); - } else { + mPendingRequest = null; + mState = STATE_LAUNCHING; + } else if (mState == STATE_PICK_OPTION) { + 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) { + mPendingRequest.sendPickOptionResult(true, picked, null); + mPendingRequest = null; + mState = STATE_LAUNCHING; + } else { + mPendingRequest.sendPickOptionResult(false, picked, null); + updatePickText(); + } + } else if (mPendingRequest != null) { mPendingRequest.sendCommandResult(true, null); + mPendingRequest = null; + mState = STATE_LAUNCHING; } - 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); mPendingRequest = null; - mState = STATE_IDLE; - updateState(); + } + updateState(); + } + + @Override + public void onComputeInsets(Insets outInsets) { + super.onComputeInsets(outInsets); + if (mState != STATE_IDLE) { + outInsets.contentInsets.top = mBottomContent.getTop(); + outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_CONTENT; } } @@ -117,13 +227,40 @@ public class MainInteractionSession extends VoiceInteractionSession 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"); + mConfirmButton.setText("Confirm"); mPendingRequest = request; + mPendingPrompt = prompt; mState = STATE_CONFIRM; updateState(); } @Override + public void onPickOption(Caller caller, Request request, CharSequence prompt, + VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) { + Log.i(TAG, "onPickOption: prompt=" + prompt + " options=" + options + " extras=" + extras); + mConfirmButton.setText("Pick Option"); + mPendingRequest = request; + mPendingPrompt = prompt; + mPendingOptions = options; + 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 onCompleteVoice(Caller caller, Request request, CharSequence message, Bundle extras) { Log.i(TAG, "onCompleteVoice: message=" + message + " extras=" + extras); mText.setText(message); @@ -145,7 +282,7 @@ public class MainInteractionSession extends VoiceInteractionSession 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"); + mConfirmButton.setText("Finish Command"); mPendingRequest = request; mState = STATE_COMMAND; updateState(); diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java index d64eefa..9d24c59 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java @@ -18,19 +18,28 @@ 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.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"; VoiceInteractor mInteractor; + VoiceInteractor.Request mCurrentRequest = null; + TextView mLog; Button mAbortButton; Button mCompleteButton; + Button mPickButton; + Button mJumpOutButton; + Button mCancelButton; @Override public void onCreate(Bundle savedInstanceState) { @@ -42,19 +51,28 @@ 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); 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); + 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( + mCurrentRequest = new VoiceInteractor.ConfirmationRequest( "This is a confirmation", null) { @Override public void onCancel() { @@ -68,7 +86,7 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis getActivity().finish(); } }; - mInteractor.submitRequest(req); + mInteractor.submitRequest(mCurrentRequest); } @Override @@ -84,11 +102,13 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis @Override public void onCancel() { Log.i(TAG, "Canceled!"); + mLog.append("Canceled abort\n"); } @Override public void onAbortResult(Bundle result) { Log.i(TAG, "Abort result: result=" + result); + mLog.append("Abort: result=" + result + "\n"); getActivity().finish(); } }; @@ -99,15 +119,66 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis @Override public void onCancel() { Log.i(TAG, "Canceled!"); + mLog.append("Canceled complete\n"); } @Override public void onCompleteResult(Bundle result) { Log.i(TAG, "Complete result: result=" + result); + mLog.append("Complete: result=" + result + "\n"); getActivity().finish(); } }; mInteractor.submitRequest(req); + } 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 VoiceInteractor.PickOptionRequest( + "Need to pick something", options, null) { + @Override + public void onCancel() { + Log.i(TAG, "Canceled!"); + 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()); + } + mLog.append(sb.toString()); + if (finished) { + getActivity().finish(); + } + } + }; + mInteractor.submitRequest(req); + } 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(); } } 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) { |
