Commit ab18ea7a authored by Sander Alewijnse's avatar Sander Alewijnse
Browse files

Intercept HOME intent that is send by the Setup Wizard.

Only after interception send the complete intent to the mdm.

Bug:17370665
Change-Id: I82ab41c7b6fafed6ad756fe8d190ad3f0bde2144
parent eed2f48f
......@@ -129,5 +129,17 @@
</intent-filter>
</receiver>
<activity android:name="com.android.managedprovisioning.HomeReceiverActivity"
android:theme="@android:style/Theme.NoDisplay"
android:noHistory="true"
android:excludeFromRecents="true"
android:enabled="false">
<intent-filter android:priority="2">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
......@@ -16,9 +16,6 @@
package com.android.managedprovisioning;
import static android.app.admin.DeviceAdminReceiver.ACTION_PROFILE_PROVISIONING_COMPLETE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
......@@ -80,8 +77,6 @@ public class DeviceOwnerProvisioningActivity extends Activity {
// Run when wifi picker activity reports success.
private Runnable mOnWifiConnectedRunnable;
private Intent mProvisioningCompleteIntent;
// Indicates whether user consented by clicking on positive button of interstitial.
private boolean mUserConsented = false;
......@@ -209,8 +204,6 @@ public class DeviceOwnerProvisioningActivity extends Activity {
if (action.equals(DeviceOwnerProvisioningService.ACTION_PROVISIONING_SUCCESS)) {
ProvisionLogger.logd("Successfully provisioned");
mProvisioningCompleteIntent = getProvisioningCompleteIntent(intent);
synchronized(this) {
if (mDialog == null) {
onProvisioningSuccess();
......@@ -241,31 +234,14 @@ public class DeviceOwnerProvisioningActivity extends Activity {
}
}
private Intent getProvisioningCompleteIntent(Intent serviceIntent) {
ProvisioningParams paramsFromService = (ProvisioningParams) serviceIntent.getExtra(
DeviceOwnerProvisioningService.EXTRA_PROVISIONING_PARAMS);
Intent result = new Intent(ACTION_PROFILE_PROVISIONING_COMPLETE);
result.setPackage(paramsFromService.mDeviceAdminPackageName);
result.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES |
Intent.FLAG_RECEIVER_FOREGROUND);
if (paramsFromService.mAdminExtrasBundle != null) {
result.putExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE,
paramsFromService.mAdminExtrasBundle);
}
return result;
}
private void onProvisioningSuccess() {
stopService(new Intent(DeviceOwnerProvisioningActivity.this,
DeviceOwnerProvisioningService.class));
// Skip the setup wizard.
// The Setup wizards listens to this flag and finishes itself when it is set.
// It then fires a home intent, which we catch in the HomeReceiverActivity before sending
// the intent to notify the mdm that provisioning is complete.
Global.putInt(getContentResolver(), Global.DEVICE_PROVISIONED, 1);
Secure.putInt(getContentResolver(), Secure.USER_SETUP_COMPLETE, 1);
sendBroadcast(mProvisioningCompleteIntent);
// Note: the DeviceOwnerProvisioningService will stop itself.
setResult(Activity.RESULT_OK);
finish();
}
......
......@@ -16,11 +16,17 @@
package com.android.managedprovisioning;
import static android.app.admin.DeviceAdminReceiver.ACTION_PROFILE_PROVISIONING_COMPLETE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
import android.app.AlarmManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.UserHandle;
......@@ -74,6 +80,11 @@ public class DeviceOwnerProvisioningService extends Service {
protected static final String ACTION_REQUEST_WIFI_PICK =
"com.android.managedprovisioning.request_wifi_pick";
// Intent action used by the HomeReceiverActivity to notify this Service that a HOME intent was
// received, which indicates that the Setup wizard has closed after provisioning completed.
protected static final String ACTION_HOME_INDIRECT =
"com.android.managedprovisioning.home_indirect";
// Indicates whether provisioning has started.
private boolean mProvisioningInFlight = false;
......@@ -95,6 +106,8 @@ public class DeviceOwnerProvisioningService extends Service {
private ProvisioningParams mParams;
private BroadcastReceiver mIndirectHomeReceiver;
@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
ProvisionLogger.logd("Device owner provisioning service ONSTARTCOMMAND.");
......@@ -122,6 +135,8 @@ public class DeviceOwnerProvisioningService extends Service {
// Load the ProvisioningParams (from message in Intent).
mParams = (ProvisioningParams) intent.getParcelableExtra(EXTRA_PROVISIONING_PARAMS);
registerHomeIntentReceiver();
// Do the work on a separate thread.
new Thread(new Runnable() {
public void run() {
......@@ -134,6 +149,45 @@ public class DeviceOwnerProvisioningService extends Service {
return START_NOT_STICKY;
}
// Register the receiver for the ACTION_HOME_INDIRECT intent.
// The ACTION_HOME_INDIRECT intent is used to notify this service that the home intent was send.
// After receiving that intent we send the complete intent to the mdm.
// Note: if we would send the complete intent earlier, the home intent can close the mdm.
private void registerHomeIntentReceiver() {
mIndirectHomeReceiver = new IndirectHomeReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(DeviceOwnerProvisioningService.ACTION_HOME_INDIRECT);
LocalBroadcastManager.getInstance(this).registerReceiver(mIndirectHomeReceiver, filter);
}
class IndirectHomeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (!mDone) {
return;
}
// Disable the HomeReceiverActivity. It's no longer of use.
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(new ComponentName(DeviceOwnerProvisioningService.this,
HomeReceiverActivity.class), PackageManager
.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
// Send complete intent to mdm.
Intent result = new Intent(ACTION_PROFILE_PROVISIONING_COMPLETE);
result.setPackage(mParams.mDeviceAdminPackageName);
result.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES |
Intent.FLAG_RECEIVER_FOREGROUND);
if (mParams.mAdminExtrasBundle != null) {
result.putExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE,
mParams.mAdminExtrasBundle);
}
sendBroadcast(result);
stopSelf();
}
}
/**
* This is the core method of this class. It goes through every provisioning step.
*/
......@@ -314,8 +368,16 @@ public class DeviceOwnerProvisioningService extends Service {
private void onProvisioningSuccess(String deviceAdminPackage) {
ProvisionLogger.logv("Reporting success.");
mDone = true;
// Enable the HomeReceiverActivity, since the DeviceOwnerProvisioningActivity will shutdown
// the Setup wizard soon, which will result in a home intent that should be caught by the
// HomeReceiverActivity.
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(new ComponentName(DeviceOwnerProvisioningService.this,
HomeReceiverActivity.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
Intent successIntent = new Intent(ACTION_PROVISIONING_SUCCESS);
successIntent.putExtra(EXTRA_PROVISIONING_PARAMS, mParams);
successIntent.setClass(this, DeviceOwnerProvisioningActivity.ServiceMessageReceiver.class);
LocalBroadcastManager.getInstance(this).sendBroadcast(successIntent);
// Wait for stopService() call from the activity.
......@@ -378,6 +440,11 @@ public class DeviceOwnerProvisioningService extends Service {
if (mDownloadPackageTask != null) {
mDownloadPackageTask.cleanUp();
}
if (mIndirectHomeReceiver != null) {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mIndirectHomeReceiver);
mIndirectHomeReceiver = null;
}
}
@Override
......
/*
* Copyright 2014, 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.managedprovisioning;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
/*
* This class is used to make sure that we start the mdm after we shut the Setup wizard down.
* The shut down of the Setup wizard is initiated in the DeviceOwnerProvisioningActivity by setting
* Global.DEVICE_PROVISIONED. This will cause the Setup wizard to shut down and send a HOME intent.
* Instead of opening the home screen we want to open the mdm, so the HOME intent is caught by this
* activity instead, which notifies the DeviceOwnerProvisioningService to send the
* ACTION_PROFILE_PROVISIONING_COMPLETE to the mdm, which will then open up.
*/
public class HomeReceiverActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent indirectIntent = new Intent(DeviceOwnerProvisioningService.ACTION_HOME_INDIRECT);
LocalBroadcastManager.getInstance(this).sendBroadcast(indirectIntent);
finish();
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment