OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.multiwindow; | 5 package org.chromium.chrome.browser.multiwindow; |
6 | 6 |
7 import android.annotation.TargetApi; | 7 import android.annotation.TargetApi; |
8 import android.app.Activity; | 8 import android.app.Activity; |
9 import android.app.ActivityManager; | 9 import android.app.ActivityManager; |
10 import android.app.ActivityManager.AppTask; | 10 import android.app.ActivityManager.AppTask; |
11 import android.content.Context; | 11 import android.content.Context; |
12 import android.content.Intent; | 12 import android.content.Intent; |
13 import android.os.Build; | 13 import android.os.Build; |
14 import android.provider.Browser; | 14 import android.provider.Browser; |
15 import android.text.TextUtils; | 15 import android.text.TextUtils; |
16 | 16 |
17 import org.chromium.base.ActivityState; | 17 import org.chromium.base.ActivityState; |
18 import org.chromium.base.ApplicationStatus; | 18 import org.chromium.base.ApplicationStatus; |
19 import org.chromium.base.ApplicationStatus.ActivityStateListener; | 19 import org.chromium.base.ApplicationStatus.ActivityStateListener; |
20 import org.chromium.base.VisibleForTesting; | 20 import org.chromium.base.VisibleForTesting; |
21 import org.chromium.chrome.browser.AppHooks; | 21 import org.chromium.chrome.browser.AppHooks; |
22 import org.chromium.chrome.browser.ChromeTabbedActivity; | 22 import org.chromium.chrome.browser.ChromeTabbedActivity; |
23 import org.chromium.chrome.browser.ChromeTabbedActivity2; | 23 import org.chromium.chrome.browser.ChromeTabbedActivity2; |
24 import org.chromium.chrome.browser.IntentHandler; | 24 import org.chromium.chrome.browser.IntentHandler; |
25 import org.chromium.chrome.browser.document.ChromeLauncherActivity; | 25 import org.chromium.chrome.browser.document.ChromeLauncherActivity; |
26 import org.chromium.chrome.browser.tab.Tab; | |
26 import org.chromium.chrome.browser.util.IntentUtils; | 27 import org.chromium.chrome.browser.util.IntentUtils; |
27 | 28 |
28 import java.lang.ref.WeakReference; | 29 import java.lang.ref.WeakReference; |
29 import java.lang.reflect.InvocationTargetException; | 30 import java.lang.reflect.InvocationTargetException; |
30 import java.lang.reflect.Method; | 31 import java.lang.reflect.Method; |
31 import java.util.List; | 32 import java.util.List; |
32 import java.util.concurrent.atomic.AtomicReference; | 33 import java.util.concurrent.atomic.AtomicReference; |
33 | 34 |
34 import javax.annotation.Nullable; | 35 import javax.annotation.Nullable; |
35 | 36 |
36 /** | 37 /** |
37 * Utilities for detecting multi-window/multi-instance support. | 38 * Utilities for detecting multi-window/multi-instance support. |
38 * | 39 * |
39 * Thread-safe: This class may be accessed from any thread. | 40 * Thread-safe: This class may be accessed from any thread. |
40 */ | 41 */ |
41 public class MultiWindowUtils implements ActivityStateListener { | 42 public class MultiWindowUtils implements ActivityStateListener { |
42 | 43 |
43 // TODO(twellington): replace this with Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT once we're building | 44 // TODO(twellington): replace this with Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT once we're building |
44 // against N. | 45 // against N. |
45 public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT = 0x00001000; | 46 public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT = 0x00001000; |
46 | 47 |
47 private static AtomicReference<MultiWindowUtils> sInstance = | 48 private static AtomicReference<MultiWindowUtils> sInstance = new AtomicRefer ence<>(); |
48 new AtomicReference<MultiWindowUtils>(); | |
49 | 49 |
50 // Used to keep track of whether ChromeTabbedActivity2 is running. A tri-sta te Boolean is | 50 // Used to keep track of whether ChromeTabbedActivity2 is running. A tri-sta te Boolean is |
51 // used in case both activities die in the background and MultiWindowUtils i s recreated. | 51 // used in case both activities die in the background and MultiWindowUtils i s recreated. |
52 private Boolean mTabbedActivity2TaskRunning; | 52 private Boolean mTabbedActivity2TaskRunning; |
53 private WeakReference<ChromeTabbedActivity> mLastResumedTabbedActivity; | 53 private WeakReference<ChromeTabbedActivity> mLastResumedTabbedActivity; |
54 private boolean mIsInMultiWindowModeForTesting; | 54 private boolean mIsInMultiWindowModeForTesting; |
55 | 55 |
56 /** | 56 /** |
57 * Returns the singleton instance of MultiWindowUtils, creating it if needed . | 57 * Returns the singleton instance of MultiWindowUtils, creating it if needed . |
58 */ | 58 */ |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 | 140 |
141 // Let Chrome know that this intent is from Chrome, so that it does not close the app when | 141 // Let Chrome know that this intent is from Chrome, so that it does not close the app when |
142 // the user presses 'back' button. | 142 // the user presses 'back' button. |
143 intent.putExtra(Browser.EXTRA_APPLICATION_ID, activity.getPackageName()) ; | 143 intent.putExtra(Browser.EXTRA_APPLICATION_ID, activity.getPackageName()) ; |
144 intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true); | 144 intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true); |
145 } | 145 } |
146 | 146 |
147 @Override | 147 @Override |
148 public void onActivityStateChange(Activity activity, int newState) { | 148 public void onActivityStateChange(Activity activity, int newState) { |
149 if (newState == ActivityState.RESUMED && activity instanceof ChromeTabbe dActivity) { | 149 if (newState == ActivityState.RESUMED && activity instanceof ChromeTabbe dActivity) { |
150 mLastResumedTabbedActivity = | 150 mLastResumedTabbedActivity = new WeakReference<>((ChromeTabbedActivi ty) activity); |
151 new WeakReference<ChromeTabbedActivity>((ChromeTabbedActivit y) activity); | |
152 } | 151 } |
153 } | 152 } |
154 | 153 |
155 /** | 154 /** |
156 * Determines the correct ChromeTabbedActivity class to use for an incoming intent. | 155 * Determines the correct ChromeTabbedActivity class to use for an incoming intent. |
157 * @param intent The incoming intent that is starting ChromeTabbedActivity. | 156 * @param intent The incoming intent that is starting ChromeTabbedActivity. |
158 * @param context The current Context, used to retrieve the ActivityManager system service. | 157 * @param context The current Context, used to retrieve the ActivityManager system service. |
159 * @return The ChromeTabbedActivity to use for the incoming intent. | 158 * @return The ChromeTabbedActivity to use for the incoming intent. |
160 */ | 159 */ |
161 public Class<? extends ChromeTabbedActivity> getTabbedActivityForIntent( | 160 public Class<? extends ChromeTabbedActivity> getTabbedActivityForIntent( |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 */ | 267 */ |
269 public static boolean isActivityVisible(Activity activity) { | 268 public static boolean isActivityVisible(Activity activity) { |
270 if (activity == null) return false; | 269 if (activity == null) return false; |
271 int activityState = ApplicationStatus.getStateForActivity(activity); | 270 int activityState = ApplicationStatus.getStateForActivity(activity); |
272 // In Android N multi-window mode, only one activity is resumed at a tim e. The other | 271 // In Android N multi-window mode, only one activity is resumed at a tim e. The other |
273 // activity visible on the screen will be in the paused state. Activitie s not visible on | 272 // activity visible on the screen will be in the paused state. Activitie s not visible on |
274 // the screen will be stopped or destroyed. | 273 // the screen will be stopped or destroyed. |
275 return activityState == ActivityState.RESUMED || activityState == Activi tyState.PAUSED; | 274 return activityState == ActivityState.RESUMED || activityState == Activi tyState.PAUSED; |
276 } | 275 } |
277 | 276 |
277 /** | |
278 * Moves a Tab to the other MultiWindow window. | |
279 * @param activity An Activity to use for context. | |
280 * @param tab The Tab to move. | |
281 */ | |
282 public static void moveTabToOtherWindow(Activity activity, Tab tab) { | |
283 moveTabToActivity( | |
284 activity, tab, getInstance().getOpenInOtherWindowActivity(activi ty), false); | |
285 } | |
286 | |
287 /** | |
288 * Moves a Tab to a specific Activity. | |
289 * @param activity An Activity to use for context. | |
290 * @param tab The Tab to move. | |
291 * @param targetActivity The Activity to move the Tab to. | |
Bernhard Bauer
2017/04/07 20:08:59
It's the Activity Class, no? You could also wrap t
PEConn
2017/04/11 00:54:46
Done.
| |
292 * @param pendingFullscreen The fullscreen mode for the Tab to change to aft er being moved. | |
293 * Null if no change is required. | |
294 */ | |
295 public static void moveTabToActivity(Activity activity, Tab tab, | |
296 Class<? extends Activity> targetActivity, @Nullable Boolean pendingF ullscreen) { | |
297 if (targetActivity == null) return; | |
298 | |
299 Intent intent = new Intent(activity, targetActivity); | |
300 MultiWindowUtils.setOpenInOtherWindowIntentExtras(intent, activity, targ etActivity); | |
301 MultiWindowUtils.onMultiInstanceModeStarted(); | |
302 tab.detachAndStartReparenting(intent, null, null, pendingFullscreen); | |
303 } | |
304 | |
278 @VisibleForTesting | 305 @VisibleForTesting |
279 public Boolean getTabbedActivity2TaskRunning() { | 306 public Boolean getTabbedActivity2TaskRunning() { |
280 return mTabbedActivity2TaskRunning; | 307 return mTabbedActivity2TaskRunning; |
281 } | 308 } |
282 | 309 |
283 /** | 310 /** |
284 * @param activity The {@link Activity} to check. | 311 * @param activity The {@link Activity} to check. |
285 * @return Whether or not {@code activity} is currently in pre-N Samsung mul ti-window mode. | 312 * @return Whether or not {@code activity} is currently in pre-N Samsung mul ti-window mode. |
286 */ | 313 */ |
287 public boolean isLegacyMultiWindow(Activity activity) { | 314 public boolean isLegacyMultiWindow(Activity activity) { |
(...skipping 20 matching lines...) Expand all Loading... | |
308 if (isLegacyMultiWindow(activity)) { | 335 if (isLegacyMultiWindow(activity)) { |
309 if (TextUtils.equals(ChromeTabbedActivity.class.getName(), | 336 if (TextUtils.equals(ChromeTabbedActivity.class.getName(), |
310 intent.getComponent().getClassName())) { | 337 intent.getComponent().getClassName())) { |
311 intent.setClassName(activity, MultiInstanceChromeTabbedActivity. class.getName()); | 338 intent.setClassName(activity, MultiInstanceChromeTabbedActivity. class.getName()); |
312 } | 339 } |
313 intent.setFlags(intent.getFlags() | 340 intent.setFlags(intent.getFlags() |
314 & ~(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW _DOCUMENT)); | 341 & ~(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW _DOCUMENT)); |
315 } | 342 } |
316 } | 343 } |
317 } | 344 } |
OLD | NEW |