Skip to content

Commit f1f3a5d

Browse files
committed
Upstream 3.0.8 source
2 parents 5cd5cc4 + d9f1289 commit f1f3a5d

File tree

56 files changed

+2308
-211
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2308
-211
lines changed

app/build.gradle

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@ ext {
77
// exactly 1 digit
88
versionMinor = 0
99
// exactly 2 digits
10-
versionBuild = 3
10+
versionBuild = 8
1111
}
1212

1313
android {
14-
compileSdkVersion 'android-N'
15-
buildToolsVersion '23.0.2'
14+
compileSdkVersion 24
15+
buildToolsVersion '24.0.0'
1616

1717
defaultConfig {
1818
applicationId "com.afwsamples.testdpc"
1919
minSdkVersion 21
20-
targetSdkVersion 23
20+
targetSdkVersion 24
2121
versionCode versionMajor * 1000 + versionMinor * 100 + versionBuild
2222
versionName "${versionMajor}.${versionMinor}.${versionBuild}"
2323
}
@@ -48,38 +48,6 @@ android {
4848
}
4949
}
5050

51-
productFlavors {
52-
standard {
53-
minSdkVersion 21
54-
targetSdkVersion 23
55-
}
56-
57-
N {
58-
minSdkVersion 'N'
59-
targetSdkVersion 'N'
60-
}
61-
}
62-
63-
/* TODO: Remove once release version of N SDK is released. */
64-
applicationVariants.all { variant ->
65-
variant.outputs.each { output ->
66-
output.processManifest.doLast {
67-
// minSdkVersion and targetSdkVersion are overrided if we build against preview
68-
// SDK, let us override them again here.
69-
minSdkVersion = variant.getMergedFlavor().minSdkVersion.getApiString();
70-
targetSdkVersion = variant.getMergedFlavor().targetSdkVersion.getApiString();
71-
72-
def manifestOutFile = output.processManifest.manifestOutputFile
73-
def newFileContents = manifestOutFile.getText('UTF-8').
74-
replace('android:minSdkVersion="N"',
75-
'android:minSdkVersion="' + minSdkVersion + '"')
76-
newFileContents = newFileContents.replace('android:targetSdkVersion="N"',
77-
'android:targetSdkVersion="' + targetSdkVersion + '"')
78-
manifestOutFile.write(newFileContents, 'UTF-8')
79-
}
80-
}
81-
}
82-
8351
// Enable lint checking in all build variants.
8452
applicationVariants.all { variant ->
8553
variant.outputs.each { output ->
@@ -90,8 +58,9 @@ android {
9058
}
9159

9260
dependencies {
93-
compile 'com.android.support:appcompat-v7:24.+'
61+
compile 'com.android.support:preference-v14:24+'
9462
compile 'com.android.support:recyclerview-v7:24.+'
9563
compile "com.android.support:support-v13:24.+"
64+
compile 'com.google.android.gms:play-services-safetynet:+'
9665
compile(name:'setup-wizard-lib-platform-release', ext:'aar')
9766
}

app/src/main/AndroidManifest.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
2626
<uses-permission android:name="android.permission.INTERNET" />
2727
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
28+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
2829

2930
<application
3031
android:allowBackup="true"
@@ -40,6 +41,10 @@
4041
</intent-filter>
4142
</activity>
4243

44+
<activity
45+
android:name=".SetupManagementActivity"
46+
android:label="@string/app_name"/>
47+
4348
<activity
4449
android:name=".PolicyManagementActivity"
4550
android:label="@string/app_name"
@@ -92,6 +97,17 @@
9297
</intent-filter>
9398
</receiver>
9499

100+
<receiver android:name=".FirstAccountReadyBroadcastReceiver"
101+
android:exported="true"
102+
android:enabled="false">
103+
<intent-filter>
104+
<action android:name="com.google.android.work.action.FIRST_ACCOUNT_READY"/>
105+
</intent-filter>
106+
<intent-filter>
107+
<action android:name="com.afwsamples.testdpc.FIRST_ACCOUNT_READY_TIMEOUT"/>
108+
</intent-filter>
109+
</receiver>
110+
95111
<provider
96112
android:authorities="com.afwsamples.testdpc.fileprovider"
97113
android:name="android.support.v4.content.FileProvider"

app/src/main/java/com/afwsamples/testdpc/AddAccountActivity.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ public void onClick(DialogInterface dialogInterface, int i) {
126126
.show();
127127
break;
128128
case R.id.add_account_skip:
129+
mNextActivityIntent.putExtra(EnableProfileActivity.EXTRA_ENABLE_PROFILE_NOW, true);
129130
startActivity(mNextActivityIntent);
130131
finish();
131132
break;

app/src/main/java/com/afwsamples/testdpc/DeviceAdminReceiver.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ public void onProfileProvisioningComplete(Context context, Intent intent) {
133133
}
134134
}
135135

136+
// Enable first account ready receiver for PO flow. On pre-N devices, the only supported
137+
// PO flow is managed profile. On N+ devices we need to check whether we're running in a
138+
// managed profile.
139+
ComponentName adminComponent = DeviceAdminReceiver.getComponentName(context);
140+
if (devicePolicyManager.isProfileOwnerApp(context.getPackageName())
141+
&& (Util.isBeforeN() || Util.isManagedProfile(context, adminComponent))) {
142+
FirstAccountReadyBroadcastReceiver.setEnabled(context, true);
143+
}
144+
136145
// For synchronous auth cases, we can assume accounts are already setup (or will be shortly,
137146
// as account migration for Profile Owner is asynchronous). For COSU we don't want to show
138147
// the account option to the user, as no accounts should be added for now.

app/src/main/java/com/afwsamples/testdpc/EnableProfileActivity.java

Lines changed: 77 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,45 +19,73 @@
1919
import android.accounts.Account;
2020
import android.accounts.AccountManager;
2121
import android.app.Activity;
22-
import android.app.admin.DevicePolicyManager;
23-
import android.content.ComponentName;
22+
import android.content.BroadcastReceiver;
2423
import android.content.Context;
24+
import android.content.Intent;
25+
import android.content.IntentFilter;
2526
import android.content.pm.ApplicationInfo;
2627
import android.content.pm.PackageManager;
2728
import android.os.Bundle;
29+
import android.support.v4.content.LocalBroadcastManager;
2830
import android.util.Log;
2931
import android.view.View;
32+
import android.widget.Button;
3033
import android.widget.ImageView;
3134
import android.widget.TextView;
3235

3336
import com.afwsamples.testdpc.common.LaunchIntentUtil;
37+
import com.afwsamples.testdpc.provision.CheckInState;
38+
import com.afwsamples.testdpc.provision.ProvisioningUtil;
3439
import com.android.setupwizardlib.SetupWizardLayout;
3540
import com.android.setupwizardlib.view.NavigationBar;
3641

42+
import static com.afwsamples.testdpc.provision.CheckInState.FIRST_ACCOUNT_READY_PROCESSED_ACTION;
43+
3744
/**
3845
* This activity is started after managed profile provisioning is complete in
39-
* {@link DeviceAdminReceiver}. It is responsible for enabling the managed profile and providing a
40-
* shortcut to the policy management screen.
46+
* {@link DeviceAdminReceiver}. There could be two cases:
47+
* 1. If we are not going to add account now, we will then enable profile immediately.
48+
* 2. If we have just added account, we need to wait for the FIRST_ACCOUNT_READY broadcast before
49+
* enabling the profile. The broadcast indicates that the account has been synced with Google
50+
* and is ready for use.
4151
*/
4252
public class EnableProfileActivity extends Activity implements NavigationBar.NavigationBarListener {
53+
private CheckInStateReceiver mCheckInStateReceiver;
54+
private Button mFinishButton;
55+
private SetupWizardLayout mSetupWizardLayout;
56+
57+
private boolean mEnableProfileNow;
58+
59+
public static final String EXTRA_ENABLE_PROFILE_NOW = "enable_profile_now";
60+
private static final IntentFilter sIntentFilter =
61+
new IntentFilter(FIRST_ACCOUNT_READY_PROCESSED_ACTION);
62+
private static final long WAIT_FOR_FIRST_ACCOUNT_READY_TIMEOUT = 60 * 1000;
4363

4464
@Override
4565
protected void onCreate(Bundle savedInstanceState) {
4666
super.onCreate(savedInstanceState);
47-
// Don't enable the profile again if this activity is being re-initialized.
48-
if (null == savedInstanceState) {
49-
// Important: After the profile has been created, the MDM must enable it for corporate
50-
// apps to become visible in the launcher.
51-
enableProfile();
67+
mEnableProfileNow = getIntent().getBooleanExtra(EXTRA_ENABLE_PROFILE_NOW, false);
68+
if (savedInstanceState == null) {
69+
if (mEnableProfileNow) {
70+
ProvisioningUtil.enableProfile(this);
71+
} else {
72+
// Set up an alarm to enable profile in case we do not receive first account ready
73+
// broadcast for whatever reason.
74+
FirstAccountReadyBroadcastReceiver.scheduleFirstAccountReadyTimeoutAlarm(
75+
this, WAIT_FOR_FIRST_ACCOUNT_READY_TIMEOUT);
76+
}
5277
}
53-
54-
// This is just a user friendly shortcut to the policy management screen of this app.
5578
setContentView(R.layout.enable_profile_activity);
56-
SetupWizardLayout layout = (SetupWizardLayout) findViewById(R.id.setup_wizard_layout);
57-
NavigationBar navigationBar = layout.getNavigationBar();
79+
mSetupWizardLayout = (SetupWizardLayout) findViewById(R.id.setup_wizard_layout);
80+
NavigationBar navigationBar = mSetupWizardLayout.getNavigationBar();
81+
navigationBar.getBackButton().setEnabled(false);
5882
navigationBar.setNavigationBarListener(this);
59-
navigationBar.getNextButton().setText(R.string.finish_button);
83+
mFinishButton = navigationBar.getNextButton();
84+
mFinishButton.setText(R.string.finish_button);
85+
86+
mCheckInStateReceiver = new CheckInStateReceiver();
6087

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

117+
@Override
118+
protected void onResume() {
119+
super.onResume();
120+
LocalBroadcastManager.getInstance(this).registerReceiver(mCheckInStateReceiver,
121+
sIntentFilter);
122+
// In case the broadcast is sent before we register the receiver.
123+
CheckInState checkInState = new CheckInState(this);
124+
refreshUi(mEnableProfileNow || checkInState.isFirstAccountReady() /* enableFinish */);
125+
}
126+
127+
@Override
128+
protected void onStop() {
129+
super.onStop();
130+
LocalBroadcastManager.getInstance(this).unregisterReceiver(mCheckInStateReceiver);
131+
}
132+
89133
private boolean isAccountMigrated(String addedAccount) {
90134
Account[] accounts = AccountManager.get(this).getAccounts();
91135
for (Account account : accounts) {
@@ -96,14 +140,17 @@ private boolean isAccountMigrated(String addedAccount) {
96140
return false;
97141
}
98142

99-
private void enableProfile() {
100-
DevicePolicyManager manager = (DevicePolicyManager) getSystemService(
101-
Context.DEVICE_POLICY_SERVICE);
102-
ComponentName componentName = DeviceAdminReceiver.getComponentName(this);
103-
// This is the name for the newly created managed profile.
104-
manager.setProfileName(componentName, getString(R.string.profile_name));
105-
// We enable the profile here.
106-
manager.setProfileEnabled(componentName);
143+
private void refreshUi(boolean enableFinish) {
144+
if (enableFinish) {
145+
mSetupWizardLayout.hideProgressBar();
146+
} else {
147+
mSetupWizardLayout.showProgressBar();
148+
}
149+
mSetupWizardLayout.setHeaderText(
150+
(enableFinish)
151+
? R.string.finish_setup
152+
: R.string.waiting_for_first_account_check_in);
153+
mFinishButton.setEnabled(enableFinish);
107154
}
108155

109156
@Override
@@ -115,4 +162,12 @@ public void onNavigateBack() {
115162
public void onNavigateNext() {
116163
finish();
117164
}
165+
166+
class CheckInStateReceiver extends BroadcastReceiver {
167+
@Override
168+
public void onReceive(Context context, Intent intent) {
169+
// Processed the first check-in broadcast, allow user to tap the finish button.
170+
refreshUi(true);
171+
}
172+
}
118173
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright (C) 2016 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.afwsamples.testdpc;
18+
19+
import android.app.AlarmManager;
20+
import android.app.PendingIntent;
21+
import android.content.BroadcastReceiver;
22+
import android.content.ComponentName;
23+
import android.content.Context;
24+
import android.content.Intent;
25+
import android.content.pm.PackageManager;
26+
import android.os.SystemClock;
27+
import android.util.Log;
28+
29+
import com.afwsamples.testdpc.provision.CheckInState;
30+
import com.afwsamples.testdpc.provision.ProvisioningUtil;
31+
32+
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
33+
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
34+
import static android.content.pm.PackageManager.DONT_KILL_APP;
35+
36+
/**
37+
* Receiver for FIRST_ACCOUNT_READY_ACTION from Google Play Service.
38+
*/
39+
public class FirstAccountReadyBroadcastReceiver extends BroadcastReceiver {
40+
private static final String TAG = "FirstAccountReady";
41+
42+
private static final String FIRST_ACCOUNT_READY_ACTION =
43+
"com.google.android.work.action.FIRST_ACCOUNT_READY";
44+
45+
public static final String FIRST_ACCOUNT_READY_TIMEOUT_ACTION =
46+
"com.afwsamples.testdpc.FIRST_ACCOUNT_READY_TIMEOUT";
47+
48+
public void onReceive(Context context, Intent intent) {
49+
final String action = intent.getAction();
50+
Log.d(TAG, "Received: " + action);
51+
if (FIRST_ACCOUNT_READY_ACTION.equals(action) ||
52+
FIRST_ACCOUNT_READY_TIMEOUT_ACTION.equals(action)) {
53+
CheckInState checkInState = new CheckInState(context);
54+
if (!checkInState.isFirstAccountReady()) {
55+
checkInState.setFirstAccountReady();
56+
ProvisioningUtil.enableProfile(context);
57+
}
58+
// This receiver is disabled in ProvisioningUtil.enableProfile, no more code should
59+
// be put after it.
60+
}
61+
}
62+
63+
public static void setEnabled(Context context, boolean enabled) {
64+
PackageManager pm = context.getPackageManager();
65+
pm.setComponentEnabledSetting(
66+
new ComponentName(context, FirstAccountReadyBroadcastReceiver.class),
67+
(enabled) ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DISABLED,
68+
DONT_KILL_APP
69+
);
70+
}
71+
72+
/**
73+
* Enable profile anyway if we cannot receive the broadcast after certain amount time.
74+
*/
75+
public static void scheduleFirstAccountReadyTimeoutAlarm(Context context, long timeout) {
76+
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
77+
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
78+
SystemClock.elapsedRealtime() + timeout,
79+
createFirstAccountReadyTimeoutPendingIntent(context));
80+
}
81+
82+
public static void cancelFirstAccountReadyTimeoutAlarm(Context context) {
83+
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
84+
alarmManager.cancel(createFirstAccountReadyTimeoutPendingIntent(context));
85+
}
86+
87+
private static PendingIntent createFirstAccountReadyTimeoutPendingIntent(Context context) {
88+
Intent intent = new Intent(context, FirstAccountReadyBroadcastReceiver.class);
89+
intent.setAction(FirstAccountReadyBroadcastReceiver.FIRST_ACCOUNT_READY_TIMEOUT_ACTION);
90+
return PendingIntent.getBroadcast(
91+
context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
92+
}
93+
}

0 commit comments

Comments
 (0)