Skip to content

Commit

Permalink
Upstream 3.0.8 source
Browse files Browse the repository at this point in the history
  • Loading branch information
tony-mak committed Jun 9, 2016
2 parents 5cd5cc4 + d9f1289 commit f1f3a5d
Show file tree
Hide file tree
Showing 56 changed files with 2,308 additions and 211 deletions.
43 changes: 6 additions & 37 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ ext {
// exactly 1 digit
versionMinor = 0
// exactly 2 digits
versionBuild = 3
versionBuild = 8
}

android {
compileSdkVersion 'android-N'
buildToolsVersion '23.0.2'
compileSdkVersion 24
buildToolsVersion '24.0.0'

defaultConfig {
applicationId "com.afwsamples.testdpc"
minSdkVersion 21
targetSdkVersion 23
targetSdkVersion 24
versionCode versionMajor * 1000 + versionMinor * 100 + versionBuild
versionName "${versionMajor}.${versionMinor}.${versionBuild}"
}
Expand Down Expand Up @@ -48,38 +48,6 @@ android {
}
}

productFlavors {
standard {
minSdkVersion 21
targetSdkVersion 23
}

N {
minSdkVersion 'N'
targetSdkVersion 'N'
}
}

/* TODO: Remove once release version of N SDK is released. */
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.processManifest.doLast {
// minSdkVersion and targetSdkVersion are overrided if we build against preview
// SDK, let us override them again here.
minSdkVersion = variant.getMergedFlavor().minSdkVersion.getApiString();
targetSdkVersion = variant.getMergedFlavor().targetSdkVersion.getApiString();

def manifestOutFile = output.processManifest.manifestOutputFile
def newFileContents = manifestOutFile.getText('UTF-8').
replace('android:minSdkVersion="N"',
'android:minSdkVersion="' + minSdkVersion + '"')
newFileContents = newFileContents.replace('android:targetSdkVersion="N"',
'android:targetSdkVersion="' + targetSdkVersion + '"')
manifestOutFile.write(newFileContents, 'UTF-8')
}
}
}

// Enable lint checking in all build variants.
applicationVariants.all { variant ->
variant.outputs.each { output ->
Expand All @@ -90,8 +58,9 @@ android {
}

dependencies {
compile 'com.android.support:appcompat-v7:24.+'
compile 'com.android.support:preference-v14:24+'
compile 'com.android.support:recyclerview-v7:24.+'
compile "com.android.support:support-v13:24.+"
compile 'com.google.android.gms:play-services-safetynet:+'
compile(name:'setup-wizard-lib-platform-release', ext:'aar')
}
16 changes: 16 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<application
android:allowBackup="true"
Expand All @@ -40,6 +41,10 @@
</intent-filter>
</activity>

<activity
android:name=".SetupManagementActivity"
android:label="@string/app_name"/>

<activity
android:name=".PolicyManagementActivity"
android:label="@string/app_name"
Expand Down Expand Up @@ -92,6 +97,17 @@
</intent-filter>
</receiver>

<receiver android:name=".FirstAccountReadyBroadcastReceiver"
android:exported="true"
android:enabled="false">
<intent-filter>
<action android:name="com.google.android.work.action.FIRST_ACCOUNT_READY"/>
</intent-filter>
<intent-filter>
<action android:name="com.afwsamples.testdpc.FIRST_ACCOUNT_READY_TIMEOUT"/>
</intent-filter>
</receiver>

<provider
android:authorities="com.afwsamples.testdpc.fileprovider"
android:name="android.support.v4.content.FileProvider"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ public void onClick(DialogInterface dialogInterface, int i) {
.show();
break;
case R.id.add_account_skip:
mNextActivityIntent.putExtra(EnableProfileActivity.EXTRA_ENABLE_PROFILE_NOW, true);
startActivity(mNextActivityIntent);
finish();
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,15 @@ public void onProfileProvisioningComplete(Context context, Intent intent) {
}
}

// Enable first account ready receiver for PO flow. On pre-N devices, the only supported
// PO flow is managed profile. On N+ devices we need to check whether we're running in a
// managed profile.
ComponentName adminComponent = DeviceAdminReceiver.getComponentName(context);
if (devicePolicyManager.isProfileOwnerApp(context.getPackageName())
&& (Util.isBeforeN() || Util.isManagedProfile(context, adminComponent))) {
FirstAccountReadyBroadcastReceiver.setEnabled(context, true);
}

// For synchronous auth cases, we can assume accounts are already setup (or will be shortly,
// as account migration for Profile Owner is asynchronous). For COSU we don't want to show
// the account option to the user, as no accounts should be added for now.
Expand Down
99 changes: 77 additions & 22 deletions app/src/main/java/com/afwsamples/testdpc/EnableProfileActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,73 @@
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.afwsamples.testdpc.common.LaunchIntentUtil;
import com.afwsamples.testdpc.provision.CheckInState;
import com.afwsamples.testdpc.provision.ProvisioningUtil;
import com.android.setupwizardlib.SetupWizardLayout;
import com.android.setupwizardlib.view.NavigationBar;

import static com.afwsamples.testdpc.provision.CheckInState.FIRST_ACCOUNT_READY_PROCESSED_ACTION;

/**
* This activity is started after managed profile provisioning is complete in
* {@link DeviceAdminReceiver}. It is responsible for enabling the managed profile and providing a
* shortcut to the policy management screen.
* {@link DeviceAdminReceiver}. There could be two cases:
* 1. If we are not going to add account now, we will then enable profile immediately.
* 2. If we have just added account, we need to wait for the FIRST_ACCOUNT_READY broadcast before
* enabling the profile. The broadcast indicates that the account has been synced with Google
* and is ready for use.
*/
public class EnableProfileActivity extends Activity implements NavigationBar.NavigationBarListener {
private CheckInStateReceiver mCheckInStateReceiver;
private Button mFinishButton;
private SetupWizardLayout mSetupWizardLayout;

private boolean mEnableProfileNow;

public static final String EXTRA_ENABLE_PROFILE_NOW = "enable_profile_now";
private static final IntentFilter sIntentFilter =
new IntentFilter(FIRST_ACCOUNT_READY_PROCESSED_ACTION);
private static final long WAIT_FOR_FIRST_ACCOUNT_READY_TIMEOUT = 60 * 1000;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Don't enable the profile again if this activity is being re-initialized.
if (null == savedInstanceState) {
// Important: After the profile has been created, the MDM must enable it for corporate
// apps to become visible in the launcher.
enableProfile();
mEnableProfileNow = getIntent().getBooleanExtra(EXTRA_ENABLE_PROFILE_NOW, false);
if (savedInstanceState == null) {
if (mEnableProfileNow) {
ProvisioningUtil.enableProfile(this);
} else {
// Set up an alarm to enable profile in case we do not receive first account ready
// broadcast for whatever reason.
FirstAccountReadyBroadcastReceiver.scheduleFirstAccountReadyTimeoutAlarm(
this, WAIT_FOR_FIRST_ACCOUNT_READY_TIMEOUT);
}
}

// This is just a user friendly shortcut to the policy management screen of this app.
setContentView(R.layout.enable_profile_activity);
SetupWizardLayout layout = (SetupWizardLayout) findViewById(R.id.setup_wizard_layout);
NavigationBar navigationBar = layout.getNavigationBar();
mSetupWizardLayout = (SetupWizardLayout) findViewById(R.id.setup_wizard_layout);
NavigationBar navigationBar = mSetupWizardLayout.getNavigationBar();
navigationBar.getBackButton().setEnabled(false);
navigationBar.setNavigationBarListener(this);
navigationBar.getNextButton().setText(R.string.finish_button);
mFinishButton = navigationBar.getNextButton();
mFinishButton.setText(R.string.finish_button);

mCheckInStateReceiver = new CheckInStateReceiver();

// This is just a user friendly shortcut to the policy management screen of this app.
ImageView appIcon = (ImageView) findViewById(R.id.app_icon);
TextView appLabel = (TextView) findViewById(R.id.app_label);
try {
Expand Down Expand Up @@ -86,6 +114,22 @@ protected void onCreate(Bundle savedInstanceState) {
}
}

@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mCheckInStateReceiver,
sIntentFilter);
// In case the broadcast is sent before we register the receiver.
CheckInState checkInState = new CheckInState(this);
refreshUi(mEnableProfileNow || checkInState.isFirstAccountReady() /* enableFinish */);
}

@Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mCheckInStateReceiver);
}

private boolean isAccountMigrated(String addedAccount) {
Account[] accounts = AccountManager.get(this).getAccounts();
for (Account account : accounts) {
Expand All @@ -96,14 +140,17 @@ private boolean isAccountMigrated(String addedAccount) {
return false;
}

private void enableProfile() {
DevicePolicyManager manager = (DevicePolicyManager) getSystemService(
Context.DEVICE_POLICY_SERVICE);
ComponentName componentName = DeviceAdminReceiver.getComponentName(this);
// This is the name for the newly created managed profile.
manager.setProfileName(componentName, getString(R.string.profile_name));
// We enable the profile here.
manager.setProfileEnabled(componentName);
private void refreshUi(boolean enableFinish) {
if (enableFinish) {
mSetupWizardLayout.hideProgressBar();
} else {
mSetupWizardLayout.showProgressBar();
}
mSetupWizardLayout.setHeaderText(
(enableFinish)
? R.string.finish_setup
: R.string.waiting_for_first_account_check_in);
mFinishButton.setEnabled(enableFinish);
}

@Override
Expand All @@ -115,4 +162,12 @@ public void onNavigateBack() {
public void onNavigateNext() {
finish();
}

class CheckInStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Processed the first check-in broadcast, allow user to tap the finish button.
refreshUi(true);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright (C) 2016 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.afwsamples.testdpc;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.SystemClock;
import android.util.Log;

import com.afwsamples.testdpc.provision.CheckInState;
import com.afwsamples.testdpc.provision.ProvisioningUtil;

import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.DONT_KILL_APP;

/**
* Receiver for FIRST_ACCOUNT_READY_ACTION from Google Play Service.
*/
public class FirstAccountReadyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "FirstAccountReady";

private static final String FIRST_ACCOUNT_READY_ACTION =
"com.google.android.work.action.FIRST_ACCOUNT_READY";

public static final String FIRST_ACCOUNT_READY_TIMEOUT_ACTION =
"com.afwsamples.testdpc.FIRST_ACCOUNT_READY_TIMEOUT";

public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
Log.d(TAG, "Received: " + action);
if (FIRST_ACCOUNT_READY_ACTION.equals(action) ||
FIRST_ACCOUNT_READY_TIMEOUT_ACTION.equals(action)) {
CheckInState checkInState = new CheckInState(context);
if (!checkInState.isFirstAccountReady()) {
checkInState.setFirstAccountReady();
ProvisioningUtil.enableProfile(context);
}
// This receiver is disabled in ProvisioningUtil.enableProfile, no more code should
// be put after it.
}
}

public static void setEnabled(Context context, boolean enabled) {
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(
new ComponentName(context, FirstAccountReadyBroadcastReceiver.class),
(enabled) ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DISABLED,
DONT_KILL_APP
);
}

/**
* Enable profile anyway if we cannot receive the broadcast after certain amount time.
*/
public static void scheduleFirstAccountReadyTimeoutAlarm(Context context, long timeout) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + timeout,
createFirstAccountReadyTimeoutPendingIntent(context));
}

public static void cancelFirstAccountReadyTimeoutAlarm(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(createFirstAccountReadyTimeoutPendingIntent(context));
}

private static PendingIntent createFirstAccountReadyTimeoutPendingIntent(Context context) {
Intent intent = new Intent(context, FirstAccountReadyBroadcastReceiver.class);
intent.setAction(FirstAccountReadyBroadcastReceiver.FIRST_ACCOUNT_READY_TIMEOUT_ACTION);
return PendingIntent.getBroadcast(
context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
Loading

0 comments on commit f1f3a5d

Please sign in to comment.