validEntries) {
24 | return new StringFilter() {
25 | @Override
26 | public boolean matches(String str) {
27 | return validEntries.contains(str);
28 | }
29 | };
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/com/android/launcher3/util/Thunk.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.launcher3.util;
18 |
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * Indicates that the given field or method has package visibility solely to prevent the creation
26 | * of a synthetic method. In practice, you should treat this field/method as if it were private.
27 | *
28 | *
29 | * When a private method is called from an inner class, the Java compiler generates a simple
30 | * package private shim method that the class generated from the inner class can call. This results
31 | * in unnecessary bloat and runtime method call overhead. It also gets us closer to the dex method
32 | * count limit.
33 | *
34 | *
35 | * If you'd like to see warnings for these synthetic methods in eclipse, turn on:
36 | * Window > Preferences > Java > Compiler > Errors/Warnings > "Access to a non-accessible member
37 | * of an enclosing type".
38 | *
39 | *
40 | */
41 | @Retention(RetentionPolicy.SOURCE)
42 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.TYPE})
43 | public @interface Thunk { }
--------------------------------------------------------------------------------
/src/com/android/launcher3/util/TouchController.java:
--------------------------------------------------------------------------------
1 | package com.android.launcher3.util;
2 |
3 | import android.view.MotionEvent;
4 |
5 | public interface TouchController {
6 | boolean onTouchEvent(MotionEvent ev);
7 | boolean onInterceptTouchEvent(MotionEvent ev);
8 | }
9 |
--------------------------------------------------------------------------------
/src/com/android/launcher3/widget/PendingAddShortcutInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.android.launcher3.widget;
17 |
18 | import android.content.ComponentName;
19 | import android.content.pm.ActivityInfo;
20 |
21 | import com.android.launcher3.LauncherSettings;
22 | import com.android.launcher3.PendingAddItemInfo;
23 |
24 | /**
25 | * Meta data used for late binding of the short cuts.
26 | *
27 | * @see {@link PendingAddItemInfo}
28 | */
29 | public class PendingAddShortcutInfo extends PendingAddItemInfo {
30 |
31 | ActivityInfo activityInfo;
32 |
33 | public PendingAddShortcutInfo(ActivityInfo activityInfo) {
34 | this.activityInfo = activityInfo;
35 | componentName = new ComponentName(activityInfo.packageName, activityInfo.name);
36 | itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/com/android/launcher3/widget/WidgetsRowViewHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.android.launcher3.widget;
17 |
18 | import android.support.v7.widget.RecyclerView.ViewHolder;
19 | import android.view.ViewGroup;
20 |
21 | import com.android.launcher3.BubbleTextView;
22 | import com.android.launcher3.R;
23 |
24 | public class WidgetsRowViewHolder extends ViewHolder {
25 |
26 | public final ViewGroup cellContainer;
27 | public final BubbleTextView title;
28 |
29 | public WidgetsRowViewHolder(ViewGroup v) {
30 | super(v);
31 |
32 | cellContainer = (ViewGroup) v.findViewById(R.id.widgets_cell_list);
33 | title = (BubbleTextView) v.findViewById(R.id.section);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src_config/com/android/launcher3/config/FeatureFlags.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.launcher3.config;
18 |
19 | /**
20 | * Defines a set of flags used to control various launcher behaviors
21 | */
22 | public final class FeatureFlags {
23 | private FeatureFlags() {}
24 |
25 | // Custom flags go below this
26 | public static boolean LAUNCHER3_DISABLE_ICON_NORMALIZATION = false;
27 | // As opposed to the new spring-loaded workspace.
28 | public static boolean LAUNCHER3_LEGACY_WORKSPACE_DND = false;
29 | public static boolean LAUNCHER3_LEGACY_FOLDER_ICON = false;
30 | public static boolean LAUNCHER3_USE_SYSTEM_DRAG_DRIVER = true;
31 | public static boolean LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW = false;
32 | public static boolean LAUNCHER3_ALL_APPS_PULL_UP = true;
33 |
34 | // Feature flag to enable moving the QSB on the 0th screen of the workspace.
35 | public static final boolean QSB_ON_FIRST_SCREEN = true;
36 | // When enabled the all-apps icon is not added to the hotseat.
37 | public static final boolean NO_ALL_APPS_ICON = true;
38 | // When enabled fling down gesture on the first workspace triggers search.
39 | public static final boolean PULLDOWN_SEARCH = false;
40 | // When enabled the status bar may show dark icons based on the top of the wallpaper.
41 | public static final boolean LIGHT_STATUS_BAR = false;
42 | }
43 |
--------------------------------------------------------------------------------
/src_config/com/android/launcher3/config/ProviderConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.launcher3.config;
18 |
19 | public class ProviderConfig {
20 |
21 | public static final String AUTHORITY = "com.android.launcher3.settings".intern();
22 |
23 | public static boolean IS_DOGFOOD_BUILD = true;
24 | }
25 |
--------------------------------------------------------------------------------
/tests/Android.mk:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2015 The Android Open Source Project
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | #
15 |
16 | LOCAL_PATH := $(call my-dir)
17 | include $(CLEAR_VARS)
18 |
19 | LOCAL_MODULE_TAGS := tests
20 | LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ub-uiautomator
21 |
22 | LOCAL_SRC_FILES := $(call all-java-files-under, src)
23 |
24 | LOCAL_SDK_VERSION := current
25 |
26 | LOCAL_PACKAGE_NAME := Launcher3Tests
27 |
28 | LOCAL_INSTRUMENTATION_FOR := Launcher3
29 |
30 | include $(BUILD_PACKAGE)
31 |
--------------------------------------------------------------------------------
/tests/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java:
--------------------------------------------------------------------------------
1 | package com.android.launcher3.ui;
2 |
3 | import android.support.test.uiautomator.By;
4 | import android.support.test.uiautomator.UiObject2;
5 | import android.support.test.uiautomator.Until;
6 | import android.test.suitebuilder.annotation.LargeTest;
7 |
8 | import com.android.launcher3.compat.LauncherActivityInfoCompat;
9 | import com.android.launcher3.compat.LauncherAppsCompat;
10 | import com.android.launcher3.compat.UserHandleCompat;
11 | import com.android.launcher3.util.Condition;
12 | import com.android.launcher3.util.Wait;
13 |
14 | /**
15 | * Test for verifying apps is launched from all-apps
16 | */
17 | @LargeTest
18 | public class AllAppsAppLaunchTest extends LauncherInstrumentationTestCase {
19 |
20 | private LauncherActivityInfoCompat mSettingsApp;
21 |
22 | @Override
23 | protected void setUp() throws Exception {
24 | super.setUp();
25 |
26 | mSettingsApp = LauncherAppsCompat.getInstance(mTargetContext)
27 | .getActivityList("com.android.settings", UserHandleCompat.myUserHandle()).get(0);
28 | }
29 |
30 | public void testAppLauncher_portrait() throws Exception {
31 | lockRotation(true);
32 | performTest();
33 | }
34 |
35 | public void testAppLauncher_landscape() throws Exception {
36 | lockRotation(false);
37 | performTest();
38 | }
39 |
40 | private void performTest() throws Exception {
41 | startLauncher();
42 |
43 | // Open all apps and wait for load complete
44 | final UiObject2 appsContainer = openAllApps();
45 | assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT));
46 |
47 | // Open settings app and verify app launched
48 | scrollAndFind(appsContainer, By.text(mSettingsApp.getLabel().toString())).click();
49 | assertTrue(mDevice.wait(Until.hasObject(By.pkg(
50 | mSettingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT));
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java:
--------------------------------------------------------------------------------
1 | package com.android.launcher3.ui;
2 |
3 | import android.support.test.uiautomator.By;
4 | import android.support.test.uiautomator.UiObject2;
5 | import android.support.test.uiautomator.Until;
6 | import android.test.suitebuilder.annotation.LargeTest;
7 |
8 | import com.android.launcher3.compat.LauncherActivityInfoCompat;
9 | import com.android.launcher3.compat.LauncherAppsCompat;
10 | import com.android.launcher3.compat.UserHandleCompat;
11 | import com.android.launcher3.util.Condition;
12 | import com.android.launcher3.util.Wait;
13 |
14 | /**
15 | * Test for dragging an icon from all-apps to homescreen.
16 | */
17 | @LargeTest
18 | public class AllAppsIconToHomeTest extends LauncherInstrumentationTestCase {
19 |
20 | private LauncherActivityInfoCompat mSettingsApp;
21 |
22 | @Override
23 | protected void setUp() throws Exception {
24 | super.setUp();
25 |
26 | mSettingsApp = LauncherAppsCompat.getInstance(mTargetContext)
27 | .getActivityList("com.android.settings", UserHandleCompat.myUserHandle()).get(0);
28 | }
29 |
30 | public void testDragIcon_portrait() throws Throwable {
31 | lockRotation(true);
32 | performTest();
33 | }
34 |
35 | public void testDragIcon_landscape() throws Throwable {
36 | lockRotation(false);
37 | performTest();
38 | }
39 |
40 | private void performTest() throws Throwable {
41 | clearHomescreen();
42 | startLauncher();
43 |
44 | // Open all apps and wait for load complete.
45 | final UiObject2 appsContainer = openAllApps();
46 | assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT));
47 |
48 | // Drag icon to homescreen.
49 | UiObject2 icon = scrollAndFind(appsContainer, By.text(mSettingsApp.getLabel().toString()));
50 | dragToWorkspace(icon);
51 |
52 | // Verify that the icon works on homescreen.
53 | mDevice.findObject(By.text(mSettingsApp.getLabel().toString())).click();
54 | assertTrue(mDevice.wait(Until.hasObject(By.pkg(
55 | mSettingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT));
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/tests/src/com/android/launcher3/util/Condition.java:
--------------------------------------------------------------------------------
1 | package com.android.launcher3.util;
2 |
3 | import android.support.test.uiautomator.UiObject2;
4 |
5 | import com.android.launcher3.MainThreadExecutor;
6 |
7 | import java.util.concurrent.CountDownLatch;
8 | import java.util.concurrent.TimeUnit;
9 | import java.util.concurrent.atomic.AtomicBoolean;
10 |
11 | public abstract class Condition {
12 |
13 | public abstract boolean isTrue() throws Throwable;
14 |
15 | /**
16 | * Converts the condition to be run on UI thread.
17 | */
18 | public static Condition runOnUiThread(final Condition condition) {
19 | final MainThreadExecutor executor = new MainThreadExecutor();
20 | return new Condition() {
21 | @Override
22 | public boolean isTrue() throws Throwable {
23 | final AtomicBoolean value = new AtomicBoolean(false);
24 | final Throwable[] exceptions = new Throwable[1];
25 | final CountDownLatch latch = new CountDownLatch(1);
26 | executor.execute(new Runnable() {
27 | @Override
28 | public void run() {
29 | try {
30 | value.set(condition.isTrue());
31 | } catch (Throwable e) {
32 | exceptions[0] = e;
33 | }
34 |
35 | }
36 | });
37 | latch.await(1, TimeUnit.SECONDS);
38 | if (exceptions[0] != null) {
39 | throw exceptions[0];
40 | }
41 | return value.get();
42 | }
43 | };
44 | }
45 |
46 | public static Condition minChildCount(final UiObject2 obj, final int childCount) {
47 | return new Condition() {
48 | @Override
49 | public boolean isTrue() {
50 | return obj.getChildCount() >= childCount;
51 | }
52 | };
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/tests/src/com/android/launcher3/util/GridOccupancyTest.java:
--------------------------------------------------------------------------------
1 | package com.android.launcher3.util;
2 |
3 | import android.test.suitebuilder.annotation.SmallTest;
4 |
5 | import junit.framework.TestCase;
6 |
7 | /**
8 | * Unit tests for {@link GridOccupancy}
9 | */
10 | @SmallTest
11 | public class GridOccupancyTest extends TestCase {
12 |
13 | public void testFindVacantCell() {
14 | GridOccupancy grid = initGrid(4,
15 | 1, 1, 1, 0, 0,
16 | 0, 0, 1, 1, 0,
17 | 0, 0, 0, 0, 0,
18 | 1, 1, 0, 0, 0
19 | );
20 |
21 | int[] vacant = new int[2];
22 | assertTrue(grid.findVacantCell(vacant, 2, 2));
23 | assertEquals(vacant[0], 0);
24 | assertEquals(vacant[1], 1);
25 |
26 | assertTrue(grid.findVacantCell(vacant, 3, 2));
27 | assertEquals(vacant[0], 2);
28 | assertEquals(vacant[1], 2);
29 |
30 | assertFalse(grid.findVacantCell(vacant, 3, 3));
31 | }
32 |
33 | public void testIsRegionVacant() {
34 | GridOccupancy grid = initGrid(4,
35 | 1, 1, 1, 0, 0,
36 | 0, 0, 1, 1, 0,
37 | 0, 0, 0, 0, 0,
38 | 1, 1, 0, 0, 0
39 | );
40 |
41 | assertTrue(grid.isRegionVacant(4, 0, 1, 4));
42 | assertTrue(grid.isRegionVacant(0, 1, 2, 2));
43 | assertTrue(grid.isRegionVacant(2, 2, 3, 2));
44 |
45 | assertFalse(grid.isRegionVacant(3, 0, 2, 4));
46 | assertFalse(grid.isRegionVacant(0, 0, 2, 1));
47 | }
48 |
49 | private GridOccupancy initGrid(int rows, int... cells) {
50 | int cols = cells.length / rows;
51 | int i = 0;
52 | GridOccupancy grid = new GridOccupancy(cols, rows);
53 | for (int y = 0; y < rows; y++) {
54 | for (int x = 0; x < cols; x++) {
55 | grid.cells[x][y] = cells[i] != 0;
56 | i++;
57 | }
58 | }
59 | return grid;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/tests/src/com/android/launcher3/util/TestLauncherProvider.java:
--------------------------------------------------------------------------------
1 | package com.android.launcher3.util;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteOpenHelper;
5 |
6 | import com.android.launcher3.LauncherProvider;
7 |
8 | /**
9 | * An extension of LauncherProvider backed up by in-memory database.
10 | */
11 | public class TestLauncherProvider extends LauncherProvider {
12 |
13 | @Override
14 | public boolean onCreate() {
15 | return true;
16 | }
17 |
18 | @Override
19 | protected synchronized void createDbIfNotExists() {
20 | if (mOpenHelper == null) {
21 | mOpenHelper = new MyDatabaseHelper(getContext());
22 | }
23 | }
24 |
25 | public SQLiteOpenHelper getHelper() {
26 | createDbIfNotExists();
27 | return mOpenHelper;
28 | }
29 |
30 | @Override
31 | protected void notifyListeners() { }
32 |
33 | private static class MyDatabaseHelper extends DatabaseHelper {
34 | public MyDatabaseHelper(Context context) {
35 | super(context, null, null);
36 | initIds();
37 | }
38 |
39 | @Override
40 | public long getDefaultUserSerial() {
41 | return 0;
42 | }
43 |
44 | @Override
45 | protected void onEmptyDbCreated() { }
46 | }
47 | }
--------------------------------------------------------------------------------
/tests/src/com/android/launcher3/util/Wait.java:
--------------------------------------------------------------------------------
1 | package com.android.launcher3.util;
2 |
3 | import android.os.SystemClock;
4 |
5 | /**
6 | * A utility class for waiting for a condition to be true.
7 | */
8 | public class Wait {
9 |
10 | private static final long DEFAULT_SLEEP_MS = 200;
11 |
12 | public static boolean atMost(Condition condition, long timeout) {
13 | return atMost(condition, timeout, DEFAULT_SLEEP_MS);
14 | }
15 |
16 | public static boolean atMost(Condition condition, long timeout, long sleepMillis) {
17 | long endTime = SystemClock.uptimeMillis() + timeout;
18 | while (SystemClock.uptimeMillis() < endTime) {
19 | try {
20 | if (condition.isTrue()) {
21 | return true;
22 | }
23 | } catch (Throwable t) {
24 | // Ignore
25 | }
26 | SystemClock.sleep(sleepMillis);
27 | }
28 |
29 | // Check once more before returning false.
30 | try {
31 | if (condition.isTrue()) {
32 | return true;
33 | }
34 | } catch (Throwable t) {
35 | // Ignore
36 | }
37 | return false;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------