Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c5951bf authored by Katie McCormick's avatar Katie McCormick
Browse files

Doc change: Updating device-admin with camera info.

Change-Id: I5a5bf50b1362346f0a245ee40248a62a3c94a879
parent 95142919
Loading
Loading
Loading
Loading
+118 −129
Original line number Original line Diff line number Diff line
@@ -27,6 +27,12 @@ page.title=Device Administration
      <li>{@link android.app.admin.DevicePolicyManager}</li>
      <li>{@link android.app.admin.DevicePolicyManager}</li>
      <li>{@link android.app.admin.DeviceAdminInfo}</li>
      <li>{@link android.app.admin.DeviceAdminInfo}</li>
    </ol>
    </ol>
    <h2>Related samples</h2>
    <ol>
      <li><a
href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.html">
DeviceAdminSample</a></li>
</ol>
</div>
</div>
</div>
</div>


@@ -201,6 +207,16 @@ access data. The value can be between 1 and 60 minutes.</td> </tr>
<td>Specifies that the storage area should be encrypted, if the device supports it. 
<td>Specifies that the storage area should be encrypted, if the device supports it. 
Introduced in Android 3.0.</td> </tr>
Introduced in Android 3.0.</td> </tr>


<tr>
  <td>Disable camera</td>
  
  <td>Specifies that the camera should be disabled. Note that this doesn't have
to be a permanent disabling. The camera can be enabled/disabled dynamically
based on context, time, and so on. Introduced in Android 4.0.</td>
  
</tr>


</table>
</table>


<h4>Other features</h4>
<h4>Other features</h4>
@@ -247,6 +263,7 @@ one of the last <em>n</em> passwords they previously used.</li>
locks.</li>
locks.</li>
  <li>Make the device lock immediately.</li>
  <li>Make the device lock immediately.</li>
  <li>Wipe the device's data (that is, restore factory settings).</li>
  <li>Wipe the device's data (that is, restore factory settings).</li>
  <li>Disable the camera.</li>
  
  
</ul>
</ul>


@@ -280,46 +297,38 @@ intent, expressed in the manifest as an intent filter.</li>
  <li>A declaration of security policies used in metadata.</li>
  <li>A declaration of security policies used in metadata.</li>
</ul>
</ul>
<p>Here is an excerpt from the Device Administration sample manifest:</p>
<p>Here is an excerpt from the Device Administration sample manifest:</p>
<pre>&lt;activity android:name=&quot;.app.DeviceAdminSample$Controller&quot;
<pre>&lt;activity android:name=&quot;.app.DeviceAdminSample&quot;
          android:label=&quot;&#64;string/activity_sample_device_admin&quot;&gt;
            android:label=&quot;&#64;string/activity_sample_device_admin&quot;&gt;
    &lt;intent-filter&gt;
    &lt;intent-filter&gt;
        &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
        &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
        &lt;category android:name=&quot;android.intent.category.SAMPLE_CODE&quot; /&gt;
        &lt;category android:name=&quot;android.intent.category.SAMPLE_CODE&quot; /&gt;
    &lt;/intent-filter&gt;
    &lt;/intent-filter&gt;
&lt;/activity&gt;
&lt;/activity&gt;

&lt;receiver android:name=&quot;.app.DeviceAdminSample$DeviceAdminSampleReceiver&quot;
&lt;receiver android:name=&quot;.app.DeviceAdminSample&quot;
        android:label=&quot;&#64;string/sample_device_admin&quot;
          android:label=&quot;&#64;string/sample_device_admin&quot;
        android:description=&quot;&#64;string/sample_device_admin_description&quot;
          android:description=&quot;&#64;string/sample_device_admin_description&quot;
        android:permission=&quot;android.permission.BIND_DEVICE_ADMIN&quot;&gt;
          android:permission=&quot;android.permission.BIND_DEVICE_ADMIN&quot;&gt;
    &lt;meta-data android:name=&quot;android.app.device_admin&quot;
    &lt;meta-data android:name=&quot;android.app.device_admin&quot;
            android:resource=&quot;&#64;xml/device_admin_sample&quot; /&gt;
               android:resource=&quot;&#64;xml/device_admin_sample&quot; /&gt;
    &lt;intent-filter&gt;
    &lt;intent-filter&gt;
        &lt;action android:name=&quot;android.app.action.DEVICE_ADMIN_ENABLED&quot; /&gt;
        &lt;action android:name=&quot;android.app.action.DEVICE_ADMIN_ENABLED&quot; /&gt;
    &lt;/intent-filter&gt;
    &lt;/intent-filter&gt;
&lt;/receiver&gt;</pre>
&lt;/receiver&gt;</pre>


 <p>Note that:</p>
 <p>Note that:</p>
<ul>
<ul>
  <li>The activity in the sample application is an {@link android.app.Activity}
subclass called <code>Controller</code>. The syntax
<code>&quot;.app.DeviceAdminSample$Controller&quot;</code>  indicates that
<code>Controller</code> is an inner class that is nested inside the
<code>DeviceAdminSample</code> class. Note that an Activity does not need to be
an inner class; it just is in this example.</li>

<li>The following attributes refer to string resources that for the sample application reside in
<li>The following attributes refer to string resources that for the sample application reside in
<code>ApiDemos/res/values/strings.xml</code>. For more information about resources, see
<code>ApiDemos/res/values/strings.xml</code>. For more information about resources, see
<a
<a
href="{@docRoot}guide/topics/resources/index.html">Application Resources</a>.
href="{@docRoot}guide/topics/resources/index.html">Application Resources</a>.
<ul>
<ul>
<li><code>android:label=&quot;@string/activity_sample_device_admin&quot;</code> refers to the
<li><code>android:label=&quot;&#64;string/activity_sample_device_admin&quot;</code> refers to the
user-readable label for the activity.</li>
user-readable label for the activity.</li>


<li><code>android:label=&quot;@string/sample_device_admin&quot;</code> refers to the
<li><code>android:label=&quot;&#64;string/sample_device_admin&quot;</code> refers to the
user-readable label for the permission.</li>
user-readable label for the permission.</li>


<li><code>android:description=&quot;@string/sample_device_admin_description&quot;</code> refers to
<li><code>android:description=&quot;&#64;string/sample_device_admin_description&quot;</code> refers to
the user-readable description of the permission. A descripton is typically longer and more
the user-readable description of the permission. A descripton is typically longer and more
informative than
informative than
a label.</li>
a label.</li>
@@ -357,6 +366,9 @@ android.app.admin.DeviceAdminInfo} class. Here are the contents of
    &lt;reset-password /&gt;
    &lt;reset-password /&gt;
    &lt;force-lock /&gt;
    &lt;force-lock /&gt;
    &lt;wipe-data /&gt;
    &lt;wipe-data /&gt;
    &lt;expire-password /&gt;
    &lt;encrypted-storage /&gt;
    &lt;disable-camera /&gt;
  &lt;/uses-policies&gt;
  &lt;/uses-policies&gt;
&lt;/device-admin&gt;
&lt;/device-admin&gt;
</pre>
</pre>
@@ -401,33 +413,34 @@ simply displays a {@link android.widget.Toast} notification in response to parti
events. For example:</p>
events. For example:</p>
<pre>public class DeviceAdminSample extends DeviceAdminReceiver {
<pre>public class DeviceAdminSample extends DeviceAdminReceiver {


...
    void showToast(Context context, String msg) {
        String status = context.getString(R.string.admin_receiver_status, msg);
        Toast.makeText(context, status, Toast.LENGTH_SHORT).show();
    }

    &#64;Override
    &#64;Override
    public void onEnabled(Context context, Intent intent) {
    public void onEnabled(Context context, Intent intent) {
        showToast(context, &quot;Sample Device Admin: enabled&quot;);
        showToast(context, context.getString(R.string.admin_receiver_status_enabled));
    }
    }


    &#64;Override
    &#64;Override
    public CharSequence onDisableRequested(Context context, Intent intent) {
    public CharSequence onDisableRequested(Context context, Intent intent) {
        return &quot;This is an optional message to warn the user about disabling.&quot;;
        return context.getString(R.string.admin_receiver_status_disable_warning);
    }
    }


    &#64;Override
    &#64;Override
    public void onDisabled(Context context, Intent intent) {
    public void onDisabled(Context context, Intent intent) {
        showToast(context, &quot;Sample Device Admin: disabled&quot;);
        showToast(context, context.getString(R.string.admin_receiver_status_disabled));
    }
    }


    &#64;Override
    &#64;Override
    public void onPasswordChanged(Context context, Intent intent) {
    public void onPasswordChanged(Context context, Intent intent) {
        showToast(context, &quot;Sample Device Admin: pw changed&quot;);
        showToast(context, context.getString(R.string.admin_receiver_status_pw_changed));
    }

    void showToast(Context context, CharSequence msg) {
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
    }
    }
...
...
}</pre>
}</pre>



<h4 id="enabling">Enabling the application</h4>
<h4 id="enabling">Enabling the application</h4>
<p>One of the major events a device admin application has to handle is the user
<p>One of the major events a device admin application has to handle is the user
enabling the application. The user must explicitly enable the application for
enabling the application. The user must explicitly enable the application for
@@ -438,44 +451,51 @@ get any of the application's benefits.</p>
action that triggers the {@link android.app.admin.DevicePolicyManager#ACTION_ADD_DEVICE_ADMIN}
action that triggers the {@link android.app.admin.DevicePolicyManager#ACTION_ADD_DEVICE_ADMIN}
intent. In the
intent. In the
sample application, this happens when the user clicks the <strong>Enable
sample application, this happens when the user clicks the <strong>Enable
Admin</strong> button. </p>
Admin</strong> checkbox. </p>
<p>When the user clicks the <strong>Enable Admin</strong> button, the display
<p>When the user clicks the <strong>Enable Admin</strong> checkbox, the display
changes to prompt the user to enable the device admin application, as shown in figure
changes to prompt the user to activate the device admin application, as shown in figure
2.</p>
2.</p>


<img src="{@docRoot}images/admin/device-admin-activate-prompt.png"/>
<img src="{@docRoot}images/admin/device-admin-activate-prompt.png"/>
<p class="img-caption"><strong>Figure 2.</strong> Sample Application: Activating the Application</p>
<p class="img-caption"><strong>Figure 2.</strong> Sample Application: Activating the Application</p>
<p>Below  is the code that gets executed when the user clicks the <strong>Enable
Admin</strong> button shown in figure 1. </p>


<pre> private OnClickListener mEnableListener = new OnClickListener() {
<p>Below  is the code that gets executed when the user clicks the <strong>Enable Admin</strong> checkbox. This has the effect of triggering the 
    public void onClick(View v) {
{@link android.preference.Preference.OnPreferenceChangeListener#onPreferenceChange(android.preference.Preference, java.lang.Object) onPreferenceChange()} 
callback. This callback is invoked when the value of this  {@link android.preference.Preference} has been changed by the user and is about to be set and/or persisted. If the user is enabling the application, the display
changes to prompt the user to activate the device admin application, as shown in figure
2. Otherwise, the device admin application is disabled. </p>

<pre>&#64;Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (super.onPreferenceChange(preference, newValue)) {
                return true;
            }
            boolean value = (Boolean) newValue;
            if (preference == mEnableCheckbox) {
                if (value != mAdminActive) {
                    if (value) {
                        // Launch the activity to have the user enable our admin.
                        // Launch the activity to have the user enable our admin.
        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
                        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
                        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mDeviceAdminSample);
               mDeviceAdminSample);
                        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                                mActivity.getString(R.string.add_admin_extra_app_text));
               &quot;Additional text explaining why this needs to be added.&quot;);
                        startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
        startActivityForResult(intent, RESULT_ENABLE);
                        // return false - don't update checkbox until we're really active
                        return false;
                    } else {
                        mDPM.removeActiveAdmin(mDeviceAdminSample);
                        enableDeviceCapabilitiesArea(false);
                        mAdminActive = false;
                    }
                    }
};
                }

            } else if (preference == mDisableCameraCheckbox) {
                mDPM.setCameraDisabled(mDeviceAdminSample, value);
                ...
                ...
// This code checks whether the device admin app was successfully enabled.
            }
&#64;Override
            return true;
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case RESULT_ENABLE:
            if (resultCode == Activity.RESULT_OK) {
                Log.i(&quot;DeviceAdminSample&quot;, &quot;Administration enabled!&quot;);
            } else {
                Log.i(&quot;DeviceAdminSample&quot;, &quot;Administration enable FAILED!&quot;);
            }
            return;
    }
    super.onActivityResult(requestCode, resultCode, data);
        }</pre>
        }</pre>



<p>The line
<p>The line
<code>intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
<code>intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
mDeviceAdminSample)</code> states that <code>mDeviceAdminSample</code> (which is
mDeviceAdminSample)</code> states that <code>mDeviceAdminSample</code> (which is
@@ -489,18 +509,17 @@ active. To do this it uses the {@link android.app.admin.DevicePolicyManager} met
{@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()}. Notice that the {@link android.app.admin.DevicePolicyManager}
{@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()}. Notice that the {@link android.app.admin.DevicePolicyManager}
method {@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()} takes a {@link android.app.admin.DeviceAdminReceiver}
method {@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()} takes a {@link android.app.admin.DeviceAdminReceiver}
component as its argument:</p>
component as its argument:</p>

<pre>
<pre>
DevicePolicyManager mDPM;
DevicePolicyManager mDPM;
...
...
boolean active = mDPM.isAdminActive(mDeviceAdminSample);
private boolean isActiveAdmin() {
if (active) {
    return mDPM.isAdminActive(mDeviceAdminSample);
    // Admin app is active, so do some admin stuff
               ...
} else {
    // do something else
}
}
</pre>
</pre>




<h3 id="admin_ops">Managing policies</h3>
<h3 id="admin_ops">Managing policies</h3>
<p>{@link android.app.admin.DevicePolicyManager} is a public class for managing policies
<p>{@link android.app.admin.DevicePolicyManager} is a public class for managing policies
enforced on a device. {@link android.app.admin.DevicePolicyManager} manages policies for one
enforced on a device. {@link android.app.admin.DevicePolicyManager} manages policies for one
@@ -619,49 +638,6 @@ long pwExpiration;
mDPM.setPasswordExpirationTimeout(mDeviceAdminSample, pwExpiration);
mDPM.setPasswordExpirationTimeout(mDeviceAdminSample, pwExpiration);
</pre>
</pre>
    
    
<p>From the <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.html"
>Device Administration API sample</a>, here is the code
that updates the password expiration status:</p>

<pre>
DevicePolicyManager mDPM;
ComponentName mDeviceAdminSample;
private TextView mPasswordExpirationStatus;
...
void updatePasswordExpirationStatus() {
    boolean active = mDPM.isAdminActive(mDeviceAdminSample);
    String statusText;
    if (active) {
        long now = System.currentTimeMillis();
        // Query the DevicePolicyManager twice - first for the expiration values
        // set by the sample app, and later, for the system values (which may be different
        // if there is another administrator active.)
        long expirationDate = mDPM.getPasswordExpiration(mDeviceAdminSample);
        long mSecUntilExpiration = expirationDate - now;
        if (mSecUntilExpiration &gt;= 0) {
            statusText = &quot;Expiration in &quot; + countdownString(mSecUntilExpiration);
        } else {
            statusText = &quot;Expired &quot; + countdownString(-mSecUntilExpiration) + &quot; ago&quot;;
        }

        // expirationTimeout is the cycle time between required password refresh
        long expirationTimeout = mDPM.getPasswordExpirationTimeout(mDeviceAdminSample);
        statusText += &quot; / timeout period &quot; + countdownString(expirationTimeout);

        // Now report the aggregate (global) expiration time
        statusText += &quot; / Aggregate &quot;;
        expirationDate = mDPM.getPasswordExpiration(null);
        mSecUntilExpiration = expirationDate - now;
        if (mSecUntilExpiration &gt;= 0) {
            statusText += &quot;expiration in &quot; + countdownString(mSecUntilExpiration);
        } else {
            statusText += &quot;expired &quot; + countdownString(-mSecUntilExpiration) + &quot; ago&quot;;
        }
    } else {
        statusText = &quot;&lt;inactive&gt;&quot;;
    }
    mPasswordExpirationStatus.setText(statusText);</pre>
    
<h5 id="history">Restrict password based on history</h5>
<h5 id="history">Restrict password based on history</h5>


<p>Beginning with Android 3.0, you can use the 
<p>Beginning with Android 3.0, you can use the 
@@ -718,6 +694,19 @@ mDPM.wipeData(0);</pre>
<p>The {@link android.app.admin.DevicePolicyManager#wipeData wipeData()} method takes as its parameter a bit mask of
<p>The {@link android.app.admin.DevicePolicyManager#wipeData wipeData()} method takes as its parameter a bit mask of
additional options. Currently the value must be 0. </p>
additional options. Currently the value must be 0. </p>


<h4>Disable camera</h4>
<p>Beginning with Android 4.0, you can disable the camera. Note that this doesn't have to be a permanent disabling. The camera can be enabled/disabled dynamically based on context, time, and so on. </p>
<p>You control whether the camera is disabled by using the 
{@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName, boolean) setCameraDisabled()} method. For example, this snippet sets the camera to be enabled or disabled based on a checkbox setting:</p>

<pre>private CheckBoxPreference mDisableCameraCheckbox;
DevicePolicyManager mDPM;
ComponentName mDeviceAdminSample;
...
mDPM.setCameraDisabled(mDeviceAdminSample, mDisableCameraCheckbox.isChecked());<br />
</pre>


<h4 id=storage">Storage encryption</h4>
<h4 id=storage">Storage encryption</h4>
<p>Beginning with Android 3.0, you can use the 
<p>Beginning with Android 3.0, you can use the 
{@link android.app.admin.DevicePolicyManager#setStorageEncryption(android.content.ComponentName,boolean) setStorageEncryption()} 
{@link android.app.admin.DevicePolicyManager#setStorageEncryption(android.content.ComponentName,boolean) setStorageEncryption()} 
−522 B (89.9 KiB)
Loading image diff...
−261 KiB (28.6 KiB)
Loading image diff...