Subclassing Launcher instead of using UiFactory

Allows us to override only the required methods, instead of providing
a proxy method for everything

Change-Id: I816dcdb2a8d5432496050118ded0f2bbe7122cf7
This commit is contained in:
Sunny Goyal 2019-10-17 12:05:38 -07:00
parent 221823c337
commit 210e174c9c
23 changed files with 683 additions and 641 deletions

View File

@ -200,7 +200,7 @@ LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/quickstep/recents_ui_overrides/res
LOCAL_FULL_LIBS_MANIFEST_FILES := \
$(LOCAL_PATH)/AndroidManifest.xml \
$(LOCAL_PATH)/quickstep/AndroidManifest-launcher.xml \
$(LOCAL_PATH)/AndroidManifest-common.xml
LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
@ -247,7 +247,7 @@ LOCAL_REQUIRED_MODULES := privapp_whitelist_com.android.launcher3
LOCAL_FULL_LIBS_MANIFEST_FILES := \
$(LOCAL_PATH)/go/AndroidManifest.xml \
$(LOCAL_PATH)/AndroidManifest.xml \
$(LOCAL_PATH)/quickstep/AndroidManifest-launcher.xml \
$(LOCAL_PATH)/AndroidManifest-common.xml
LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
@ -293,7 +293,7 @@ LOCAL_REQUIRED_MODULES := privapp_whitelist_com.android.launcher3
LOCAL_FULL_LIBS_MANIFEST_FILES := \
$(LOCAL_PATH)/go/AndroidManifest.xml \
$(LOCAL_PATH)/AndroidManifest.xml \
$(LOCAL_PATH)/quickstep/AndroidManifest-launcher.xml \
$(LOCAL_PATH)/AndroidManifest-common.xml
LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml

View File

@ -0,0 +1,46 @@
/**
* Copyright (C) 2019 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.launcher3.uioverrides;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeEdgeSwipeController;
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeStatesTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.SysUINavigationMode;
import java.util.ArrayList;
public class QuickstepLauncher extends BaseQuickstepLauncher {
public static final boolean GO_LOW_RAM_RECENTS_ENABLED = true;
@Override
public TouchController[] createTouchControllers() {
ArrayList<TouchController> list = new ArrayList<>();
list.add(getDragController());
if (getDeviceProfile().isVerticalBarLayout()) {
list.add(new LandscapeStatesTouchController(this));
list.add(new LandscapeEdgeSwipeController(this));
} else {
boolean allowDragToOverview = SysUINavigationMode.INSTANCE.get(this)
.getMode().hasGestures;
list.add(new PortraitStatesTouchController(this, allowDragToOverview));
}
return list.toArray(new TouchController[list.size()]);
}
}

View File

@ -1,91 +0,0 @@
/*
* Copyright (C) 2019 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.launcher3.uioverrides;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.Utilities;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeEdgeSwipeController;
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeStatesTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchController;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.views.IconRecentsView;
import java.util.ArrayList;
/**
* Provides recents-related {@link UiFactory} logic and classes.
*/
public abstract class RecentsUiFactory {
public static final boolean GO_LOW_RAM_RECENTS_ENABLED = true;
public static TouchController[] createTouchControllers(Launcher launcher) {
ArrayList<TouchController> list = new ArrayList<>();
list.add(launcher.getDragController());
if (launcher.getDeviceProfile().isVerticalBarLayout()) {
list.add(new LandscapeStatesTouchController(launcher));
list.add(new LandscapeEdgeSwipeController(launcher));
} else {
boolean allowDragToOverview = SysUINavigationMode.INSTANCE.get(launcher)
.getMode().hasGestures;
list.add(new PortraitStatesTouchController(launcher, allowDragToOverview));
}
if (Utilities.IS_DEBUG_DEVICE
&& !launcher.getDeviceProfile().isMultiWindowMode
&& !launcher.getDeviceProfile().isVerticalBarLayout()) {
list.add(new StatusBarTouchController(launcher));
}
return list.toArray(new TouchController[list.size()]);
}
/**
* Creates and returns the controller responsible for recents view state transitions.
*
* @param launcher the launcher activity
* @return state handler for recents
*/
public static StateHandler createRecentsViewStateController(Launcher launcher) {
return new RecentsViewStateController(launcher);
}
/**
* Clean-up logic that occurs when recents is no longer in use/visible.
*
* @param launcher the launcher activity
*/
public static void resetOverview(Launcher launcher) {
IconRecentsView recentsView = launcher.getOverviewPanel();
recentsView.setTransitionedFromApp(false);
}
/**
* Recents logic that triggers when launcher state changes or launcher activity stops/resumes.
*
* @param launcher the launcher activity
*/
public static void onLauncherStateOrResumeChanged(Launcher launcher) {}
public static RotationMode getRotationMode(DeviceProfile dp) {
return RotationMode.NORMAL;
}
}

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2019, 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.launcher3">
<uses-sdk android:targetSdkVersion="29" android:minSdkVersion="25"/>
<!--
Manifest entries specific to Launcher3. This is merged with AndroidManifest-common.xml.
Refer comments around specific entries on how to extend individual components.
-->
<application
android:backupAgent="com.android.launcher3.LauncherBackupAgent"
android:fullBackupOnly="true"
android:fullBackupContent="@xml/backupscheme"
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher_home"
android:label="@string/derived_app_name"
android:theme="@style/AppTheme"
android:largeHeap="@bool/config_largeHeap"
android:restoreAnyVersion="true"
android:supportsRtl="true" >
<!--
Main launcher activity. When extending only change the name, and keep all the
attributes and intent filters the same
-->
<activity
android:name="com.android.launcher3.uioverrides.QuickstepLauncher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
<category android:name="android.intent.category.LAUNCHER_APP" />
</intent-filter>
<meta-data
android:name="com.android.launcher3.grid.control"
android:value="${packageName}.grid_control" />
</activity>
</application>
</manifest>

View File

@ -1,4 +1,4 @@
/*
/**
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.uioverrides;
import static com.android.launcher3.LauncherState.NORMAL;
@ -21,13 +20,14 @@ import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.view.Gravity;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.uioverrides.touchcontrollers.FlingAndHoldTouchController;
@ -49,21 +49,15 @@ import com.android.quickstep.views.RecentsView;
import java.util.ArrayList;
/**
* Provides recents-related {@link UiFactory} logic and classes.
*/
public abstract class RecentsUiFactory {
private static final String TAG = RecentsUiFactory.class.getSimpleName();
public class QuickstepLauncher extends BaseQuickstepLauncher {
public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false;
/**
* Reusable command for applying the shelf height on the background thread.
*/
public static final AsyncCommand SET_SHELF_HEIGHT = (context, arg1, arg2) -> {
SystemUiProxy.INSTANCE.get(context).setShelfHeight(arg1 != 0, arg2);
};
public static final AsyncCommand SET_SHELF_HEIGHT = (context, arg1, arg2) ->
SystemUiProxy.INSTANCE.get(context).setShelfHeight(arg1 != 0, arg2);
public static RotationMode ROTATION_LANDSCAPE = new RotationMode(-90) {
@Override
@ -138,71 +132,78 @@ public abstract class RecentsUiFactory {
}
};
public static RotationMode getRotationMode(DeviceProfile dp) {
@Override
protected RotationMode getFakeRotationMode(DeviceProfile dp) {
return !dp.isVerticalBarLayout() ? RotationMode.NORMAL
: (dp.isSeascape() ? ROTATION_SEASCAPE : ROTATION_LANDSCAPE);
}
public static TouchController[] createTouchControllers(Launcher launcher) {
Mode mode = SysUINavigationMode.getMode(launcher);
ArrayList<TouchController> list = new ArrayList<>();
list.add(launcher.getDragController());
if (mode == NO_BUTTON) {
list.add(new QuickSwitchTouchController(launcher));
list.add(new NavBarToHomeTouchController(launcher));
list.add(new FlingAndHoldTouchController(launcher));
} else {
if (launcher.getDeviceProfile().isVerticalBarLayout()) {
list.add(new OverviewToAllAppsTouchController(launcher));
list.add(new LandscapeEdgeSwipeController(launcher));
if (mode.hasGestures) {
list.add(new TransposedQuickSwitchTouchController(launcher));
}
} else {
list.add(new PortraitStatesTouchController(launcher,
mode.hasGestures /* allowDragToOverview */));
if (mode.hasGestures) {
list.add(new QuickSwitchTouchController(launcher));
}
}
}
if (!launcher.getDeviceProfile().isMultiWindowMode) {
list.add(new StatusBarTouchController(launcher));
}
list.add(new LauncherTaskViewController(launcher));
return list.toArray(new TouchController[list.size()]);
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
onStateOrResumeChanged();
}
/**
* Creates and returns the controller responsible for recents view state transitions.
*
* @param launcher the launcher activity
* @return state handler for recents
*/
public static StateHandler createRecentsViewStateController(Launcher launcher) {
return new RecentsViewStateController(launcher);
@Override
protected void onActivityFlagsChanged(int changeBits) {
super.onActivityFlagsChanged(changeBits);
if ((changeBits & (ACTIVITY_STATE_DEFERRED_RESUMED | ACTIVITY_STATE_STARTED
| ACTIVITY_STATE_USER_ACTIVE | ACTIVITY_STATE_TRANSITION_ACTIVE)) != 0
&& (getActivityFlags() & ACTIVITY_STATE_TRANSITION_ACTIVE) == 0) {
onStateOrResumeChanged();
}
}
/**
* Recents logic that triggers when launcher state changes or launcher activity stops/resumes.
*
* @param launcher the launcher activity
*/
public static void onLauncherStateOrResumeChanged(Launcher launcher) {
LauncherState state = launcher.getStateManager().getState();
DeviceProfile profile = launcher.getDeviceProfile();
boolean visible = (state == NORMAL || state == OVERVIEW) && launcher.isUserActive()
private void onStateOrResumeChanged() {
LauncherState state = getStateManager().getState();
DeviceProfile profile = getDeviceProfile();
boolean visible = (state == NORMAL || state == OVERVIEW) && isUserActive()
&& !profile.isVerticalBarLayout();
UiThreadHelper.runAsyncCommand(launcher, SET_SHELF_HEIGHT, visible ? 1 : 0,
UiThreadHelper.runAsyncCommand(this, SET_SHELF_HEIGHT, visible ? 1 : 0,
profile.hotseatBarSizePx);
if (state == NORMAL) {
launcher.<RecentsView>getOverviewPanel().setSwipeDownShouldLaunchApp(false);
((RecentsView) getOverviewPanel()).setSwipeDownShouldLaunchApp(false);
}
}
@Override
public TouchController[] createTouchControllers() {
Mode mode = SysUINavigationMode.getMode(this);
ArrayList<TouchController> list = new ArrayList<>();
list.add(getDragController());
if (mode == NO_BUTTON) {
list.add(new QuickSwitchTouchController(this));
list.add(new NavBarToHomeTouchController(this));
list.add(new FlingAndHoldTouchController(this));
} else {
if (getDeviceProfile().isVerticalBarLayout()) {
list.add(new OverviewToAllAppsTouchController(this));
list.add(new LandscapeEdgeSwipeController(this));
if (mode.hasGestures) {
list.add(new TransposedQuickSwitchTouchController(this));
}
} else {
list.add(new PortraitStatesTouchController(this,
mode.hasGestures /* allowDragToOverview */));
if (mode.hasGestures) {
list.add(new QuickSwitchTouchController(this));
}
}
}
if (!getDeviceProfile().isMultiWindowMode) {
list.add(new StatusBarTouchController(this));
}
list.add(new LauncherTaskViewController(this));
return list.toArray(new TouchController[list.size()]);
}
private static final class LauncherTaskViewController extends
TaskViewTouchController<Launcher> {

View File

@ -15,8 +15,8 @@
*/
package com.android.quickstep.util;
import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_LANDSCAPE;
import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE;
import static com.android.launcher3.uioverrides.QuickstepLauncher.ROTATION_LANDSCAPE;
import static com.android.launcher3.uioverrides.QuickstepLauncher.ROTATION_SEASCAPE;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import android.content.Context;

View File

@ -0,0 +1,254 @@
/*
* Copyright (C) 2019 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.launcher3;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.DiscoveryBounce.BOUNCE_MAX_COUNT;
import static com.android.launcher3.allapps.DiscoveryBounce.HOME_BOUNCE_COUNT;
import static com.android.launcher3.allapps.DiscoveryBounce.HOME_BOUNCE_SEEN;
import static com.android.launcher3.allapps.DiscoveryBounce.SHELF_BOUNCE_COUNT;
import static com.android.launcher3.allapps.DiscoveryBounce.SHELF_BOUNCE_SEEN;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.os.CancellationSignal;
import com.android.launcher3.LauncherState.ScaleAndTranslation;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.proxy.ProxyActivityStarter;
import com.android.launcher3.proxy.StartActivityParams;
import com.android.launcher3.uioverrides.BackButtonAlphaHandler;
import com.android.launcher3.uioverrides.RecentsViewStateController;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
/**
* Extension of Launcher activity to provide quickstep specific functionality
*/
public abstract class BaseQuickstepLauncher extends Launcher
implements NavigationModeChangeListener {
/**
* Reusable command for applying the back button alpha on the background thread.
*/
public static final UiThreadHelper.AsyncCommand SET_BACK_BUTTON_ALPHA =
(context, arg1, arg2) -> SystemUiProxy.INSTANCE.get(context).setBackButtonAlpha(
Float.intBitsToFloat(arg1), arg2 != 0);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SysUINavigationMode.Mode mode = SysUINavigationMode.INSTANCE.get(this)
.addModeChangeListener(this);
getRotationHelper().setRotationHadDifferentUI(mode != Mode.NO_BUTTON);
if (!getSharedPrefs().getBoolean(HOME_BOUNCE_SEEN, false)) {
getStateManager().addStateListener(new LauncherStateManager.StateListener() {
@Override
public void onStateTransitionStart(LauncherState toState) { }
@Override
public void onStateTransitionComplete(LauncherState finalState) {
boolean swipeUpEnabled = SysUINavigationMode.INSTANCE
.get(BaseQuickstepLauncher.this).getMode().hasGestures;
LauncherState prevState = getStateManager().getLastState();
if (((swipeUpEnabled && finalState == OVERVIEW) || (!swipeUpEnabled
&& finalState == ALL_APPS && prevState == NORMAL) || BOUNCE_MAX_COUNT
<= getSharedPrefs().getInt(HOME_BOUNCE_COUNT, 0))) {
getSharedPrefs().edit().putBoolean(HOME_BOUNCE_SEEN, true).apply();
getStateManager().removeStateListener(this);
}
}
});
}
if (!getSharedPrefs().getBoolean(SHELF_BOUNCE_SEEN, false)) {
getStateManager().addStateListener(new LauncherStateManager.StateListener() {
@Override
public void onStateTransitionStart(LauncherState toState) { }
@Override
public void onStateTransitionComplete(LauncherState finalState) {
LauncherState prevState = getStateManager().getLastState();
if ((finalState == ALL_APPS && prevState == OVERVIEW) || BOUNCE_MAX_COUNT
<= getSharedPrefs().getInt(SHELF_BOUNCE_COUNT, 0)) {
getSharedPrefs().edit().putBoolean(SHELF_BOUNCE_SEEN, true).apply();
getStateManager().removeStateListener(this);
}
}
});
}
}
@Override
public void onDestroy() {
SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
super.onDestroy();
}
@Override
public void onNavigationModeChanged(Mode newMode) {
getDragLayer().recreateControllers();
getRotationHelper().setRotationHadDifferentUI(newMode != Mode.NO_BUTTON);
}
@Override
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
// After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
// as a part of quickstep, so that high-res thumbnails can load the next time we enter
// overview
RecentsModel.INSTANCE.get(this).getThumbnailCache()
.getHighResLoadingState().setVisible(true);
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
RecentsModel.INSTANCE.get(this).onTrimMemory(level);
}
@Override
public void startIntentSenderForResult(IntentSender intent, int requestCode,
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {
if (requestCode != -1) {
mPendingActivityRequestCode = requestCode;
StartActivityParams params = new StartActivityParams(this, requestCode);
params.intentSender = intent;
params.fillInIntent = fillInIntent;
params.flagsMask = flagsMask;
params.flagsValues = flagsValues;
params.extraFlags = extraFlags;
params.options = options;
startActivity(ProxyActivityStarter.getLaunchIntent(this, params));
} else {
super.startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
flagsValues, extraFlags, options);
}
}
@Override
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
if (requestCode != -1) {
mPendingActivityRequestCode = -1;
StartActivityParams params = new StartActivityParams(this, requestCode);
params.intent = intent;
params.options = options;
startActivity(ProxyActivityStarter.getLaunchIntent(this, params));
} else {
super.startActivityForResult(intent, requestCode, options);
}
}
@Override
protected void onDeferredResumed() {
if (mPendingActivityRequestCode != -1 && isInState(NORMAL)) {
// Remove any active ProxyActivityStarter task and send RESULT_CANCELED to Launcher.
onActivityResult(mPendingActivityRequestCode, RESULT_CANCELED, null);
// ProxyActivityStarter is started with clear task to reset the task after which it
// removes the task itself.
startActivity(ProxyActivityStarter.getLaunchIntent(this, null));
}
}
@Override
protected StateHandler[] createStateHandlers() {
return new StateHandler[] {
getAllAppsController(),
getWorkspace(),
new RecentsViewStateController(this),
new BackButtonAlphaHandler(this)};
}
@Override
protected ScaleAndTranslation getOverviewScaleAndTranslationForNormalState() {
if (SysUINavigationMode.getMode(this) == Mode.NO_BUTTON) {
float offscreenTranslationX = getDeviceProfile().widthPx
- getOverviewPanel().getPaddingStart();
return new ScaleAndTranslation(1f, offscreenTranslationX, 0f);
}
return super.getOverviewScaleAndTranslationForNormalState();
}
@Override
public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) {
QuickstepAppTransitionManagerImpl appTransitionManager =
(QuickstepAppTransitionManagerImpl) getAppTransitionManager();
appTransitionManager.setRemoteAnimationProvider((appTargets, wallpaperTargets) -> {
// On the first call clear the reference.
signal.cancel();
ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0);
fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(appTargets,
wallpaperTargets));
AnimatorSet anim = new AnimatorSet();
anim.play(fadeAnimation);
return anim;
}, signal);
}
@Override
public void onDragLayerHierarchyChanged() {
onLauncherStateOrFocusChanged();
}
@Override
protected void onActivityFlagsChanged(int changeBits) {
if ((changeBits
& (ACTIVITY_STATE_WINDOW_FOCUSED | ACTIVITY_STATE_TRANSITION_ACTIVE)) != 0) {
onLauncherStateOrFocusChanged();
}
super.onActivityFlagsChanged(changeBits);
}
/**
* Sets the back button visibility based on the current state/window focus.
*/
private void onLauncherStateOrFocusChanged() {
Mode mode = SysUINavigationMode.getMode(this);
boolean shouldBackButtonBeHidden = mode.hasGestures
&& getStateManager().getState().hideBackButton
&& hasWindowFocus()
&& (getActivityFlags() & ACTIVITY_STATE_TRANSITION_ACTIVE) == 0;
if (shouldBackButtonBeHidden) {
// Show the back button if there is a floating view visible.
shouldBackButtonBeHidden = AbstractFloatingView.getTopOpenViewWithType(this,
TYPE_ALL & ~TYPE_HIDE_BACK_BUTTON) == null;
}
UiThreadHelper.setBackButtonAlphaAsync(this, SET_BACK_BUTTON_ALPHA,
shouldBackButtonBeHidden ? 0f : 1f, true /* animate */);
if (getDragLayer() != null) {
getRootView().setDisallowBackGesture(shouldBackButtonBeHidden);
}
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2017 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.launcher3.uioverrides;
import android.app.Activity;
import android.app.Person;
import android.content.pm.ShortcutInfo;
import android.util.Base64;
import com.android.launcher3.Utilities;
import com.android.systemui.shared.system.ActivityCompat;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.util.zip.Deflater;
public class ApiWrapper {
public static boolean dumpActivity(Activity activity, PrintWriter writer) {
if (!Utilities.IS_DEBUG_DEVICE) {
return false;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
if (!(new ActivityCompat(activity).encodeViewHierarchy(out))) {
return false;
}
Deflater deflater = new Deflater();
deflater.setInput(out.toByteArray());
deflater.finish();
out.reset();
byte[] buffer = new byte[1024];
while (!deflater.finished()) {
int count = deflater.deflate(buffer); // returns the generated code... index
out.write(buffer, 0, count);
}
writer.println("--encoded-view-dump-v0--");
writer.println(Base64.encodeToString(
out.toByteArray(), Base64.NO_WRAP | Base64.NO_PADDING));
return true;
}
public static Person[] getPersons(ShortcutInfo si) {
Person[] persons = si.getPersons();
return persons == null ? Utilities.EMPTY_PERSON_ARRAY : persons;
}
}

View File

@ -16,11 +16,9 @@
package com.android.launcher3.uioverrides;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import com.android.launcher3.Launcher;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.anim.AnimatorSetBuilder;
@ -30,18 +28,14 @@ import com.android.quickstep.SystemUiProxy;
public class BackButtonAlphaHandler implements LauncherStateManager.StateHandler {
private static final String TAG = "BackButtonAlphaHandler";
private final BaseQuickstepLauncher mLauncher;
private final Launcher mLauncher;
public BackButtonAlphaHandler(Launcher launcher) {
public BackButtonAlphaHandler(BaseQuickstepLauncher launcher) {
mLauncher = launcher;
}
@Override
public void setState(LauncherState state) {
UiFactory.onLauncherStateOrFocusChanged(mLauncher);
}
public void setState(LauncherState state) { }
@Override
public void setStateWithAnimation(LauncherState toState,
@ -52,8 +46,8 @@ public class BackButtonAlphaHandler implements LauncherStateManager.StateHandler
if (!SysUINavigationMode.getMode(mLauncher).hasGestures) {
// If the nav mode is not gestural, then force back button alpha to be 1
UiThreadHelper.setBackButtonAlphaAsync(mLauncher, UiFactory.SET_BACK_BUTTON_ALPHA, 1f,
true /* animate */);
UiThreadHelper.setBackButtonAlphaAsync(mLauncher,
BaseQuickstepLauncher.SET_BACK_BUTTON_ALPHA, 1f, true /* animate */);
return;
}
@ -64,15 +58,8 @@ public class BackButtonAlphaHandler implements LauncherStateManager.StateHandler
anim.setDuration(config.duration);
anim.addUpdateListener(valueAnimator -> {
final float alpha = (float) valueAnimator.getAnimatedValue();
UiThreadHelper.setBackButtonAlphaAsync(mLauncher, UiFactory.SET_BACK_BUTTON_ALPHA,
alpha, false /* animate */);
});
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// Reapply the final alpha in case some state (e.g. window focus) changed.
UiFactory.onLauncherStateOrFocusChanged(mLauncher);
}
UiThreadHelper.setBackButtonAlphaAsync(mLauncher,
BaseQuickstepLauncher.SET_BACK_BUTTON_ALPHA, alpha, false /* animate */);
});
builder.play(anim);
}

View File

@ -1,267 +0,0 @@
/*
* Copyright (C) 2017 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.launcher3.uioverrides;
import static android.app.Activity.RESULT_CANCELED;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.DiscoveryBounce.BOUNCE_MAX_COUNT;
import static com.android.launcher3.allapps.DiscoveryBounce.HOME_BOUNCE_COUNT;
import static com.android.launcher3.allapps.DiscoveryBounce.HOME_BOUNCE_SEEN;
import static com.android.launcher3.allapps.DiscoveryBounce.SHELF_BOUNCE_COUNT;
import static com.android.launcher3.allapps.DiscoveryBounce.SHELF_BOUNCE_SEEN;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.app.Person;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ShortcutInfo;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.util.Base64;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherState.ScaleAndTranslation;
import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.QuickstepAppTransitionManagerImpl;
import com.android.launcher3.Utilities;
import com.android.launcher3.proxy.ProxyActivityStarter;
import com.android.launcher3.proxy.StartActivityParams;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
import com.android.systemui.shared.system.ActivityCompat;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.util.zip.Deflater;
public class UiFactory extends RecentsUiFactory {
/**
* Reusable command for applying the back button alpha on the background thread.
*/
public static final UiThreadHelper.AsyncCommand SET_BACK_BUTTON_ALPHA =
(context, arg1, arg2) -> {
SystemUiProxy.INSTANCE.get(context).setBackButtonAlpha(Float.intBitsToFloat(arg1),
arg2 != 0);
};
public static Runnable enableLiveUIChanges(Launcher launcher) {
NavigationModeChangeListener listener = m -> {
launcher.getDragLayer().recreateControllers();
launcher.getRotationHelper().setRotationHadDifferentUI(m != Mode.NO_BUTTON);
};
SysUINavigationMode mode = SysUINavigationMode.INSTANCE.get(launcher);
SysUINavigationMode.Mode m = mode.addModeChangeListener(listener);
launcher.getRotationHelper().setRotationHadDifferentUI(m != Mode.NO_BUTTON);
return () -> mode.removeModeChangeListener(listener);
}
public static StateHandler[] getStateHandler(Launcher launcher) {
return new StateHandler[] {
launcher.getAllAppsController(),
launcher.getWorkspace(),
createRecentsViewStateController(launcher),
new BackButtonAlphaHandler(launcher)};
}
/**
* Sets the back button visibility based on the current state/window focus.
*/
public static void onLauncherStateOrFocusChanged(Launcher launcher) {
Mode mode = SysUINavigationMode.getMode(launcher);
boolean shouldBackButtonBeHidden = mode.hasGestures
&& launcher != null
&& launcher.getStateManager().getState().hideBackButton
&& launcher.hasWindowFocus();
if (shouldBackButtonBeHidden) {
// Show the back button if there is a floating view visible.
shouldBackButtonBeHidden = AbstractFloatingView.getTopOpenViewWithType(launcher,
TYPE_ALL & ~TYPE_HIDE_BACK_BUTTON) == null;
}
UiThreadHelper.setBackButtonAlphaAsync(launcher, UiFactory.SET_BACK_BUTTON_ALPHA,
shouldBackButtonBeHidden ? 0f : 1f, true /* animate */);
if (launcher != null && launcher.getDragLayer() != null) {
launcher.getRootView().setDisallowBackGesture(shouldBackButtonBeHidden);
}
}
public static void onCreate(Launcher launcher) {
if (!launcher.getSharedPrefs().getBoolean(HOME_BOUNCE_SEEN, false)) {
launcher.getStateManager().addStateListener(new LauncherStateManager.StateListener() {
@Override
public void onStateTransitionStart(LauncherState toState) {
}
@Override
public void onStateTransitionComplete(LauncherState finalState) {
boolean swipeUpEnabled = SysUINavigationMode.INSTANCE.get(launcher).getMode()
.hasGestures;
LauncherState prevState = launcher.getStateManager().getLastState();
if (((swipeUpEnabled && finalState == OVERVIEW) || (!swipeUpEnabled
&& finalState == ALL_APPS && prevState == NORMAL) || BOUNCE_MAX_COUNT <=
launcher.getSharedPrefs().getInt(HOME_BOUNCE_COUNT, 0))) {
launcher.getSharedPrefs().edit().putBoolean(HOME_BOUNCE_SEEN, true).apply();
launcher.getStateManager().removeStateListener(this);
}
}
});
}
if (!launcher.getSharedPrefs().getBoolean(SHELF_BOUNCE_SEEN, false)) {
launcher.getStateManager().addStateListener(new LauncherStateManager.StateListener() {
@Override
public void onStateTransitionStart(LauncherState toState) {
}
@Override
public void onStateTransitionComplete(LauncherState finalState) {
LauncherState prevState = launcher.getStateManager().getLastState();
if ((finalState == ALL_APPS && prevState == OVERVIEW) || BOUNCE_MAX_COUNT <=
launcher.getSharedPrefs().getInt(SHELF_BOUNCE_COUNT, 0)) {
launcher.getSharedPrefs().edit().putBoolean(SHELF_BOUNCE_SEEN, true).apply();
launcher.getStateManager().removeStateListener(this);
}
}
});
}
}
public static void onEnterAnimationComplete(Context context) {
// After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
// as a part of quickstep, so that high-res thumbnails can load the next time we enter
// overview
RecentsModel.INSTANCE.get(context).getThumbnailCache()
.getHighResLoadingState().setVisible(true);
}
public static void onTrimMemory(Context context, int level) {
RecentsModel model = RecentsModel.INSTANCE.get(context);
if (model != null) {
model.onTrimMemory(level);
}
}
public static void useFadeOutAnimationForLauncherStart(Launcher launcher,
CancellationSignal cancellationSignal) {
QuickstepAppTransitionManagerImpl appTransitionManager =
(QuickstepAppTransitionManagerImpl) launcher.getAppTransitionManager();
appTransitionManager.setRemoteAnimationProvider((appTargets, wallpaperTargets) -> {
// On the first call clear the reference.
cancellationSignal.cancel();
ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0);
fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(appTargets,
wallpaperTargets));
AnimatorSet anim = new AnimatorSet();
anim.play(fadeAnimation);
return anim;
}, cancellationSignal);
}
public static boolean dumpActivity(Activity activity, PrintWriter writer) {
if (!Utilities.IS_DEBUG_DEVICE) {
return false;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
if (!(new ActivityCompat(activity).encodeViewHierarchy(out))) {
return false;
}
Deflater deflater = new Deflater();
deflater.setInput(out.toByteArray());
deflater.finish();
out.reset();
byte[] buffer = new byte[1024];
while (!deflater.finished()) {
int count = deflater.deflate(buffer); // returns the generated code... index
out.write(buffer, 0, count);
}
writer.println("--encoded-view-dump-v0--");
writer.println(Base64.encodeToString(
out.toByteArray(), Base64.NO_WRAP | Base64.NO_PADDING));
return true;
}
public static boolean startIntentSenderForResult(Activity activity, IntentSender intent,
int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
Bundle options) {
StartActivityParams params = new StartActivityParams(activity, requestCode);
params.intentSender = intent;
params.fillInIntent = fillInIntent;
params.flagsMask = flagsMask;
params.flagsValues = flagsValues;
params.extraFlags = extraFlags;
params.options = options;
((Context) activity).startActivity(ProxyActivityStarter.getLaunchIntent(activity, params));
return true;
}
public static boolean startActivityForResult(Activity activity, Intent intent, int requestCode,
Bundle options) {
StartActivityParams params = new StartActivityParams(activity, requestCode);
params.intent = intent;
params.options = options;
activity.startActivity(ProxyActivityStarter.getLaunchIntent(activity, params));
return true;
}
/**
* Removes any active ProxyActivityStarter task and sends RESULT_CANCELED to Launcher.
*
* ProxyActivityStarter is started with clear task to reset the task after which it removes the
* task itself.
*/
public static void resetPendingActivityResults(Launcher launcher, int requestCode) {
launcher.onActivityResult(requestCode, RESULT_CANCELED, null);
launcher.startActivity(ProxyActivityStarter.getLaunchIntent(launcher, null));
}
public static ScaleAndTranslation getOverviewScaleAndTranslationForNormalState(Launcher l) {
if (SysUINavigationMode.getMode(l) == Mode.NO_BUTTON) {
float offscreenTranslationX = l.getDeviceProfile().widthPx
- l.getOverviewPanel().getPaddingStart();
return new ScaleAndTranslation(1f, offscreenTranslationX, 0f);
}
return new ScaleAndTranslation(1.1f, 0f, 0f);
}
public static Person[] getPersons(ShortcutInfo si) {
Person[] persons = si.getPersons();
return persons == null ? Utilities.EMPTY_PERSON_ARRAY : persons;
}
}

View File

@ -27,7 +27,6 @@ import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
@ -122,13 +121,17 @@ public abstract class BaseRecentsActivity extends BaseDraggingActivity {
@Override
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
UiFactory.onEnterAnimationComplete(this);
// After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
// as a part of quickstep, so that high-res thumbnails can load the next time we enter
// overview
RecentsModel.INSTANCE.get(this).getThumbnailCache()
.getHighResLoadingState().setVisible(true);
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
UiFactory.onTrimMemory(this, level);
RecentsModel.INSTANCE.get(this).onTrimMemory(level);
}
@Override

View File

@ -15,7 +15,7 @@
*/
package com.android.quickstep;
import static com.android.launcher3.uioverrides.RecentsUiFactory.GO_LOW_RAM_RECENTS_ENABLED;
import static com.android.launcher3.uioverrides.QuickstepLauncher.GO_LOW_RAM_RECENTS_ENABLED;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.ComponentName;

View File

@ -35,7 +35,7 @@ import com.android.launcher3.logging.StatsLogUtils;
import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.ViewCache;
@ -81,19 +81,39 @@ public abstract class BaseActivity extends Activity
protected StatsLogManager mStatsLogManager;
protected SystemUiController mSystemUiController;
private static final int ACTIVITY_STATE_STARTED = 1 << 0;
private static final int ACTIVITY_STATE_RESUMED = 1 << 1;
public static final int ACTIVITY_STATE_STARTED = 1 << 0;
public static final int ACTIVITY_STATE_RESUMED = 1 << 1;
/**
* State flag indicating if the user is active or the actitvity when to background as a result
* State flags indicating that the activity has received one frame after resume, and was
* not immediately paused.
*/
public static final int ACTIVITY_STATE_DEFERRED_RESUMED = 1 << 2;
public static final int ACTIVITY_STATE_WINDOW_FOCUSED = 1 << 3;
/**
* State flag indicating if the user is active or the activity when to background as a result
* of user action.
* @see #isUserActive()
*/
private static final int ACTIVITY_STATE_USER_ACTIVE = 1 << 2;
public static final int ACTIVITY_STATE_USER_ACTIVE = 1 << 4;
/**
* State flag indicating that a state transition is in progress
*/
public static final int ACTIVITY_STATE_TRANSITION_ACTIVE = 1 << 5;
@Retention(SOURCE)
@IntDef(
flag = true,
value = {ACTIVITY_STATE_STARTED, ACTIVITY_STATE_RESUMED, ACTIVITY_STATE_USER_ACTIVE})
value = {ACTIVITY_STATE_STARTED,
ACTIVITY_STATE_RESUMED,
ACTIVITY_STATE_DEFERRED_RESUMED,
ACTIVITY_STATE_WINDOW_FOCUSED,
ACTIVITY_STATE_USER_ACTIVE,
ACTIVITY_STATE_TRANSITION_ACTIVE})
public @interface ActivityFlags{}
@ActivityFlags
@ -146,19 +166,19 @@ public abstract class BaseActivity extends Activity
@Override
protected void onStart() {
mActivityFlags |= ACTIVITY_STATE_STARTED;
addActivityFlags(ACTIVITY_STATE_STARTED);
super.onStart();
}
@Override
protected void onResume() {
mActivityFlags |= ACTIVITY_STATE_RESUMED | ACTIVITY_STATE_USER_ACTIVE;
addActivityFlags(ACTIVITY_STATE_RESUMED | ACTIVITY_STATE_USER_ACTIVE);
super.onResume();
}
@Override
protected void onUserLeaveHint() {
mActivityFlags &= ~ACTIVITY_STATE_USER_ACTIVE;
removeActivityFlags(ACTIVITY_STATE_USER_ACTIVE);
super.onUserLeaveHint();
}
@ -172,7 +192,7 @@ public abstract class BaseActivity extends Activity
@Override
protected void onStop() {
mActivityFlags &= ~ACTIVITY_STATE_STARTED & ~ACTIVITY_STATE_USER_ACTIVE;
removeActivityFlags(ACTIVITY_STATE_STARTED | ACTIVITY_STATE_USER_ACTIVE);
mForceInvisible = 0;
super.onStop();
@ -183,7 +203,7 @@ public abstract class BaseActivity extends Activity
@Override
protected void onPause() {
mActivityFlags &= ~ACTIVITY_STATE_RESUMED;
removeActivityFlags(ACTIVITY_STATE_RESUMED | ACTIVITY_STATE_DEFERRED_RESUMED);
super.onPause();
// Reset the overridden sysui flags used for the task-swipe launch animation, we do this
@ -193,6 +213,17 @@ public abstract class BaseActivity extends Activity
getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
addActivityFlags(ACTIVITY_STATE_WINDOW_FOCUSED);
} else {
removeActivityFlags(ACTIVITY_STATE_WINDOW_FOCUSED);
}
}
public boolean isStarted() {
return (mActivityFlags & ACTIVITY_STATE_STARTED) != 0;
}
@ -208,6 +239,22 @@ public abstract class BaseActivity extends Activity
return (mActivityFlags & ACTIVITY_STATE_USER_ACTIVE) != 0;
}
public int getActivityFlags() {
return mActivityFlags;
}
protected void addActivityFlags(int flags) {
mActivityFlags |= flags;
onActivityFlagsChanged(flags);
}
protected void removeActivityFlags(int flags) {
mActivityFlags &= ~flags;
onActivityFlagsChanged(flags);
}
protected void onActivityFlagsChanged(int changeBits) { }
public void addOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
mDPChangeListeners.add(listener);
}
@ -233,7 +280,7 @@ public abstract class BaseActivity extends Activity
/**
* Used to set the override visibility state, used only to handle the transition home with the
* recents animation.
* @see QuickstepAppTransitionManagerImpl#getWallpaperOpenRunner()
* @see QuickstepAppTransitionManagerImpl#getWallpaperOpenRunner
*/
public void addForceInvisibleFlag(@InvisibilityFlags int flag) {
mForceInvisible |= flag;
@ -260,7 +307,7 @@ public abstract class BaseActivity extends Activity
@Override
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
if (!UiFactory.dumpActivity(this, writer)) {
if (!ApiWrapper.dumpActivity(this, writer)) {
super.dump(prefix, fd, writer, args);
}
}

View File

@ -58,6 +58,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Parcelable;
import android.os.Process;
@ -82,6 +83,8 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.LauncherState.ScaleAndTranslation;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.AllAppsStore;
@ -114,8 +117,8 @@ import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.qsb.QsbContainerView;
import com.android.launcher3.states.RotationHelper;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
@ -135,6 +138,7 @@ import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.UiThreadHelper;
import com.android.launcher3.util.ViewOnDrawExecutor;
@ -294,12 +298,11 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
*/
private PendingRequestArgs mPendingRequestArgs;
// Request id for any pending activity result
private int mPendingActivityRequestCode = -1;
protected int mPendingActivityRequestCode = -1;
public ViewGroupFocusHelper mFocusHandler;
private RotationHelper mRotationHelper;
private Runnable mCancelTouchController;
final Handler mHandler = new Handler();
private final Runnable mHandleDeferredResume = this::handleDeferredResume;
@ -350,7 +353,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
mDragController = new DragController(this);
mAllAppsController = new AllAppsTransitionController(this);
mStateManager = new LauncherStateManager(this);
UiFactory.onCreate(this);
mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);
mAppWidgetHost = new LauncherAppWidgetHost(this,
@ -474,7 +476,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
@Override
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
UiFactory.onEnterAnimationComplete(this);
mAllAppsController.highlightWorkTabIfNecessary();
mRotationHelper.setCurrentTransitionRequest(REQUEST_NONE);
}
@ -488,7 +489,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
mOldConfig.setTo(newConfig);
UiFactory.onLauncherStateOrResumeChanged(this);
super.onConfigurationChanged(newConfig);
}
@ -504,7 +504,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
public void reapplyUi() {
if (supportsFakeLandscapeUI()) {
mRotationMode = mStableDeviceProfile == null
? RotationMode.NORMAL : UiFactory.getRotationMode(mDeviceProfile);
? RotationMode.NORMAL : getFakeRotationMode(mDeviceProfile);
}
getRootView().dispatchInsets();
getStateManager().reapplyState(true /* cancelCurrentAnimation */);
@ -567,7 +567,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
if (supportsFakeLandscapeUI() && mDeviceProfile.isVerticalBarLayout()) {
mStableDeviceProfile = mDeviceProfile.inv.portraitProfile;
mRotationMode = UiFactory.getRotationMode(mDeviceProfile);
mRotationMode = getFakeRotationMode(mDeviceProfile);
} else {
mStableDeviceProfile = null;
mRotationMode = RotationMode.NORMAL;
@ -933,8 +933,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
NotificationListener.removeNotificationsChangedListener();
getStateManager().moveToRestState();
UiFactory.onLauncherStateOrResumeChanged(this);
// Workaround for b/78520668, explicitly trim memory once UI is hidden
onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
}
@ -957,7 +955,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
logStopAndResume(Action.Command.RESUME);
getUserEventDispatcher().startSession();
UiFactory.onLauncherStateOrResumeChanged(this);
AppLaunchTracker.INSTANCE.get(this).onReturnedToHome();
// Process any items that were added while Launcher was away.
@ -972,15 +969,17 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
DiscoveryBounce.showForHomeIfNeeded(this);
if (mPendingActivityRequestCode != -1 && isInState(NORMAL)) {
UiFactory.resetPendingActivityResults(this, mPendingActivityRequestCode);
}
onDeferredResumed();
addActivityFlags(ACTIVITY_STATE_DEFERRED_RESUMED);
mDeferredResumePending = false;
} else {
mDeferredResumePending = true;
}
}
protected void onDeferredResumed() { }
private void logStopAndResume(int command) {
int containerType = mStateManager.getState().containerType;
if (containerType == ContainerType.WORKSPACE && mWorkspace != null) {
@ -1034,12 +1033,14 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
if (mDeferOverlayCallbacks) {
scheduleDeferredCheck();
}
addActivityFlags(ACTIVITY_STATE_TRANSITION_ACTIVE);
}
public void onStateSetEnd(LauncherState state) {
getAppWidgetHost().setResumed(state == LauncherState.NORMAL);
getWorkspace().setClipChildren(!state.disablePageClipping);
finishAutoCancelActionMode();
removeActivityFlags(ACTIVITY_STATE_TRANSITION_ACTIVE);
}
@Override
@ -1084,18 +1085,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
}
@Override
protected void onUserLeaveHint() {
super.onUserLeaveHint();
UiFactory.onLauncherStateOrResumeChanged(this);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
mStateManager.onWindowFocusChanged();
}
class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {
public void onScrollChanged(float progress) {
@ -1159,7 +1148,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
// Setup the drag layer
mDragLayer.setup(mDragController, mWorkspace);
mCancelTouchController = UiFactory.enableLiveUIChanges(this);
mWorkspace.setup(mDragController);
// Until the workspace is bound, ensure that we keep the wallpaper offset locked to the
@ -1537,11 +1525,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
mWorkspace.removeFolderListeners();
PluginManagerWrapper.INSTANCE.get(this).removePluginListener(this);
if (mCancelTouchController != null) {
mCancelTouchController.run();
mCancelTouchController = null;
}
// Stop callbacks from LauncherModel
// It's possible to receive onDestroy after a new Launcher activity has
// been created. In this case, don't interfere with the new Launcher.
@ -1577,10 +1560,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
if (requestCode != -1) {
mPendingActivityRequestCode = requestCode;
}
if (requestCode == -1
|| !UiFactory.startActivityForResult(this, intent, requestCode, options)) {
super.startActivityForResult(intent, requestCode, options);
}
super.startActivityForResult(intent, requestCode, options);
}
@Override
@ -1589,14 +1569,11 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
if (requestCode != -1) {
mPendingActivityRequestCode = requestCode;
}
if (requestCode == -1 || !UiFactory.startIntentSenderForResult(this, intent, requestCode,
fillInIntent, flagsMask, flagsValues, extraFlags, options)) {
try {
super.startIntentSenderForResult(intent, requestCode,
fillInIntent, flagsMask, flagsValues, extraFlags, options);
} catch (IntentSender.SendIntentException e) {
throw new ActivityNotFoundException();
}
try {
super.startIntentSenderForResult(intent, requestCode,
fillInIntent, flagsMask, flagsValues, extraFlags, options);
} catch (IntentSender.SendIntentException e) {
throw new ActivityNotFoundException();
}
}
@ -1934,7 +1911,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
// This clears all widget bitmaps from the widget tray
// TODO(hyunyoungs)
}
UiFactory.onTrimMemory(this, level);
}
@Override
@ -2653,16 +2629,36 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
return super.onKeyUp(keyCode, event);
}
public static Launcher getLauncher(Context context) {
return (Launcher) fromContext(context);
protected StateHandler[] createStateHandlers() {
return new StateHandler[] { getAllAppsController(), getWorkspace() };
}
public TouchController[] createTouchControllers() {
return new TouchController[] {getDragController(), new AllAppsSwipeController(this)};
}
protected RotationMode getFakeRotationMode(DeviceProfile deviceProfile) {
return RotationMode.NORMAL;
}
protected ScaleAndTranslation getOverviewScaleAndTranslationForNormalState() {
return new ScaleAndTranslation(1.1f, 0f, 0f);
}
public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) { }
public void onDragLayerHierarchyChanged() { }
@Override
public void returnToHomescreen() {
super.returnToHomescreen();
getStateManager().goToState(LauncherState.NORMAL);
}
public static Launcher getLauncher(Context context) {
return (Launcher) fromContext(context);
}
/**
* Just a wrapper around the type cast to allow easier tracking of calls.
*/

View File

@ -26,9 +26,11 @@ import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSL
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_SCALE;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.BACKGROUND_APP_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.NORMAL_STATE_ORDINAL;
@ -36,14 +38,11 @@ import static com.android.launcher3.testing.TestProtocol.OVERVIEW_PEEK_STATE_ORD
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
import android.view.animation.Interpolator;
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.states.SpringLoadedState;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.uioverrides.states.AllAppsState;
import com.android.launcher3.uioverrides.states.OverviewState;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@ -210,7 +209,7 @@ public class LauncherState {
}
public ScaleAndTranslation getOverviewScaleAndTranslation(Launcher launcher) {
return UiFactory.getOverviewScaleAndTranslationForNormalState(launcher);
return launcher.getOverviewScaleAndTranslationForNormalState();
}
public float getOverviewFullscreenProgress() {

View File

@ -24,7 +24,8 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.IntDef;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
@ -32,16 +33,12 @@ import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.anim.PropertySetter.AnimatedPropertySetter;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.uioverrides.UiFactory;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import androidx.annotation.IntDef;
/**
* TODO: figure out what kind of tests we can write for this
*
@ -146,7 +143,7 @@ public class LauncherStateManager {
public StateHandler[] getStateHandlers() {
if (mStateHandlers == null) {
mStateHandlers = UiFactory.getStateHandler(mLauncher);
mStateHandlers = mLauncher.createStateHandlers();
}
return mStateHandlers;
}
@ -414,7 +411,6 @@ public class LauncherStateManager {
// Only disable clipping if needed, otherwise leave it as previous value.
mLauncher.getWorkspace().setClipChildren(false);
}
UiFactory.onLauncherStateOrResumeChanged(mLauncher);
for (int i = mListeners.size() - 1; i >= 0; i--) {
mListeners.get(i).onStateTransitionStart(state);
@ -435,8 +431,6 @@ public class LauncherStateManager {
setRestState(null);
}
UiFactory.onLauncherStateOrResumeChanged(mLauncher);
for (int i = mListeners.size() - 1; i >= 0; i--) {
mListeners.get(i).onStateTransitionComplete(state);
}
@ -444,10 +438,6 @@ public class LauncherStateManager {
AccessibilityManagerCompat.sendStateEventToTest(mLauncher, state.ordinal);
}
public void onWindowFocusChanged() {
UiFactory.onLauncherStateOrFocusChanged(mLauncher);
}
public LauncherState getLastState() {
return mLastStableState;
}

View File

@ -28,7 +28,7 @@ import androidx.annotation.NonNull;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.util.ContentWriter;
import java.util.Arrays;
@ -192,7 +192,7 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon {
}
disabledMessage = shortcutInfo.getDisabledMessage();
Person[] persons = UiFactory.getPersons(shortcutInfo);
Person[] persons = ApiWrapper.getPersons(shortcutInfo);
personKeys = persons.length == 0 ? Utilities.EMPTY_STRING_ARRAY
: Arrays.stream(persons).map(Person::getKey).sorted().toArray(String[]::new);
}

View File

@ -57,7 +57,6 @@ import com.android.launcher3.graphics.OverviewScrim;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.graphics.WorkspaceAndHotseatScrim;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.BaseDragLayer;
import com.android.launcher3.views.Transposable;
@ -121,7 +120,7 @@ public class DragLayer extends BaseDragLayer<Launcher> {
}
public void recreateControllers() {
mControllers = UiFactory.createTouchControllers(mActivity);
mControllers = mActivity.createTouchControllers();
}
public ViewGroupFocusHelper getFocusIndicatorHelper() {
@ -477,14 +476,14 @@ public class DragLayer extends BaseDragLayer<Launcher> {
public void onViewAdded(View child) {
super.onViewAdded(child);
updateChildIndices();
UiFactory.onLauncherStateOrFocusChanged(mActivity);
mActivity.onDragLayerHierarchyChanged();
}
@Override
public void onViewRemoved(View child) {
super.onViewRemoved(child);
updateChildIndices();
UiFactory.onLauncherStateOrFocusChanged(mActivity);
mActivity.onDragLayerHierarchyChanged();
}
@Override

View File

@ -32,7 +32,6 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.PendingAddItemInfo;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
@ -68,7 +67,7 @@ public class PinItemDragListener extends BaseItemDragListener {
public boolean init(Launcher launcher, boolean alreadyOnHome) {
super.init(launcher, alreadyOnHome);
if (!alreadyOnHome) {
UiFactory.useFadeOutAnimationForLauncherStart(launcher, mCancelSignal);
launcher.useFadeOutAnimationForLauncherStart(mCancelSignal);
}
return false;
}

View File

@ -1,4 +1,19 @@
package com.android.launcher3.uioverrides;
/**
* Copyright (C) 2019 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.launcher3.touch;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
@ -9,8 +24,6 @@ import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager.AnimationComponents;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SwipeDetector;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
/**
@ -58,8 +71,8 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
@Override
protected int getLogContainerTypeForNormalState(MotionEvent ev) {
return mLauncher.getDragLayer().isEventOverView(mLauncher.getHotseat(), mTouchDownEvent) ?
ContainerType.HOTSEAT : ContainerType.WORKSPACE;
return mLauncher.getDragLayer().isEventOverView(mLauncher.getHotseat(), mTouchDownEvent)
? ContainerType.HOTSEAT : ContainerType.WORKSPACE;
}
@Override

View File

@ -23,7 +23,6 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.inputmethod.InputMethodManager;
import com.android.launcher3.uioverrides.UiFactory;
/**
* Utility class for offloading some class from UI thread

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2017 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.launcher3.uioverrides;
import android.app.Activity;
import android.app.Person;
import android.content.pm.ShortcutInfo;
import com.android.launcher3.Utilities;
import java.io.PrintWriter;
public class ApiWrapper {
public static boolean dumpActivity(Activity activity, PrintWriter writer) {
return false;
}
public static Person[] getPersons(ShortcutInfo si) {
return Utilities.EMPTY_PERSON_ARRAY;
}
}

View File

@ -1,102 +0,0 @@
/*
* Copyright (C) 2017 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.launcher3.uioverrides;
import android.app.Activity;
import android.app.Person;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ShortcutInfo;
import android.os.Bundle;
import android.os.CancellationSignal;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState.ScaleAndTranslation;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.Utilities;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.util.TouchController;
import java.io.PrintWriter;
public class UiFactory {
public static TouchController[] createTouchControllers(Launcher launcher) {
return new TouchController[] {
launcher.getDragController(), new AllAppsSwipeController(launcher)};
}
public static Runnable enableLiveUIChanges(Launcher l) {
return null;
}
public static StateHandler[] getStateHandler(Launcher launcher) {
return new StateHandler[] {
launcher.getAllAppsController(), launcher.getWorkspace() };
}
public static void resetOverview(Launcher launcher) { }
public static void onLauncherStateOrFocusChanged(Launcher launcher) { }
public static void onCreate(Launcher launcher) { }
public static void onStart(Launcher launcher) { }
public static void onEnterAnimationComplete(Context context) {}
public static void onLauncherStateOrResumeChanged(Launcher launcher) { }
public static void onTrimMemory(Launcher launcher, int level) { }
public static void useFadeOutAnimationForLauncherStart(Launcher launcher,
CancellationSignal cancellationSignal) { }
public static boolean dumpActivity(Activity activity, PrintWriter writer) {
return false;
}
public static void setBackButtonAlpha(Launcher launcher, float alpha, boolean animate) { }
public static ScaleAndTranslation getOverviewScaleAndTranslationForNormalState(Launcher l) {
return new ScaleAndTranslation(1.1f, 0f, 0f);
}
public static RotationMode getRotationMode(DeviceProfile dp) {
return RotationMode.NORMAL;
}
public static boolean startIntentSenderForResult(Activity activity, IntentSender intent,
int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
Bundle options) {
return false;
}
public static boolean startActivityForResult(Activity activity, Intent intent, int requestCode,
Bundle options) {
return false;
}
public static void resetPendingActivityResults(Launcher launcher, int requestCode) { }
public static Person[] getPersons(ShortcutInfo si) {
return Utilities.EMPTY_PERSON_ARRAY;
}
}