[Settings] Additional route for dismiss activity dialog
Previous design dismiss an activity dialog through Intent would lead to a pair of creating and finishing activity. The task switch during the creating and finishing may introduce some side effect to the other apps. This change tried to add additional route to avoid from dismiss through Intent but sending an async close request to that specific dialog (if available). Bug: 236956105 Test: local, auto testing Change-Id: I0a7e0e9826a301f2aa0ca34f40b5570f0e384b4f
This commit is contained in:
@@ -65,6 +65,8 @@ public class SimDialogActivity extends FragmentActivity {
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
SimDialogProhibitService.supportDismiss(this);
|
||||||
|
|
||||||
getWindow().addSystemFlags(
|
getWindow().addSystemFlags(
|
||||||
WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
||||||
showOrUpdateDialog();
|
showOrUpdateDialog();
|
||||||
@@ -225,4 +227,15 @@ public class SimDialogActivity extends FragmentActivity {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Force dismiss this Activity.
|
||||||
|
*/
|
||||||
|
protected void forceClose() {
|
||||||
|
if (isFinishing() || isDestroyed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.d(TAG, "Dismissed by Service");
|
||||||
|
finishAndRemoveTask();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
89
src/com/android/settings/sim/SimDialogProhibitService.java
Normal file
89
src/com/android/settings/sim/SimDialogProhibitService.java
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.settings.sim;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class for routing dismiss dialog request to SimDialogActivity.
|
||||||
|
*/
|
||||||
|
public class SimDialogProhibitService {
|
||||||
|
|
||||||
|
private static final String TAG = "SimDialogProhibitService";
|
||||||
|
|
||||||
|
private static WeakReference<SimDialogActivity> sSimDialogActivity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support the dismiss of {@link SimDialogActivity} (singletone.)
|
||||||
|
*
|
||||||
|
* @param activity {@link SimDialogActivity}
|
||||||
|
*/
|
||||||
|
public static void supportDismiss(SimDialogActivity activity) {
|
||||||
|
sSimDialogActivity = new WeakReference<SimDialogActivity>(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dismiss SimDialogActivity dialog.
|
||||||
|
*
|
||||||
|
* @param context is a {@link Context}
|
||||||
|
*/
|
||||||
|
public static void dismissDialog(Context context) {
|
||||||
|
// Dismiss existing dialog.
|
||||||
|
if (!dismissDialogThroughRunnable()) {
|
||||||
|
dismissDialogThroughIntent(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dismiss dialog (if there's any).
|
||||||
|
*
|
||||||
|
* @return {@code true} when success, {@code false} when failure.
|
||||||
|
*/
|
||||||
|
protected static boolean dismissDialogThroughRunnable() {
|
||||||
|
final SimDialogActivity activity = (sSimDialogActivity == null) ?
|
||||||
|
null : sSimDialogActivity.get();
|
||||||
|
if (activity == null) {
|
||||||
|
Log.i(TAG, "No SimDialogActivity for dismiss.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
activity.getMainExecutor().execute(() -> activity.forceClose());
|
||||||
|
return true;
|
||||||
|
} catch (RejectedExecutionException exception) {
|
||||||
|
Log.w(TAG, "Fail to close SimDialogActivity through executor", exception);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dismiss dialog through {@link Intent}.
|
||||||
|
*
|
||||||
|
* @param uiContext is {@link Context} for start SimDialogActivity.
|
||||||
|
*/
|
||||||
|
protected static void dismissDialogThroughIntent(Context uiContext) {
|
||||||
|
Intent newIntent = new Intent(uiContext, SimDialogActivity.class);
|
||||||
|
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, SimDialogActivity.PICK_DISMISS);
|
||||||
|
uiContext.startActivity(newIntent);
|
||||||
|
}
|
||||||
|
}
|
@@ -164,10 +164,7 @@ public class SimSelectNotification extends BroadcastReceiver {
|
|||||||
|
|
||||||
// If the dialog type is to dismiss.
|
// If the dialog type is to dismiss.
|
||||||
if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS) {
|
if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS) {
|
||||||
Intent newIntent = new Intent(context, SimDialogActivity.class);
|
SimDialogProhibitService.dismissDialog(context);
|
||||||
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, PICK_DISMISS);
|
|
||||||
context.startActivity(newIntent);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -42,6 +42,7 @@ import static org.mockito.ArgumentMatchers.any;
|
|||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.clearInvocations;
|
import static org.mockito.Mockito.clearInvocations;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -74,6 +75,7 @@ import org.robolectric.RobolectricTestRunner;
|
|||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(shadows = ShadowAlertDialogCompat.class)
|
@Config(shadows = ShadowAlertDialogCompat.class)
|
||||||
@@ -81,6 +83,8 @@ public class SimSelectNotificationTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@Mock
|
@Mock
|
||||||
|
private Executor mExecutor;
|
||||||
|
@Mock
|
||||||
private NotificationManager mNotificationManager;
|
private NotificationManager mNotificationManager;
|
||||||
@Mock
|
@Mock
|
||||||
private TelephonyManager mTelephonyManager;
|
private TelephonyManager mTelephonyManager;
|
||||||
@@ -94,6 +98,8 @@ public class SimSelectNotificationTest {
|
|||||||
private SubscriptionInfo mSubInfo;
|
private SubscriptionInfo mSubInfo;
|
||||||
@Mock
|
@Mock
|
||||||
private DisplayMetrics mDisplayMetrics;
|
private DisplayMetrics mDisplayMetrics;
|
||||||
|
@Mock
|
||||||
|
private SimDialogActivity mActivity;
|
||||||
|
|
||||||
private final String mFakeDisplayName = "fake_display_name";
|
private final String mFakeDisplayName = "fake_display_name";
|
||||||
private final CharSequence mFakeNotificationChannelTitle = "fake_notification_channel_title";
|
private final CharSequence mFakeNotificationChannelTitle = "fake_notification_channel_title";
|
||||||
@@ -236,27 +242,18 @@ public class SimSelectNotificationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onReceivePrimarySubListChange_WithDismissExtra_shouldDismiss() {
|
public void onReceivePrimarySubListChange_WithDismissExtra_shouldDismiss() {
|
||||||
|
doReturn(mExecutor).when(mActivity).getMainExecutor();
|
||||||
|
SimDialogProhibitService.supportDismiss(mActivity);
|
||||||
|
|
||||||
Intent intent = new Intent(TelephonyManager.ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED);
|
Intent intent = new Intent(TelephonyManager.ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED);
|
||||||
intent.putExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE,
|
intent.putExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE,
|
||||||
EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA);
|
EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS);
|
||||||
|
|
||||||
mSimSelectNotification.onReceive(mContext, intent);
|
mSimSelectNotification.onReceive(mContext, intent);
|
||||||
clearInvocations(mContext);
|
clearInvocations(mContext);
|
||||||
|
|
||||||
// Dismiss.
|
// Dismiss.
|
||||||
intent.putExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE,
|
verify(mExecutor).execute(any());
|
||||||
EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS);
|
|
||||||
mSimSelectNotification.onReceive(mContext, intent);
|
|
||||||
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
|
|
||||||
verify(mContext).startActivity(intentCaptor.capture());
|
|
||||||
Intent capturedIntent = intentCaptor.getValue();
|
|
||||||
assertThat(capturedIntent).isNotNull();
|
|
||||||
assertThat(capturedIntent.getComponent().getClassName()).isEqualTo(
|
|
||||||
SimDialogActivity.class.getName());
|
|
||||||
assertThat(capturedIntent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
.isNotEqualTo(0);
|
|
||||||
assertThat(capturedIntent.getIntExtra(SimDialogActivity.DIALOG_TYPE_KEY, INVALID_PICK))
|
|
||||||
.isEqualTo(PICK_DISMISS);
|
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
public void onReceivePrimarySubListChange_DualCdmaWarning_notificationShouldSend() {
|
public void onReceivePrimarySubListChange_DualCdmaWarning_notificationShouldSend() {
|
||||||
|
Reference in New Issue
Block a user