Fix Settings restart during Reset mobile nework settings flow
This CL avoids restarting Settings in the reset mobile flow when phone process is restarted, by switching the usage of the stable content provider connection to the unstable client. The CL also arranges restarting phone process as the last reset operation in the flow (later than RILD reset) to avoid any reset operation get impacted by phone process restarting. Since the permission to protect the TelephonyContentProvider has been renamed, the CL also renames the requsted permision. Bug: 347047105 Test: atest ResetNetworkOperationBuilderTest Test: Reset mobile network feature test Flag: EXEMPT resource update with minor refactoring Change-Id: I7bfa79bc9d7451a4a03269704b0009a3730e287f
This commit is contained in:
@@ -140,7 +140,7 @@
|
|||||||
<uses-permission android:name="android.permission.REMAP_MODIFIER_KEYS" />
|
<uses-permission android:name="android.permission.REMAP_MODIFIER_KEYS" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_GPU_SERVICE" />
|
<uses-permission android:name="android.permission.ACCESS_GPU_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.MANAGE_GAME_MODE" />
|
<uses-permission android:name="android.permission.MANAGE_GAME_MODE" />
|
||||||
<uses-permission android:name="android.permission.RESTART_PHONE_PROCESS" />
|
<uses-permission android:name="android.permission.RESTART_TELEPHONY_PROCESS" />
|
||||||
<uses-permission android:name="android.permission.MANAGE_ENHANCED_CONFIRMATION_STATES" />
|
<uses-permission android:name="android.permission.MANAGE_ENHANCED_CONFIRMATION_STATES" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
|
<uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
|
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
|
||||||
|
@@ -271,12 +271,12 @@ public class ResetNetworkRequest {
|
|||||||
builder.resetIms(mSubscriptionIdToResetIms);
|
builder.resetIms(mSubscriptionIdToResetIms);
|
||||||
}
|
}
|
||||||
// Reset phone process and RILD may impact above components, keep them at the end
|
// Reset phone process and RILD may impact above components, keep them at the end
|
||||||
if ((mResetOptions & RESET_PHONE_PROCESS) != 0) {
|
|
||||||
builder.restartPhoneProcess();
|
|
||||||
}
|
|
||||||
if ((mResetOptions & RESET_RILD) != 0) {
|
if ((mResetOptions & RESET_RILD) != 0) {
|
||||||
builder.restartRild();
|
builder.restartRild();
|
||||||
}
|
}
|
||||||
|
if ((mResetOptions & RESET_PHONE_PROCESS) != 0) {
|
||||||
|
builder.restartPhoneProcess();
|
||||||
|
}
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@ package com.android.settings.network;
|
|||||||
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothManager;
|
import android.bluetooth.BluetoothManager;
|
||||||
|
import android.content.ContentProviderClient;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
@@ -28,11 +29,14 @@ import android.net.wifi.WifiManager;
|
|||||||
import android.net.wifi.p2p.WifiP2pManager;
|
import android.net.wifi.p2p.WifiP2pManager;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.RecoverySystem;
|
import android.os.RecoverySystem;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.ResetNetworkRequest;
|
import com.android.settings.ResetNetworkRequest;
|
||||||
@@ -257,15 +261,15 @@ public class ResetNetworkOperationBuilder {
|
|||||||
*/
|
*/
|
||||||
public ResetNetworkOperationBuilder restartPhoneProcess() {
|
public ResetNetworkOperationBuilder restartPhoneProcess() {
|
||||||
Runnable runnable = () -> {
|
Runnable runnable = () -> {
|
||||||
try {
|
// Unstable content provider can avoid us getting killed together with phone process
|
||||||
mContext.getContentResolver().call(
|
try (ContentProviderClient client = getUnstableTelephonyContentProviderClient()) {
|
||||||
getResetTelephonyContentProviderAuthority(),
|
if (client != null) {
|
||||||
METHOD_RESTART_PHONE_PROCESS,
|
client.call(METHOD_RESTART_PHONE_PROCESS, /* arg= */ null, /* extra= */ null);
|
||||||
/* arg= */ null,
|
Log.i(TAG, "Phone process was restarted.");
|
||||||
/* extras= */ null);
|
}
|
||||||
Log.i(TAG, "Phone process was restarted.");
|
} catch (RemoteException re) {
|
||||||
} catch (IllegalArgumentException iae) {
|
// It's normal to throw RE since phone process immediately dies
|
||||||
Log.w(TAG, "Fail to restart phone process: " + iae);
|
Log.i(TAG, "Phone process has been restarted: " + re);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mResetSequence.add(runnable);
|
mResetSequence.add(runnable);
|
||||||
@@ -279,15 +283,13 @@ public class ResetNetworkOperationBuilder {
|
|||||||
*/
|
*/
|
||||||
public ResetNetworkOperationBuilder restartRild() {
|
public ResetNetworkOperationBuilder restartRild() {
|
||||||
Runnable runnable = () -> {
|
Runnable runnable = () -> {
|
||||||
try {
|
try (ContentProviderClient client = getUnstableTelephonyContentProviderClient()) {
|
||||||
mContext.getContentResolver().call(
|
if (client != null) {
|
||||||
getResetTelephonyContentProviderAuthority(),
|
client.call(METHOD_RESTART_RILD, /* arg= */ null, /* extra= */ null);
|
||||||
METHOD_RESTART_RILD,
|
Log.i(TAG, "RILD was restarted.");
|
||||||
/* arg= */ null,
|
}
|
||||||
/* extras= */ null);
|
} catch (RemoteException re) {
|
||||||
Log.i(TAG, "RILD was restarted.");
|
Log.w(TAG, "Fail to restart RILD: " + re);
|
||||||
} catch (IllegalArgumentException iae) {
|
|
||||||
Log.w(TAG, "Fail to restart RILD: " + iae);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mResetSequence.add(runnable);
|
mResetSequence.add(runnable);
|
||||||
@@ -322,9 +324,18 @@ public class ResetNetworkOperationBuilder {
|
|||||||
* @return the authority of the telephony content provider that support methods
|
* @return the authority of the telephony content provider that support methods
|
||||||
* resetPhoneProcess and resetRild.
|
* resetPhoneProcess and resetRild.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
private String getResetTelephonyContentProviderAuthority() {
|
||||||
String getResetTelephonyContentProviderAuthority() {
|
|
||||||
return mContext.getResources().getString(
|
return mContext.getResources().getString(
|
||||||
R.string.reset_telephony_stack_content_provider_authority);
|
R.string.reset_telephony_stack_content_provider_authority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the unstable content provider to avoid us getting killed with phone process
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
@VisibleForTesting
|
||||||
|
public ContentProviderClient getUnstableTelephonyContentProviderClient() {
|
||||||
|
return mContext.getContentResolver().acquireUnstableContentProviderClient(
|
||||||
|
getResetTelephonyContentProviderAuthority());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,20 +16,16 @@
|
|||||||
|
|
||||||
package com.android.settings.network;
|
package com.android.settings.network;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.ArgumentMatchers.isNull;
|
import static org.mockito.ArgumentMatchers.isNull;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.doThrow;
|
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
import android.content.ContentProviderClient;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkPolicyManager;
|
import android.net.NetworkPolicyManager;
|
||||||
@@ -67,7 +63,7 @@ public class ResetNetworkOperationBuilderTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private NetworkPolicyManager mNetworkPolicyManager;
|
private NetworkPolicyManager mNetworkPolicyManager;
|
||||||
@Mock
|
@Mock
|
||||||
private ContentProvider mContentProvider;;
|
private ContentProviderClient mContentProviderClient;
|
||||||
|
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@@ -77,9 +73,8 @@ public class ResetNetworkOperationBuilderTest {
|
|||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||||
doReturn(ContentResolver.wrap(mContentProvider)).when(mContext).getContentResolver();
|
|
||||||
|
|
||||||
mBuilder = spy(new ResetNetworkOperationBuilder(mContext));
|
mBuilder = spy(new ResetNetworkOperationBuilder(mContext));
|
||||||
|
doReturn(mContentProviderClient).when(mBuilder).getUnstableTelephonyContentProviderClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -184,38 +179,38 @@ public class ResetNetworkOperationBuilderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void restartPhoneProcess_withoutTelephonyContentProvider_shouldNotCrash() {
|
public void restartPhoneProcess_withoutTelephonyContentProvider_shouldNotCrash()
|
||||||
doThrow(new IllegalArgumentException()).when(mContentProvider).call(
|
throws Exception {
|
||||||
anyString(), anyString(), anyString(), any());
|
doReturn(null).when(mBuilder).getUnstableTelephonyContentProviderClient();
|
||||||
|
|
||||||
mBuilder.restartPhoneProcess().build().run();
|
mBuilder.restartPhoneProcess().build().run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void restartRild_withoutTelephonyContentProvider_shouldNotCrash() {
|
public void restartRild_withoutTelephonyContentProvider_shouldNotCrash()
|
||||||
doThrow(new IllegalArgumentException()).when(mContentProvider).call(
|
throws Exception {
|
||||||
anyString(), anyString(), anyString(), any());
|
doReturn(null).when(mBuilder).getUnstableTelephonyContentProviderClient();
|
||||||
|
|
||||||
mBuilder.restartRild().build().run();
|
mBuilder.restartRild().build().run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void restartPhoneProcess_withTelephonyContentProvider_shouldCallRestartPhoneProcess() {
|
public void restartPhoneProcess_withTelephonyContentProvider_shouldCallRestartPhoneProcess()
|
||||||
|
throws Exception {
|
||||||
mBuilder.restartPhoneProcess().build().run();
|
mBuilder.restartPhoneProcess().build().run();
|
||||||
|
|
||||||
verify(mContentProvider).call(
|
verify(mContentProviderClient).call(
|
||||||
eq(mBuilder.getResetTelephonyContentProviderAuthority()),
|
|
||||||
eq(ResetNetworkOperationBuilder.METHOD_RESTART_PHONE_PROCESS),
|
eq(ResetNetworkOperationBuilder.METHOD_RESTART_PHONE_PROCESS),
|
||||||
isNull(),
|
isNull(),
|
||||||
isNull());
|
isNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void restartRild_withTelephonyContentProvider_shouldCallRestartRild() {
|
public void restartRild_withTelephonyContentProvider_shouldCallRestartRild()
|
||||||
|
throws Exception {
|
||||||
mBuilder.restartRild().build().run();
|
mBuilder.restartRild().build().run();
|
||||||
|
|
||||||
verify(mContentProvider).call(
|
verify(mContentProviderClient).call(
|
||||||
eq(mBuilder.getResetTelephonyContentProviderAuthority()),
|
|
||||||
eq(ResetNetworkOperationBuilder.METHOD_RESTART_RILD),
|
eq(ResetNetworkOperationBuilder.METHOD_RESTART_RILD),
|
||||||
isNull(),
|
isNull(),
|
||||||
isNull());
|
isNull());
|
||||||
|
Reference in New Issue
Block a user