Merge "Merge "Update DockObserver to send dock intent after device provisioning" into tm-qpr-dev am: 6420742c37 am: 87cf288306"
diff --git a/services/core/java/com/android/server/DockObserver.java b/services/core/java/com/android/server/DockObserver.java
index 540ed4c..3487613 100644
--- a/services/core/java/com/android/server/DockObserver.java
+++ b/services/core/java/com/android/server/DockObserver.java
@@ -19,6 +19,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.database.ContentObserver;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
@@ -73,6 +74,7 @@
private final boolean mAllowTheaterModeWakeFromDock;
private final List<ExtconStateConfig> mExtconStateConfigs;
+ private DeviceProvisionedObserver mDeviceProvisionedObserver;
static final class ExtconStateProvider {
private final Map<String, String> mState;
@@ -110,7 +112,7 @@
Slog.w(TAG, "No state file found at: " + stateFilePath);
return new ExtconStateProvider(new HashMap<>());
} catch (Exception e) {
- Slog.e(TAG, "" , e);
+ Slog.e(TAG, "", e);
return new ExtconStateProvider(new HashMap<>());
}
}
@@ -136,7 +138,7 @@
private static List<ExtconStateConfig> loadExtconStateConfigs(Context context) {
String[] rows = context.getResources().getStringArray(
- com.android.internal.R.array.config_dockExtconStateMapping);
+ com.android.internal.R.array.config_dockExtconStateMapping);
try {
ArrayList<ExtconStateConfig> configs = new ArrayList<>();
for (String row : rows) {
@@ -167,6 +169,7 @@
com.android.internal.R.bool.config_allowTheaterModeWakeFromDock);
mKeepDreamingWhenUndocking = context.getResources().getBoolean(
com.android.internal.R.bool.config_keepDreamingWhenUndocking);
+ mDeviceProvisionedObserver = new DeviceProvisionedObserver(mHandler);
mExtconStateConfigs = loadExtconStateConfigs(context);
@@ -199,15 +202,19 @@
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
synchronized (mLock) {
mSystemReady = true;
-
- // don't bother broadcasting undocked here
- if (mReportedDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
- updateLocked();
- }
+ mDeviceProvisionedObserver.onSystemReady();
+ updateIfDockedLocked();
}
}
}
+ private void updateIfDockedLocked() {
+ // don't bother broadcasting undocked here
+ if (mReportedDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+ updateLocked();
+ }
+ }
+
private void setActualDockStateLocked(int newState) {
mActualDockState = newState;
if (!mUpdatesStopped) {
@@ -252,8 +259,7 @@
// Skip the dock intent if not yet provisioned.
final ContentResolver cr = getContext().getContentResolver();
- if (Settings.Global.getInt(cr,
- Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
+ if (!mDeviceProvisionedObserver.isDeviceProvisioned()) {
Slog.i(TAG, "Device not provisioned, skipping dock broadcast");
return;
}
@@ -419,4 +425,48 @@
}
}
}
+
+ private final class DeviceProvisionedObserver extends ContentObserver {
+ private boolean mRegistered;
+
+ public DeviceProvisionedObserver(Handler handler) {
+ super(handler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ synchronized (mLock) {
+ updateRegistration();
+ if (isDeviceProvisioned()) {
+ // Send the dock broadcast if device is docked after provisioning.
+ updateIfDockedLocked();
+ }
+ }
+ }
+
+ void onSystemReady() {
+ updateRegistration();
+ }
+
+ private void updateRegistration() {
+ boolean register = !isDeviceProvisioned();
+ if (register == mRegistered) {
+ return;
+ }
+ final ContentResolver resolver = getContext().getContentResolver();
+ if (register) {
+ resolver.registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+ false, this);
+ } else {
+ resolver.unregisterContentObserver(this);
+ }
+ mRegistered = register;
+ }
+
+ boolean isDeviceProvisioned() {
+ return Settings.Global.getInt(getContext().getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/DockObserverTest.java b/services/tests/servicestests/src/com/android/server/DockObserverTest.java
index c325778..ee09074 100644
--- a/services/tests/servicestests/src/com/android/server/DockObserverTest.java
+++ b/services/tests/servicestests/src/com/android/server/DockObserverTest.java
@@ -20,6 +20,7 @@
import android.content.Intent;
import android.os.Looper;
+import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableContext;
import android.testing.TestableLooper;
@@ -74,6 +75,11 @@
.isEqualTo(Intent.EXTRA_DOCK_STATE_UNDOCKED);
}
+ void setDeviceProvisioned(boolean provisioned) {
+ Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED,
+ provisioned ? 1 : 0);
+ }
+
@Before
public void setUp() {
if (Looper.myLooper() == null) {
@@ -131,4 +137,25 @@
assertDockEventIntentWithExtraThenUndock(observer, "DOCK=1\nKEY5=5",
Intent.EXTRA_DOCK_STATE_HE_DESK);
}
+
+ @Test
+ public void testDockIntentBroadcast_deviceNotProvisioned()
+ throws ExecutionException, InterruptedException {
+ DockObserver observer = new DockObserver(mInterceptingContext);
+ // Set the device as not provisioned.
+ setDeviceProvisioned(false);
+ observer.onBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
+
+ BroadcastInterceptingContext.FutureIntent futureIntent =
+ updateExtconDockState(observer, "DOCK=1");
+ TestableLooper.get(this).processAllMessages();
+ // Verify no broadcast was sent as device was not provisioned.
+ futureIntent.assertNotReceived();
+
+ // Ensure we send the broadcast when the device is provisioned.
+ setDeviceProvisioned(true);
+ TestableLooper.get(this).processAllMessages();
+ assertThat(futureIntent.get().getIntExtra(Intent.EXTRA_DOCK_STATE, -1))
+ .isEqualTo(Intent.EXTRA_DOCK_STATE_DESK);
+ }
}